fix: redirects + update root cdn url

This commit is contained in:
Cory Dransfeldt 2024-06-09 11:17:20 -07:00
parent f533a16bdc
commit 693fcbd2b4
No known key found for this signature in database
24 changed files with 0 additions and 1006 deletions

View file

@ -1,45 +0,0 @@
name: Deploy Cloudflare Worker
on:
workflow_dispatch:
inputs:
worker-folder:
description: 'Select the folder containing the worker to deploy'
required: true
type: choice
options:
- analytics
- contact
- now-playing
- rebuild
- scrobble
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install Wrangler
run: npm install -g wrangler
- name: Inject environment variables into wrangler.toml
run: |
cd workers/${{ github.event.inputs.worker-folder }}
sed -i 's/^zone_id =.*/zone_id = "${{ secrets.CLOUDFLARE_ZONE_ID }}"/' wrangler.toml
sed -i 's/^account_id =.*/account_id = "${{ secrets.CLOUDFLARE_ACCOUNT_ID }}"/' wrangler.toml
- name: Install dependencies
run: |
cd workers/${{ github.event.inputs.worker-folder }}
npm i
- name: Deploy to Cloudflare Worker
run: |
cd workers/${{ github.event.inputs.worker-folder }}
wrangler deploy --env production
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}

View file

@ -3,7 +3,6 @@ export default async function () {
footer: [
{ name: 'Now' },
{ name: 'Uses' },
{ name: 'Save' },
{ name: 'Blogroll' },
],
menu: [

View file

@ -1,17 +0,0 @@
---
title: Save
layout: default
permalink: /save.html
description: Save a little bit on services that I also use.
---
<h2 class="page-header">{{ title }}</h2>
<p>Referral links for services I use. I save some money, and you do as well if you choose to use them.</p>
<ul class="link-list">
<li><a class="plausible-event-name=Fastmail+referral" href="https://ref.fm/u30190984">Fastmail</a></li>
<li><a class="plausible-event-name=NextDNS+referral" href="https://nextdns.io/?from=m56mt3z6">NextDNS</a></li>
<li><a class="plausible-event-name=DNSimple+referral" href="https://dnsimple.com/r/3a7cbb9e15df8f">DNSimple</a></li>
<li><a class="plausible-event-name=Feedpress+referral" href="https://feedpress.com/?affid=34370">Feedpress</a></li>
<li><a class="plausible-event-name=Proton+referral" href="https://pr.tn/ref/X775YX40Z50G">Proton</a></li>
<li><a class="plausible-event-name=DigitalOcean+referral" href="https://m.do.co/c/3635bf99aee2">DigitalOcean</a></li>
<li><a class="plausible-event-name=Garbage+Day+referral" href="https://www.garbageday.email/subscribe?ref=4JeD4bFKQE">Garbage Day newsletter</a></li>
</ul>

View file

@ -1,5 +0,0 @@
# analytics worker
```bash
wrangler deploy --env production
```

View file

@ -1,36 +0,0 @@
const ScriptName = '/js/script.js';
const Endpoint = '/api/event';
const ScriptWithoutExtension = ScriptName.replace('.js', '')
addEventListener('fetch', event => {
event.passThroughOnException();
event.respondWith(handleRequest(event));
})
async function handleRequest(event) {
const pathname = new URL(event.request.url).pathname
const [baseUri, ...extensions] = pathname.split('.')
if (baseUri.endsWith(ScriptWithoutExtension)) {
return getScript(event, extensions)
} else if (pathname.endsWith(Endpoint)) {
return postData(event)
}
return new Response(null, { status: 404 })
}
async function getScript(event, extensions) {
let response = await caches.default.match(event.request);
if (!response) {
response = await fetch("https://plausible.io/js/plausible." + extensions.join("."));
event.waitUntil(caches.default.put(event.request, response.clone()));
}
return response;
}
async function postData(event) {
const request = new Request(event.request);
request.headers.delete('cookie');
return await fetch("https://plausible.io/api/event", request);
}

View file

@ -1,13 +0,0 @@
name = "analytics-worker"
main = "./index.js"
compatibility_date = "2023-01-01"
account_id = ""
workers_dev = true
[env.production]
name = "analytics-worker-production"
routes = [
{ pattern = "coryd.dev/js/*", zone_id = "" },
{ pattern = "coryd.dev/api/event", zone_id = "" }
]

View file

@ -1,8 +0,0 @@
# contact worker
```bash
wrangler deploy --env production
wrangler secret put SUPABASE_URL --env production
wrangler secret put SUPABASE_KEY --env production
```

View file

@ -1,57 +0,0 @@
import { createClient } from '@supabase/supabase-js';
const RATE_LIMIT = 5;
const TIME_FRAME = 60 * 60 * 1000;
const ipSubmissions = new Map();
export default {
async fetch(request, env) {
if (request.method === 'POST') {
const ip = request.headers.get('CF-Connecting-IP') || request.headers.get('X-Forwarded-For') || request.headers.get('Remote-Addr');
const currentTime = Date.now();
if (!ipSubmissions.has(ip)) {
ipSubmissions.set(ip, []);
}
const submissions = ipSubmissions.get(ip).filter(time => currentTime - time < TIME_FRAME);
if (submissions.length >= RATE_LIMIT) {
return new Response('Rate limit exceeded', { status: 429 });
}
submissions.push(currentTime);
ipSubmissions.set(ip, submissions);
try {
const formData = await request.formData();
const name = formData.get('name');
const email = formData.get('email');
const message = formData.get('message');
const hpName = formData.get('hp_name');
// check the honeypot field
if (hpName) return new Response('Spam detected', { status: 400 });
// validate input
if (!name || !email || !message) return new Response('Invalid input', { status: 400 });
const supabaseUrl = env.SUPABASE_URL;
const supabaseKey = env.SUPABASE_KEY;
const supabase = createClient(supabaseUrl, supabaseKey);
const { error } = await supabase.from('contacts').insert([
{ name, email, message, replied: false }
]);
if (error) throw error;
return Response.redirect('https://coryd.dev/contact/success', 303);
} catch (error) {
return new Response(error.message, { status: 500 });
}
} else {
return new Response('Method not allowed', { status: 405 });
}
}
};

View file

@ -1,159 +0,0 @@
{
"name": "contact-worker",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@supabase/supabase-js": "^2.43.4"
}
},
"node_modules/@supabase/auth-js": {
"version": "2.64.2",
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.2.tgz",
"integrity": "sha512-s+lkHEdGiczDrzXJ1YWt2y3bxRi+qIUnXcgkpLSrId7yjBeaXBFygNjTaoZLG02KNcYwbuZ9qkEIqmj2hF7svw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/functions-js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.3.1.tgz",
"integrity": "sha512-QyzNle/rVzlOi4BbVqxLSH828VdGY1RElqGFAj+XeVypj6+PVtMlD21G8SDnsPQDtlqqTtoGRgdMlQZih5hTuw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/node-fetch": {
"version": "2.6.15",
"resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
"integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/@supabase/postgrest-js": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.2.tgz",
"integrity": "sha512-9/7pUmXExvGuEK1yZhVYXPZnLEkDTwxgMQHXLrN5BwPZZm4iUCL1YEyep/Z2lIZah8d8M433mVAUEGsihUj5KQ==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/realtime-js": {
"version": "2.9.5",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.5.tgz",
"integrity": "sha512-TEHlGwNGGmKPdeMtca1lFTYCedrhTAv3nZVoSjrKQ+wkMmaERuCe57zkC5KSWFzLYkb5FVHW8Hrr+PX1DDwplQ==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14",
"@types/phoenix": "^1.5.4",
"@types/ws": "^8.5.10",
"ws": "^8.14.2"
}
},
"node_modules/@supabase/storage-js": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz",
"integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/supabase-js": {
"version": "2.43.4",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.43.4.tgz",
"integrity": "sha512-/pLPaxiIsn5Vaz3s32HC6O/VNwfeddnzS0bZRpOW0AKcPuXroD8pT9G8mpiBlZfpKsMmq6k7tlhW7Sr1PAQ1lw==",
"license": "MIT",
"dependencies": {
"@supabase/auth-js": "2.64.2",
"@supabase/functions-js": "2.3.1",
"@supabase/node-fetch": "2.6.15",
"@supabase/postgrest-js": "1.15.2",
"@supabase/realtime-js": "2.9.5",
"@supabase/storage-js": "2.5.5"
}
},
"node_modules/@types/node": {
"version": "20.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
"integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/phoenix": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz",
"integrity": "sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA==",
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/ws": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
}
}

View file

@ -1,5 +0,0 @@
{
"dependencies": {
"@supabase/supabase-js": "^2.43.4"
}
}

View file

@ -1,12 +0,0 @@
name = "contact-form-worker"
main = "./index.js"
compatibility_date = "2023-01-01"
account_id = ""
workers_dev = true
[env.production]
name = "contact-form-worker-production"
routes = [
{ pattern = "coryd.dev/api/contact", zone_id = "" }
]

View file

@ -1,7 +0,0 @@
# now-playing worker
```bash
wrangler deploy --env production
wrangler secret put SUPABASE_URL --env production
wrangler secret put SUPABASE_KEY --env production
```

View file

@ -1,85 +0,0 @@
import { createClient } from '@supabase/supabase-js';
import slugify from 'slugify';
const sanitizeMediaString = (str) => {
const sanitizedString = str.normalize('NFD').replace(/[\u0300-\u036f\u2010—\.\?\(\)\[\]\{\}]/g, '').replace(/\.{3}/g, '');
return slugify(sanitizedString, {
replacement: '-',
remove: /[#,&,+()$~%.'":*?<>{}]/g,
lower: true,
});
};
const regionNames = new Intl.DisplayNames(['en'], { type: 'region' });
const getCountryName = (countryCode) => regionNames.of(countryCode.trim()) || countryCode.trim();
const parseCountryField = (countryField) => {
if (!countryField) return null;
const delimiters = [',', '/', '&', 'and'];
let countries = [countryField];
delimiters.forEach(delimiter => {
countries = countries.flatMap(country => country.split(delimiter));
});
return countries.map(getCountryName).join(', ');
};
const fetchGenreById = async (supabase, genreId) => {
const { data, error } = await supabase
.from('genres')
.select('emoji')
.eq('id', genreId)
.single();
if (error) {
console.error('Error fetching genre:', error);
return null;
}
return data.emoji;
};
export default {
async fetch(request, env) {
const SUPABASE_URL = env.SUPABASE_URL;
const SUPABASE_KEY = env.SUPABASE_KEY;
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
const { data, error } = await supabase
.from('listens')
.select(`
track_name,
artist_name,
listened_at,
artists (mbid, genres, country, emoji)
`)
.order('listened_at', { ascending: false })
.range(0, 1);
const headers = {
"Content-Type": "application/json",
"Cache-Control": "public, s-maxage=360, stale-while-revalidate=1080",
};
if (error) {
console.error('Error fetching data:', error);
return new Response(JSON.stringify({ error: "Failed to fetch the latest track" }), { headers });
}
if (data.length === 0) {
return new Response(JSON.stringify({ message: "No recent tracks found" }), { headers });
}
const scrobbleData = data[0];
const genreEmoji = await fetchGenreById(supabase, scrobbleData.artists.genres);
const emoji = scrobbleData.artists.emoji || genreEmoji;
return new Response(JSON.stringify({
content: `${emoji || '🎧'} ${scrobbleData.track_name} by <a href="https://coryd.dev/music/artists/${sanitizeMediaString(scrobbleData.artist_name)}-${sanitizeMediaString(parseCountryField(scrobbleData.artists.country))}">${
scrobbleData.artist_name
}</a>`,
}), { headers });
}
};

View file

@ -1,169 +0,0 @@
{
"name": "now-playing-worker",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@supabase/supabase-js": "^2.43.4",
"slugify": "^1.6.6"
}
},
"node_modules/@supabase/auth-js": {
"version": "2.64.2",
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.2.tgz",
"integrity": "sha512-s+lkHEdGiczDrzXJ1YWt2y3bxRi+qIUnXcgkpLSrId7yjBeaXBFygNjTaoZLG02KNcYwbuZ9qkEIqmj2hF7svw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/functions-js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.3.1.tgz",
"integrity": "sha512-QyzNle/rVzlOi4BbVqxLSH828VdGY1RElqGFAj+XeVypj6+PVtMlD21G8SDnsPQDtlqqTtoGRgdMlQZih5hTuw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/node-fetch": {
"version": "2.6.15",
"resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
"integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/@supabase/postgrest-js": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.2.tgz",
"integrity": "sha512-9/7pUmXExvGuEK1yZhVYXPZnLEkDTwxgMQHXLrN5BwPZZm4iUCL1YEyep/Z2lIZah8d8M433mVAUEGsihUj5KQ==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/realtime-js": {
"version": "2.9.5",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.5.tgz",
"integrity": "sha512-TEHlGwNGGmKPdeMtca1lFTYCedrhTAv3nZVoSjrKQ+wkMmaERuCe57zkC5KSWFzLYkb5FVHW8Hrr+PX1DDwplQ==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14",
"@types/phoenix": "^1.5.4",
"@types/ws": "^8.5.10",
"ws": "^8.14.2"
}
},
"node_modules/@supabase/storage-js": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz",
"integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/supabase-js": {
"version": "2.43.4",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.43.4.tgz",
"integrity": "sha512-/pLPaxiIsn5Vaz3s32HC6O/VNwfeddnzS0bZRpOW0AKcPuXroD8pT9G8mpiBlZfpKsMmq6k7tlhW7Sr1PAQ1lw==",
"license": "MIT",
"dependencies": {
"@supabase/auth-js": "2.64.2",
"@supabase/functions-js": "2.3.1",
"@supabase/node-fetch": "2.6.15",
"@supabase/postgrest-js": "1.15.2",
"@supabase/realtime-js": "2.9.5",
"@supabase/storage-js": "2.5.5"
}
},
"node_modules/@types/node": {
"version": "20.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
"integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/phoenix": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz",
"integrity": "sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA==",
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/ws": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
}
}

View file

@ -1,6 +0,0 @@
{
"dependencies": {
"@supabase/supabase-js": "^2.43.4",
"slugify": "^1.6.6"
}
}

View file

@ -1,12 +0,0 @@
name = "now-playing-worker"
main = "./index.js" # Specify the entry point
compatibility_date = "2023-01-01"
account_id = ""
workers_dev = true
[env.production]
name = "now-playing-worker-production"
routes = [
{ pattern = "coryd.dev/api/now-playing", zone_id = "" }
]

View file

@ -1,7 +0,0 @@
# rebuild worker
```bash
wrangler deploy --env production
wrangler secret put DEPLOY_HOOK_URL --env production
```

View file

@ -1,17 +0,0 @@
export default {
async scheduled(event, env, ctx) {
const deployHookUrl = env.DEPLOY_HOOK_URL;
const response = await fetch(deployHookUrl, {
method: 'POST',
});
if (!response.ok) {
const errorText = await response.text();
console.error(`Error triggering deploy: ${response.statusText}`, errorText);
return;
}
console.log('Deploy triggered successfully');
}
};

View file

@ -1,10 +0,0 @@
name = "scheduled-rebuild-worker"
main = "./index.js"
compatibility_date = "2023-01-01"
account_id = ""
workers_dev = true
[env.production]
name = "scheduled-rebuild-worker-production"
triggers = {crons = ["0 * * * *"]}

View file

@ -1,8 +0,0 @@
# Scrobble worker
```bash
wrangler deploy --env production
wrangler secret put SUPABASE_URL --env production
wrangler secret put SUPABASE_KEY --env production
wrangler secret put ACCOUNT_ID_PLEX --env production
```

View file

@ -1,129 +0,0 @@
import { createClient } from '@supabase/supabase-js';
import { DateTime } from 'luxon';
import slugify from 'slugify';
const sanitizeMediaString = (str) => {
const sanitizedString = str.normalize('NFD').replace(/[\u0300-\u036f\u2010\-\.\?\(\)\[\]\{\}]/g, '').replace(/\.{3}/g, '');
return slugify(sanitizedString, {
replacement: '-',
remove: /[#,&,+()$~%.'":*?<>{}]/g,
lower: true,
});
};
export default {
async fetch(request, env) {
const SUPABASE_URL = env.SUPABASE_URL;
const SUPABASE_KEY = env.SUPABASE_KEY;
const ACCOUNT_ID_PLEX = env.ACCOUNT_ID_PLEX;
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
const url = new URL(request.url);
const params = url.searchParams;
const id = params.get('id');
if (!id) {
return new Response(JSON.stringify({ status: 'Bad request' }), { headers: { "Content-Type": "application/json" } });
}
if (id !== ACCOUNT_ID_PLEX) {
return new Response(JSON.stringify({ status: 'Forbidden' }), { headers: { "Content-Type": "application/json" } });
}
const contentType = request.headers.get("Content-Type") || '';
if (!contentType.includes("multipart/form-data")) {
return new Response(JSON.stringify({ status: 'Bad request', message: 'Invalid Content-Type. Expected multipart/form-data.' }), { headers: { "Content-Type": "application/json" } });
}
try {
const data = await request.formData();
const payload = JSON.parse(data.get('payload'));
if (payload?.event === 'media.scrobble') {
const artist = payload['Metadata']['grandparentTitle'];
const album = payload['Metadata']['parentTitle'];
const track = payload['Metadata']['title'];
const listenedAt = Math.floor(DateTime.now().toSeconds());
const artistKey = sanitizeMediaString(artist);
const albumKey = `${artistKey}-${sanitizeMediaString(album)}`;
let { data: artistData, error: artistError } = await supabase
.from('artists')
.select('*')
.ilike('name_string', artist)
.single();
if (artistError && artistError.code === 'PGRST116') {
const { error: insertArtistError } = await supabase.from('artists').insert([
{
mbid: null,
image: `/artists/${artistKey}.jpg`,
key: artistKey,
name: artist,
tentative: true
}
]);
if (insertArtistError) {
return new Response(JSON.stringify({ status: 'error', message: insertArtistError.message }), { headers: { "Content-Type": "application/json" } });
}
({ data: artistData, error: artistError } = await supabase
.from('artists')
.select('*')
.ilike('name_string', artist)
.single());
} else if (artistError) {
return new Response(JSON.stringify({ status: 'error', message: artistError.message }), { headers: { "Content-Type": "application/json" } });
}
let { data: albumData, error: albumError } = await supabase
.from('albums')
.select('*')
.ilike('key', albumKey)
.single();
if (albumError && albumError.code === 'PGRST116') {
const { error: insertAlbumError } = await supabase.from('albums').insert([
{
mbid: null,
image: `/albums/${albumKey}.jpg`,
key: albumKey,
name: album,
tentative: true
}
]);
if (insertAlbumError) {
return new Response(JSON.stringify({ status: 'error', message: insertAlbumError.message }), { headers: { "Content-Type": "application/json" } });
}
({ data: albumData, error: albumError } = await supabase
.from('albums')
.select('*')
.ilike('key', albumKey)
.single());
} else if (albumError) {
return new Response(JSON.stringify({ status: 'error', message: albumError.message }), { headers: { "Content-Type": "application/json" } });
}
const { error: listenError } = await supabase.from('listens').insert([
{
artist_name: artistData.name_string,
album_name: albumData.name,
track_name: track,
listened_at: listenedAt,
album_key: albumKey
}
]);
if (listenError) {
return new Response(JSON.stringify({ status: 'error', message: listenError.message }), { headers: { "Content-Type": "application/json" } });
}
}
return new Response(JSON.stringify({ status: 'success' }), { headers: { "Content-Type": "application/json" } });
} catch (e) {
return new Response(JSON.stringify({ status: 'error', message: e.message }), { headers: { "Content-Type": "application/json" } });
}
}
};

View file

@ -1,179 +0,0 @@
{
"name": "scrobble-worker",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@supabase/supabase-js": "^2.43.4",
"luxon": "^3.4.4",
"slugify": "^1.6.6"
}
},
"node_modules/@supabase/auth-js": {
"version": "2.64.2",
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.2.tgz",
"integrity": "sha512-s+lkHEdGiczDrzXJ1YWt2y3bxRi+qIUnXcgkpLSrId7yjBeaXBFygNjTaoZLG02KNcYwbuZ9qkEIqmj2hF7svw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/functions-js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.3.1.tgz",
"integrity": "sha512-QyzNle/rVzlOi4BbVqxLSH828VdGY1RElqGFAj+XeVypj6+PVtMlD21G8SDnsPQDtlqqTtoGRgdMlQZih5hTuw==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/node-fetch": {
"version": "2.6.15",
"resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
"integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/@supabase/postgrest-js": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.2.tgz",
"integrity": "sha512-9/7pUmXExvGuEK1yZhVYXPZnLEkDTwxgMQHXLrN5BwPZZm4iUCL1YEyep/Z2lIZah8d8M433mVAUEGsihUj5KQ==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/realtime-js": {
"version": "2.9.5",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.5.tgz",
"integrity": "sha512-TEHlGwNGGmKPdeMtca1lFTYCedrhTAv3nZVoSjrKQ+wkMmaERuCe57zkC5KSWFzLYkb5FVHW8Hrr+PX1DDwplQ==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14",
"@types/phoenix": "^1.5.4",
"@types/ws": "^8.5.10",
"ws": "^8.14.2"
}
},
"node_modules/@supabase/storage-js": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz",
"integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==",
"license": "MIT",
"dependencies": {
"@supabase/node-fetch": "^2.6.14"
}
},
"node_modules/@supabase/supabase-js": {
"version": "2.43.4",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.43.4.tgz",
"integrity": "sha512-/pLPaxiIsn5Vaz3s32HC6O/VNwfeddnzS0bZRpOW0AKcPuXroD8pT9G8mpiBlZfpKsMmq6k7tlhW7Sr1PAQ1lw==",
"license": "MIT",
"dependencies": {
"@supabase/auth-js": "2.64.2",
"@supabase/functions-js": "2.3.1",
"@supabase/node-fetch": "2.6.15",
"@supabase/postgrest-js": "1.15.2",
"@supabase/realtime-js": "2.9.5",
"@supabase/storage-js": "2.5.5"
}
},
"node_modules/@types/node": {
"version": "20.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
"integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/phoenix": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz",
"integrity": "sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA==",
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/luxon": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
"integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==",
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/ws": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
}
}

View file

@ -1,7 +0,0 @@
{
"dependencies": {
"@supabase/supabase-js": "^2.43.4",
"luxon": "^3.4.4",
"slugify": "^1.6.6"
}
}

View file

@ -1,12 +0,0 @@
name = "scrobble-worker"
main = "./index.js"
compatibility_date = "2023-01-01"
account_id = ""
workers_dev = true
[env.production]
name = "scrobble-worker-production"
routes = [
{ pattern = "coryd.dev/api/scrobble*", zone_id = "" }
]