Duplicate Photo Viewer

Cloudflare KV sync (no auth)

How this works: Paste the public URL to your CSV hosted on your Pages site (or any public URL). Your progress (current group index + column mapping) is stored in Cloudflare KV under a key derived from that CSV URL. No authentication; anyone with the URL could read/write that key.

Expected columns (you can map them if different): Group ID, Filename, Folder, Size (KB), Dimensions, Match %.

// Deploy this Worker and bind a KV namespace named PROGRESS. // Routes: GET /state/:id -> return saved JSON or 404 // PUT /state/:id -> save JSON body // CORS: open to any origin (no auth) export default { async fetch(request, env) { const url = new URL(request.url); // Basic CORS if (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders(request.headers.get('Origin')) }); } if (!url.pathname.startsWith('/state/')) { return new Response('Not found', { status: 404, headers: corsHeaders(request.headers.get('Origin')) }); } const id = url.pathname.replace('/state/',''); if (!id || id.length < 16) return new Response('Bad key', { status: 400, headers: corsHeaders(request.headers.get('Origin')) }); if (request.method === 'GET') { const val = await env.PROGRESS.get(id); if (!val) return new Response('Not found', { status: 404, headers: corsHeaders(request.headers.get('Origin')) }); return new Response(val, { headers: { 'content-type':'application/json', ...corsHeaders(request.headers.get('Origin')) } }); } if (request.method === 'PUT') { const body = await request.text(); try { JSON.parse(body); } catch { return new Response('Invalid JSON', { status: 400, headers: corsHeaders(request.headers.get('Origin')) }); } await env.PROGRESS.put(id, body); return new Response('OK', { headers: corsHeaders(request.headers.get('Origin')) }); } return new Response('Method not allowed', { status: 405, headers: corsHeaders(request.headers.get('Origin')) }); } } function corsHeaders(origin) { return { 'Access-Control-Allow-Origin': origin || '*', 'Access-Control-Allow-Methods': 'GET,PUT,OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Max-Age': '86400' }; } /* ============================ wrangler.toml (example) ============================ name = "dupviewer-kv" main = "worker.js" compatibility_date = "2024-10-01" [[kv_namespaces]] binding = "PROGRESS" id = "" preview_id = "" # After publishing, if the Worker runs on a different domain than your Pages site, # set window.KV_ENDPOINT = 'https://your-worker-subdomain.workers.dev/state' in index.html. */