From 32296049d4ed5c43be6c10e1b230581cf2ecaa5f Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Sat, 8 Jun 2024 18:54:18 -0700 Subject: [PATCH] chore: cleanup --- .github/workflows/scheduled-build.yaml | 12 --- _redirects | 44 ++++----- api/now-playing.js | 88 ----------------- api/scrobble.js | 130 ------------------------- netlify.toml | 89 ----------------- 5 files changed, 17 insertions(+), 346 deletions(-) delete mode 100644 .github/workflows/scheduled-build.yaml delete mode 100644 api/now-playing.js delete mode 100644 api/scrobble.js delete mode 100644 netlify.toml diff --git a/.github/workflows/scheduled-build.yaml b/.github/workflows/scheduled-build.yaml deleted file mode 100644 index a8a02656..00000000 --- a/.github/workflows/scheduled-build.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: Scheduled Netlify Build -on: - workflow_dispatch: - schedule: - - cron: '0 * * * *' -jobs: - build: - name: Request Netlify Webhook - runs-on: ubuntu-latest - steps: - - name: POST to Build Hook - run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_BUILD_KEY }}?trigger_branch=main&trigger_title=Scheduled+Github+build&clear_cache=true \ No newline at end of file diff --git a/_redirects b/_redirects index be89e01b..e5aa21a4 100644 --- a/_redirects +++ b/_redirects @@ -42,7 +42,6 @@ /posts/2024 / 301! /books/want-to-read/ /books 301! /blog/digital-privacy-tools /posts/2021/digital-privacy-tools/ 301! -/assets/img/logo.webp https://coryd-dev.b-cdn.net/assets/avatar.webp 301! # 400s /wp-* /400/ 400 @@ -62,22 +61,23 @@ //wp/* /400/ 400 //test/ /400/ 400 /api/v* /400/ 400 -/undefined /400 301! +/undefined /400 400 # assets -/favicon.ico https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 200! -/assets/icons/favicon.ico https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 200! -/apple-touch-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 200! -/apple-touch-icon https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 200! -/apple-touch-icon-precomposed.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 200! -/assets/icons/apple-touch-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 200! -/assets/img/feed-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 200! -/static/favicons/apple-touch-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 200! -/static/images/avatar.png https://coryd-dev.b-cdn.net/assets/avatar.png 200! -/static/images/avatar.webp https://coryd-dev.b-cdn.net/assets/avatar.webp 200! -/assets/img/favicon/favicon-32x32.png https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 200! -/assets/img/favicon/favicon-16x16.png https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 200! -/assets/img/logo.webp https://coryd-dev.b-cdn.net/assets/avatar.webp 200! +/favicon.ico https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 301 +/assets/icons/favicon.ico https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 301! +/apple-touch-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 301! +/apple-touch-icon https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 301! +/apple-touch-icon-precomposed.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 301! +/assets/icons/apple-touch-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 301! +/assets/img/feed-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 301! +/assets/img/logo.webp https://coryd-dev.b-cdn.net/assets/avatar.webp 301! +/static/favicons/apple-touch-icon.png https://coryd-dev.b-cdn.net/assets/icons/apple-touch-icon.png 301! +/static/images/avatar.png https://coryd-dev.b-cdn.net/assets/avatar.png 301! +/static/images/avatar.webp https://coryd-dev.b-cdn.net/assets/avatar.webp 301! +/assets/img/favicon/favicon-32x32.png https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 301! +/assets/img/favicon/favicon-16x16.png https://coryd-dev.b-cdn.net/assets/icons/favicon.ico 301! +/assets/img/logo.webp https://coryd-dev.b-cdn.net/assets/avatar.webp 301! # general /articles/ / 301! @@ -90,9 +90,6 @@ /mastodon https://social.lol/@cory 301! /coffee https://www.buymeacoffee.com/cory 301! -# netlify app domain -https://cdme.netlify.app https://coryd.dev 301! - # feeds /rss https://feedpress.me/coryd 301! /atom https://feedpress.me/coryd 301! @@ -105,12 +102,5 @@ https://cdme.netlify.app https://coryd.dev 301! /books.json https://feedpress.me/coryd-books.json /links.xml https://feedpress.me/coryd-links /links.json https://feedpress.me/coryd-links.json -/follow.xml https://feedpress.me/coryd-follow -/follow.json https://feedpress.me/coryd-follow.json - -# media -/media/* https://f001.backblazeb2.com/file/coryd-dev/:splat 200! - -# analytics -/js/script.js https://plausible.io/js/script.tagged-events.outbound-links.js 200 -/api/event https://plausible.io/api/event 200 \ No newline at end of file +/follow.xml https://feedpress.me/coryd-all +/follow.json https://feedpress.me/coryd-all.json \ No newline at end of file diff --git a/api/now-playing.js b/api/now-playing.js deleted file mode 100644 index 6bc4074e..00000000 --- a/api/now-playing.js +++ /dev/null @@ -1,88 +0,0 @@ -import { createClient } from '@supabase/supabase-js'; -import slugify from 'slugify' - -const SUPABASE_URL = process.env.SUPABASE_URL -const SUPABASE_KEY = process.env.SUPABASE_KEY -const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) - -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 (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 () => { - 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(data[0].artists.genres) - const emoji = scrobbleData.artists.emoji || genreEmoji - - return new Response(JSON.stringify({ - content: `${emoji || '🎧'} ${scrobbleData.track_name} by ${ - scrobbleData.artist_name - }`, - }), { headers }); -}; - -export const config = { - cache: "manual", - path: "/api/now-playing" -}; \ No newline at end of file diff --git a/api/scrobble.js b/api/scrobble.js deleted file mode 100644 index 7c5d7b6b..00000000 --- a/api/scrobble.js +++ /dev/null @@ -1,130 +0,0 @@ -import { createClient } from '@supabase/supabase-js' -import { DateTime } from 'luxon' -import slugify from 'slugify' - -const SUPABASE_URL = Netlify.env.get('SUPABASE_URL') -const SUPABASE_KEY = Netlify.env.get('SUPABASE_KEY') -const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) - -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 (request) => { - const ACCOUNT_ID_PLEX = process.env.ACCOUNT_ID_PLEX - const params = new URL(request.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 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) { - console.error('Error inserting artist into Supabase:', insertArtistError.message) - 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) { - console.error('Error querying artist from Supabase:', artistError.message) - 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) { - console.error('Error inserting album into Supabase:', insertAlbumError.message) - 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) { - console.error('Error querying album from Supabase:', albumError.message) - 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) { - console.error('Error inserting data into Supabase:', listenError.message) - console.log('Track with the error:', { - artist_name: artistData.name_string, - album_name: albumData.name, - track_name: track, - listened_at: listenedAt, - album_key: albumKey - }) - 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" } }) -} - -export const config = { - path: '/api/scrobble', -} \ No newline at end of file diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index bf7c9bc7..00000000 --- a/netlify.toml +++ /dev/null @@ -1,89 +0,0 @@ -### -# BUILD -### -[build] - command = "npm run build" - publish = "_site" - edge_functions = "api" - -### -# IMAGES -### -[images] - remote_images = ["https://f001.backblazeb2.com/file/coryd-dev/.*"] - -### -# URLs -### -[build.processing.html] - pretty_urls = true - -### -# HEADERS -### -[[headers]] - for = "/media/*" - [headers.values] - Cache-Control = "public, max-age=15552000, must-revalidate" - -[[headers]] -for = "/feeds/posts" - [headers.values] - Content-Type = "application/xml; charset=utf-8" - x-content-type-options = "nosniff" - -[[headers]] -for = "/feeds/links" - [headers.values] - Content-Type = "application/xml; charset=utf-8" - x-content-type-options = "nosniff" - -[[headers]] -for = "/feeds/books" - [headers.values] - Content-Type = "application/xml; charset=utf-8" - x-content-type-options = "nosniff" - -[[headers]] -for = "/.well-known/webfinger" - [headers.values] - Content-Type = "application/jrd+json; charset=utf-8" - -[[headers]] -for = "/.well-known/gpc.json" - [headers.values] - Content-Type = "application/jrd+json; charset=utf-8" - -[[headers]] -for = "/.well-known/traffic-advice" - [headers.values] - Content-Type = "application/trafficadvice+json" - -[[headers]] -for = "/contribute.json" - [headers.values] - Content-Type = "application/json" - -[[headers]] -for = "/api/now-playing" - [headers.values] - Content-Type = "application/json" - -[[headers]] -for = "/api/search" - [headers.values] - Content-Type = "application/json" - -[[headers]] -for = "/blogroll.opml" - [headers.values] - Content-Disposition = "attachment; filename=cory-dransfeldt-blogroll.opml" - -[[headers]] - for = "/*" - [headers.values] - Content-Security-Policy = "upgrade-insecure-requests; block-all-mixed-content;" - X-Frame-Options = "DENY" - X-XSS-Protection = "1; mode=block" - Referrer-Policy = "strict-origin-when-cross-origin, no-referrer-when-downgrade" - Permissions-Policy = "autoplay=(), camera=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=()"