diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fbb5b4e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# third-party files are kept byte-for-byte (verified against their sources) +site/public/vendor/** -text diff --git a/README.md b/README.md index 40e0d14..ebe9f4e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,9 @@ Källkoden till **https://publiccloud.se**: en helskärmshimmel som följer sole **Fyra rutor** - **Just nu:** väder, temperatur, vind, måne, sol och plats. -- **Plats:** karta med zoom (+/−), knappen "Utgå från min plats" (GPS), klick i kartan för att välja plats, och standardplatsen Örebro slott. Allt räknas om för vald plats. +- **Plats:** en jordglob (MapLibre GL 6.11, globprojektion) med dag- och nattskugga i realtid, kust- och landsgränser (Natural Earth), en röd nål för vald plats, scroll- och knappzoom, "Utgå från min plats" (GPS), klick på globen och standardplatsen Örebro slott. Allt räknas om för vald plats. + - **Spara som min plats:** sidan startar där nästa gång (sparas bara i webbläsaren). + - **Dela min pin:** ett öppet, anonymt index på stadsnivå. Servern avrundar positionen till 0,1°, slår själv upp stad och land (ingen fritext) och visar alla delade städer som glödande punkter på globen. Ägaren kan ta bort sin pin. Spärr: en delning per nätverk och 5 min (saltad IP-hash som går ut, IP sparas aldrig). - **Kväll & natt:** betyg för stjärnhimlen, chans till norrsken (Kp nu och prognos), meteorregn samt fullmåne och nymåne. - **Fotoljus:** gyllene och blå timmen med väderprognos, månens upp- och nedgång, dimma, regnbåge och nattlysande moln. @@ -34,8 +36,11 @@ site/ public/img/moon-photographer.svg nymåne-överraskningen public/_headers cache-regler (filmerna cachas i ett år → nytt filnamn vid ny film) public/video/ day-v2 / night som WebM (VP9) + MP4 (H.264, reserv för äldre Safari) - worker.js Cloudflare Worker: statiska filer + HTTP Range (206) för /video/* (krävs av Safari/iOS) - wrangler.jsonc Worker-konfiguration (namn publiccloud-sky) + public/vendor/maplibre-6.11.2/ MapLibre GL JS (självhostad, verifierad mot npm-registrets integritet, BSD-3) + public/vendor/ne/ Natural Earth 1:110m kust- och landsgränser (public domain) + worker.js Cloudflare Worker: statiska filer + HTTP Range (206) för /video/* + /api/pins (GET/POST/DELETE) + wrangler.jsonc Worker-konfiguration (namn publiccloud-sky, D1-databasen publiccloud-pins) + db/schema.sql tabellerna pins, ratelimit och geocache tools/ upscale-slowmo.sh hur filmerna togs fram: Real-ESRGAN x4plus (uppskalning) + RIFE v4.6 (slowmotion) ``` @@ -48,6 +53,8 @@ Sajten körs som en Cloudflare Worker med statiska filer och custom domain `publ cd site export CLOUDFLARE_API_TOKEN=... # konto-token med Workers-rättighet export CLOUDFLARE_ACCOUNT_ID=... +npx wrangler d1 execute publiccloud-pins --remote --file db/schema.sql # första gången +npx wrangler secret put PIN_SALT # slumpat salt för IP-spärren npx wrangler deploy ``` @@ -70,6 +77,7 @@ npx wrangler deploy - Väder och prognos per timme: [Open-Meteo](https://open-meteo.com/) (gratis för icke-kommersiellt bruk) - Kp-index nu och 3-dygnsprognos: [NOAA SWPC](https://www.swpc.noaa.gov/) - Karta: [OpenStreetMap](https://www.openstreetmap.org/copyright) via [Leaflet](https://leafletjs.com/) 1.9.4 (cdnjs, SRI) -- Platsnamn: OpenStreetMap Nominatim +- Platsnamn: OpenStreetMap Nominatim (i webbläsaren för vald plats, i Workern för delade pins) +- Konturer: [Natural Earth](https://www.naturalearthdata.com) (public domain) - Sol- och månberäkningar: formler från SunCalc (Vladimir Agafonkin), inbäddade i sidan - Meteorregn: American Meteor Society / IMO:s kalendrar diff --git a/site/db/schema.sql b/site/db/schema.sql new file mode 100644 index 0000000..f3aa37f --- /dev/null +++ b/site/db/schema.sql @@ -0,0 +1,16 @@ +-- Shared pins: city level only. No free text; city/country come from the server's own reverse geocoding. +CREATE TABLE IF NOT EXISTS pins ( + id TEXT PRIMARY KEY, -- random id + token_hash TEXT NOT NULL, -- sha-256 of the owner's secret (the secret itself only lives in their browser) + lat REAL NOT NULL, -- rounded to 0.1° (~11 km) + lng REAL NOT NULL, + city TEXT NOT NULL, + country TEXT NOT NULL, + cc TEXT NOT NULL, -- ISO country code + created INTEGER NOT NULL -- unix ms +); +CREATE INDEX IF NOT EXISTS pins_city ON pins (cc, city); +-- Rate limit: hashed IP (with a secret salt), expires after a few minutes. Nothing else about the visitor is stored. +CREATE TABLE IF NOT EXISTS ratelimit (k TEXT PRIMARY KEY, until INTEGER NOT NULL); +-- Server-side reverse-geocode cache per rounded position (keeps Nominatim traffic tiny) +CREATE TABLE IF NOT EXISTS geocache (k TEXT PRIMARY KEY, city TEXT, country TEXT, cc TEXT, created INTEGER NOT NULL); diff --git a/site/public/index.html b/site/public/index.html index 8a7c1cb..c0a8cd0 100644 --- a/site/public/index.html +++ b/site/public/index.html @@ -6,10 +6,7 @@ publiccloud.se - - +