-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.min.js
More file actions
1 lines (1 loc) · 6.06 KB
/
api.min.js
File metadata and controls
1 lines (1 loc) · 6.06 KB
1
export default async function handler(t,e){if(e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Accept, User-Agent"),"OPTIONS"===t.method)return e.status(204).end();const n="1.8.1",{slug:r,embed:o=!1}=t.query,a=t.headers.host||"";let s=[],i=!0;try{const t=await fetch(`https://${a}/unfiltered.json`);s=await t.json()}catch(t){return console.error("Couldn't grab the unfiltered domain whitelist:",t),e.status(500).json({error:`Couldn't grab the unfiltered domain whitelist: ${t}`})}if(!r)return e.status(400).json({error:"Invalid or missing post ID / MD5 / extension"});const c=Array.isArray(r)?r[0]:String(r),p=c.lastIndexOf("."),l=-1===p?c:c.slice(0,p),d=-1===p?void 0:c.slice(p+1),m=/^[a-f0-9]{32}$/i.test(l),u=/^\d+$/.test(l);if(!m&&!u)return e.status(400).json({error:"Slug must be a numeric post ID or a 32-character MD5 hash"});let h;s.includes(a)?(h="e621.net",i=!1):(h="e926.net",i=!0);try{let r,s;if(m){const t=new URL("https://e621.net/posts.json");t.searchParams.set("limit","1"),t.searchParams.set("tags",`md5:${l}`);const o=await fetch(t.toString(),{headers:{"User-Agent":`e694/${n}`,Accept:"application/json"}});if(!o.ok)return e.status(o.status).json({error:"Failed to search post by MD5"});const a=await o.json();if(r=a?.posts?.[0],!r)return e.status(404).json({error:"No post found for that MD5 hash"});s=String(r.id)}else{s=l;const t=`https://e621.net/posts/${s}.json`,o=await fetch(t,{headers:{"User-Agent":`e694/${n}`,Accept:"application/json"}});if(!o.ok)return e.status(o.status).json({error:"Failed to fetch post data"});const a=await o.json();r=a?.post}if(!r)return e.status(404).json({error:"Post data not found"});const c=d??r.file?.ext,p=r.preview?.url,u=`https://${a}/posts/${s}/file.${c}`,g=!("e926.net"===h&&"s"!==r.rating)&&["webm","mp4"].includes(c);let f,y="";const $=(r.tags.artist||[]).concat(r.tags.contributor||[]),w=["sound_warning","third-party_edit","conditional_dnp"],j=$.filter(t=>!w.includes(t));(r.tags.artist?.includes("sound_warning")||r.tags.meta?.includes("sound")&&!r.tags.meta?.includes("no_sound"))&&(y="\n🔊 Sound Warning! 🔊");const b=new Date(r.created_at).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"}),v={s:"Safe",q:"Questionable",e:"Explicit"},A={true:" (Safe Mode)",false:""};if("json"===d)return e.status(200).json({post:r});if(!r.file?.url)return e.status(404).json({error:"Media URL not found in post data"});const C=t.headers.accept||"";if("json+oembed"===d||C.includes("application/json+oembed"))return e.setHeader("Content-Type","application/json+oembed"),e.status(200).json({author_name:`Posted on ${b}\nRating: ${v[r.rating]} • Score: ${r.score.total}${y}`,provider_name:g?`Video from ${h} • e694`:`Image from ${h} • e694`});if("true"===o){f=0===j.length?"unknown":1===j.length?`${j[0]}`:`${j[0]} +${j.length-1}`;const t=`\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <meta property="theme-color" content="#00709e" />\n <link rel="icon" href="/favicon.ico" />\n <meta name="application-name" content="e694">\n <link rel="alternate" type="application/json+oembed" href="https://${a}/posts/${s}/file.json+oembed">\n <link rel="apple-touch-icon" href="https://e694.net/icon.png" />\n <link rel="icon" type="image/png" href="https://e694.net/icon.png">\n <link rel="icon" type="image/png" sizes="32x32" href="https://e694.net/favicon32.png">\n <link rel="icon" type="image/png" sizes="16x16" href="https://e694.net/favicon16.png">\n <meta property="title" content="#${s}" />\n <meta property="article:published_time" content="${r.created_at}">\n\n <!-- Open Graph -->\n <meta property="og:title" content="#${s} by ${f}" />\n <meta property="og:type" content="${g?"video.other":"article"}" />\n <meta property="og:site_name" content="${h} via e694${A[i]}">\n ${g?`\n <meta property="og:video" content="${u}" />\n <meta property="og:video:type" content="video/${c}" />\n <meta property="og:video:width" content="1280" />\n <meta property="og:video:height" content="720" />\n <meta property="og:image" content="${p}" />\n `:`\n <meta property="og:image" content="${u}" />\n `}\n\n <!-- Twitter -->\n <meta property="twitter:card" content="${g?"player":"summary_large_image"}" />\n <meta property="twitter:title" content="Post from ${h}" />\n ${g?`\n <meta property="twitter:image" content="${p}" />\n <meta property="twitter:player" content="${u}" />\n <meta property="twitter:player:width" content="1280" />\n <meta property="twitter:player:height" content="720" />\n <meta property="twitter:player:stream" content="${u}" />\n <meta property="twitter:player:stream:content_type" content="video/${c}" />\n `:`\n <meta property="twitter:image" content="${u}" />\n `}\n <style>html,body{background:#012e57;}</style>\n </head>\n <body>\n <script>window.location = "https://${h}/posts/${s}"</script>\n </body>\n </html>\n `.trim();return e.setHeader("Content-Type","text/html"),e.status(200).send(t)}const _=await fetch("e926.net"===h&&"s"!==r.rating?"https://e694.net/unsafe.png":r.file.url,{headers:{"User-Agent":`e694/${n}`}});if(!_.ok)return e.status(_.status).json({error:"Failed to fetch image"});const x=await _.arrayBuffer(),S=Buffer.from(x),k=_.headers.get("content-type")||"image/jpeg";return e.setHeader("Cache-Control","public, max-age=300, stale-while-revalidate=60"),e.setHeader("Content-Disposition",`inline; filename="${s}.${c}"`),e.setHeader("Content-Type",k),e.setHeader("Access-Control-Allow-Origin","*"),e.status(200).send(S)}catch(t){return console.error("Error:",t),e.status(500).json({error:"Failed to fetch from API",details:t.message})}}