|
@@ -1,18 +1,33 @@
|
|
|
#!/usr/bin/env bun
|
|
#!/usr/bin/env bun
|
|
|
-// Publish the built playlist + guide to chillidonut.com's junk drawer on GCS.
|
|
|
|
|
-// Uses `cp` (NOT `rsync`) so it only adds/overwrites these two objects — anything
|
|
|
|
|
-// else already in the bucket's junk/ is left untouched (never synced or deleted).
|
|
|
|
|
-// `-Z` gzips on upload and sets Content-Encoding: gzip (served compressed on the
|
|
|
|
|
-// wire; ~32 MB guide -> ~3-4 MB). url-tvg stays …/guide.xml — do NOT pre-gzip.
|
|
|
|
|
|
|
+// Publish the built playlist + guide to chillidonut.com/junk/iptv/ on GCS.
|
|
|
|
|
+//
|
|
|
|
|
+// SAFETY: uploads to two EXPLICIT object paths with `gsutil cp`. `cp` is additive —
|
|
|
|
|
+// it only creates/overwrites the exact objects named. It never lists, syncs, or
|
|
|
|
|
+// deletes, so NOTHING else under junk/ can be affected. (`gsutil rsync` and
|
|
|
|
|
+// `gsutil rm` — the only commands that delete — are deliberately not used.)
|
|
|
|
|
+//
|
|
|
|
|
+// `-Z` gzips on upload and sets Content-Encoding: gzip (served compressed; the
|
|
|
|
|
+// ~32 MB guide travels at ~3-4 MB). url-tvg stays …/guide.xml — do NOT pre-gzip.
|
|
|
|
|
+//
|
|
|
|
|
+// AUTH: needs a current gsutil token. If you see "Reauthentication required", run
|
|
|
|
|
+// `gcloud auth login` once. (That CLI token is separate from the ADC that
|
|
|
|
|
+// `hugo deploy` uses, which is why hugo can deploy while gsutil is stale.)
|
|
|
import { $ } from 'bun';
|
|
import { $ } from 'bun';
|
|
|
import { existsSync } from 'node:fs';
|
|
import { existsSync } from 'node:fs';
|
|
|
|
|
|
|
|
const HERE = import.meta.dir;
|
|
const HERE = import.meta.dir;
|
|
|
-const DEST = 'gs://chillidonut.com/junk/iptv/';
|
|
|
|
|
-const files = ['iptv.m3u', 'guide.xml'].map((f) => `${HERE}/${f}`);
|
|
|
|
|
|
|
+const uploads = [
|
|
|
|
|
+ { local: `${HERE}/iptv.m3u`, remote: 'gs://chillidonut.com/junk/iptv/iptv.m3u' },
|
|
|
|
|
+ { local: `${HERE}/guide.xml`, remote: 'gs://chillidonut.com/junk/iptv/guide.xml' },
|
|
|
|
|
+];
|
|
|
|
|
|
|
|
-for (const f of files)
|
|
|
|
|
- if (!existsSync(f)) { console.error(`missing ${f} — run \`bun refresh.ts\` first`); process.exit(1); }
|
|
|
|
|
|
|
+for (const u of uploads)
|
|
|
|
|
+ if (!existsSync(u.local)) { console.error(`missing ${u.local} — run \`bun refresh.ts\` first`); process.exit(1); }
|
|
|
|
|
|
|
|
-await $`gsutil -m -h ${'Cache-Control:public,max-age=3600'} cp -Z ${files} ${DEST}`;
|
|
|
|
|
-console.log(`uploaded ${files.length} files -> ${DEST} (gzipped, Content-Encoding: gzip)`);
|
|
|
|
|
|
|
+console.log('Uploading ONLY these two objects (nothing else under junk/ is touched):');
|
|
|
|
|
+for (const u of uploads) console.log(` ${u.local}\n -> ${u.remote}`);
|
|
|
|
|
+
|
|
|
|
|
+for (const u of uploads)
|
|
|
|
|
+ await $`gsutil -h ${'Cache-Control:public,max-age=3600'} cp -Z ${u.local} ${u.remote}`;
|
|
|
|
|
+
|
|
|
|
|
+console.log('done — gzipped, Content-Encoding: gzip.');
|