summaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/404.astro67
-rw-r--r--src/pages/api/update.ts200
-rw-r--r--src/pages/history/[date].astro13
-rw-r--r--src/pages/index.astro11
-rw-r--r--src/pages/privacy.astro40
5 files changed, 0 insertions, 331 deletions
diff --git a/src/pages/404.astro b/src/pages/404.astro
deleted file mode 100644
index 4db6121..0000000
--- a/src/pages/404.astro
+++ /dev/null
@@ -1,67 +0,0 @@
----
----
-
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="shortcut icon" href="/favicon.ico">
- <title>404 - Page Not Found | geshem.space</title>
- <style>
- body {
- margin: 0;
- padding: 0;
- background-color: #1a1a1a;
- color: white;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
- "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- text-align: center;
- }
-
- .container {
- max-width: 500px;
- }
-
- h1 {
- font-size: 6rem;
- margin: 0;
- font-weight: bold;
- opacity: 0.8;
- }
-
- h2 {
- font-size: 1.5rem;
- margin: 1rem 0;
- font-weight: normal;
- }
-
- p {
- margin: 1rem 0;
- opacity: 0.7;
- line-height: 1.5;
- }
-
- a {
- color: #3498db;
- text-decoration: none;
- font-weight: 500;
- }
-
- a:hover {
- text-decoration: underline;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <h1>404</h1>
- <h2>Page Not Found</h2>
- <p>The page you're looking for doesn't exist.</p>
- <p><a href="/">← Back to Rain Radar</a></p>
- </div>
- </body>
-</html> \ No newline at end of file
diff --git a/src/pages/api/update.ts b/src/pages/api/update.ts
deleted file mode 100644
index 88dfa3c..0000000
--- a/src/pages/api/update.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-import type { APIRoute } from 'astro';
-
-export const prerender = false;
-
-interface ImageData {
- [key: string]: string[];
-}
-
-interface CloudflareEnv {
- BASE_URL: string;
- AUTH_USER: string;
- AUTH_PASS: string;
- BUCKET_NAME: string;
- SCHEDULED?: boolean;
-}
-
-class GeshemUpdate {
- private bucket: R2Bucket;
- private env: CloudflareEnv;
-
- constructor(bucket: R2Bucket, env: CloudflareEnv) {
- this.bucket = bucket;
- this.env = env;
- }
-
- private async authenticate(request: Request): Promise<Request> {
- const headers = new Headers(request.headers);
- const credentials = btoa(`${this.env.AUTH_USER}:${this.env.AUTH_PASS}`);
- headers.set('Authorization', `Basic ${credentials}`);
-
- return new Request(request.url, {
- method: request.method,
- headers,
- body: request.body
- });
- }
-
- private async getLatestImages(): Promise<string[]> {
- const authenticatedRequest = await this.authenticate(new Request(this.env.BASE_URL));
- const response = await fetch(authenticatedRequest);
- const html = await response.text();
-
- const regex = /radar280comp_\d+\.png/g;
- const matches = html.match(regex) || [];
- const uniqueImages = [...new Set(matches)];
-
- return uniqueImages.sort().slice(-10);
- }
-
- private async getLatestBucketKeys(): Promise<string[]> {
- const yesterday = new Date();
- yesterday.setDate(yesterday.getDate() - 1);
- const yesterdayStr = yesterday.toISOString().slice(0, 10).replace(/-/g, '');
-
- try {
- const objects = await this.bucket.list({
- prefix: 'imgs/',
- startAfter: `imgs/${yesterdayStr}`
- });
-
- return objects.objects.map(obj => obj.key);
- } catch (error) {
- console.error('Error listing bucket objects:', error);
- return [];
- }
- }
-
- private async fetchMissingImages(): Promise<boolean> {
- const images = await this.getLatestImages();
- const s3Images = await this.getLatestBucketKeys();
- let updated = false;
-
- for (const img of images) {
- const key = this.keyFromFilename(img);
- if (!s3Images.includes(key)) {
- await this.fetchImage(img, key);
- updated = true;
- }
- }
-
- return updated;
- }
-
- private async fetchImage(imgName: string, key: string): Promise<void> {
- console.log(`Downloading ${imgName} from web server`);
-
- const imageUrl = `${this.env.BASE_URL}/${imgName}`;
- const authenticatedRequest = await this.authenticate(new Request(imageUrl));
- const response = await fetch(authenticatedRequest);
-
- if (!response.ok) {
- throw new Error(`Failed to fetch image: ${response.statusText}`);
- }
-
- const imageData = await response.arrayBuffer();
-
- console.log(`Uploading to ${key}`);
- await this.bucket.put(key, imageData, {
- httpMetadata: {
- contentType: 'image/png',
- cacheControl: 'public, max-age=31536000'
- }
- });
- }
-
- private keyFromFilename(filename: string): string {
- const [name, dateStr] = filename.split('.')[0].split('_');
- const res = 280;
-
- // Parse date: YYYYMMDDHHMM
- const year = dateStr.slice(0, 4);
- const month = dateStr.slice(4, 6);
- const day = dateStr.slice(6, 8);
- const hour = dateStr.slice(8, 10);
- const minute = dateStr.slice(10, 12);
-
- const d = `${year}${month}${day}`;
- const t = `${hour}${minute}`;
-
- return `imgs/${d}/${t}/${res}.png`;
- }
-
- private async generateJson(): Promise<void> {
- const latestKeys = await this.getLatestBucketKeys();
- const keys = latestKeys
- .filter(key => key.endsWith('280.png'))
- .sort()
- .slice(-10);
-
- const index: ImageData = { '280': keys };
-
- await this.bucket.put('imgs.json', JSON.stringify(index), {
- httpMetadata: {
- contentType: 'application/json',
- cacheControl: 'public, max-age=60'
- }
- });
- }
-
- async run(): Promise<string> {
- try {
- const updated = await this.fetchMissingImages();
- if (updated) {
- await this.generateJson();
- }
- return `Updated: ${updated}`;
- } catch (error) {
- console.error('Error in GeshemUpdate.run():', error);
- throw error;
- }
- }
-}
-
-export const GET: APIRoute = async ({ platform, request }) => {
- // This endpoint should only be accessible via Cloudflare Cron
- const cron = request.headers.get('CF-Cron');
- if (!cron) {
- return new Response('Unauthorized', { status: 401 });
- }
-
- try {
- const env = platform?.env as unknown as CloudflareEnv;
-
- if (!env?.BASE_URL || !env?.AUTH_USER || !env?.AUTH_PASS) {
- return new Response('Missing environment variables', { status: 500 });
- }
-
- // Get R2 bucket (this would be configured in your Cloudflare Workers environment)
- const bucket = env.BUCKET_NAME ? platform?.env[env.BUCKET_NAME] as R2Bucket : null;
-
- if (!bucket) {
- return new Response('R2 bucket not configured', { status: 500 });
- }
-
- const updater = new GeshemUpdate(bucket, env);
- const result = await updater.run();
-
- return new Response(JSON.stringify({
- message: `SUCCESS: ${result}`,
- timestamp: new Date().toISOString()
- }), {
- status: 200,
- headers: {
- 'Content-Type': 'application/json'
- }
- });
-
- } catch (error) {
- console.error('Error in update handler:', error);
- return new Response(JSON.stringify({
- message: 'ERROR',
- error: error instanceof Error ? error.message : 'Unknown error'
- }), {
- status: 500,
- headers: {
- 'Content-Type': 'application/json'
- }
- });
- }
-}; \ No newline at end of file
diff --git a/src/pages/history/[date].astro b/src/pages/history/[date].astro
deleted file mode 100644
index 0a78f9f..0000000
--- a/src/pages/history/[date].astro
+++ /dev/null
@@ -1,13 +0,0 @@
----
-import Layout from '../../layouts/Layout.astro';
-import { Geshem } from '../../components/Geshem';
-import '../../styles/global.css';
-
-export const prerender = false;
-
-const { date } = Astro.params;
----
-
-<Layout title="Geshem - Rain Radar History" description="Israel Rain Radar History">
- <Geshem client:load date={date} />
-</Layout> \ No newline at end of file
diff --git a/src/pages/index.astro b/src/pages/index.astro
deleted file mode 100644
index 5b08f18..0000000
--- a/src/pages/index.astro
+++ /dev/null
@@ -1,11 +0,0 @@
----
-import Layout from "../layouts/Layout.astro";
-import { Geshem } from "../components/Geshem";
-import "../styles/global.css";
-
-const { date } = Astro.params;
----
-
-<Layout>
- <Geshem client:load date={date} />
-</Layout>
diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro
deleted file mode 100644
index d01a26b..0000000
--- a/src/pages/privacy.astro
+++ /dev/null
@@ -1,40 +0,0 @@
----
-
----
-
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <meta
- name="viewport"
- content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
- />
- <meta name="apple-mobile-web-app-title" content="Geshem" />
- <meta name="apple-mobile-web-app-capable" content="yes" />
- <meta name="theme-color" content="#000000" />
- <link rel="shortcut icon" href="/favicon.ico" />
- <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
- <link rel="manifest" href="/manifest.json" />
- <title>Privacy Policy | geshem.space</title>
- <script src="https://cdn.usefathom.com/script.js" data-site="MBXPLVRM" defer
- ></script>
- <style>
- body {
- overflow: hidden;
- position: absolute;
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- font-family: sans-serif;
- background-color: #1a1a1a;
- color: white;
- margin: 0;
- }
- </style>
- </head>
- <body>
- <h1>We do not collect any data.</h1>
- </body>
-</html>