From 1880790c059284c8ced8c8703672acf9d213c2ee Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Wed, 9 Oct 2024 18:10:28 -0700 Subject: [PATCH] feat: massive refactor --- config/collections/index.js | 45 ++--- config/filters/feeds.js | 48 +++--- config/filters/media.js | 28 +--- package-lock.json | 28 +--- package.json | 2 +- src/assets/styles/components/tab-buttons.css | 18 +- src/data/albumReleases.js | 41 +---- src/data/artists.js | 65 +------- src/data/books.js | 66 +------- src/data/concerts.js | 29 +--- src/data/genres.js | 39 +---- src/data/links.js | 39 +---- src/data/movies.js | 85 ++-------- src/data/music.js | 116 ++++++------- src/data/pages.js | 68 +------- src/data/posts.js | 41 +---- src/data/tv.js | 156 ++---------------- src/includes/base.liquid | 21 ++- src/includes/partials/blocks/hero.liquid | 8 +- src/includes/partials/blocks/index.liquid | 2 +- src/includes/partials/feeds/json.liquid | 6 +- src/includes/partials/feeds/rss.liquid | 2 +- .../partials/home/recent-activity.liquid | 7 +- .../partials/media/watching/grid.liquid | 2 +- src/pages/dynamic/books/index.html | 3 +- src/pages/dynamic/books/year.html | 2 +- src/pages/dynamic/links.html | 2 +- src/pages/dynamic/music/index.html | 6 +- src/pages/dynamic/page.html | 4 +- .../dynamic/watching/favorites/movies.html | 2 +- .../dynamic/watching/favorites/shows.html | 2 +- src/pages/dynamic/watching/index.html | 4 +- src/pages/dynamic/watching/recent/shows.html | 2 +- src/pages/dynamic/watching/show.html | 9 +- src/pages/feeds/json/album-releases.liquid | 2 +- src/pages/feeds/json/books.liquid | 2 +- src/pages/feeds/rss/album-releases.liquid | 2 +- src/pages/feeds/rss/books.liquid | 2 +- 38 files changed, 245 insertions(+), 761 deletions(-) diff --git a/config/collections/index.js b/config/collections/index.js index 0ea10c4b..f77043c3 100644 --- a/config/collections/index.js +++ b/config/collections/index.js @@ -6,6 +6,7 @@ const BASE_URL = 'https://coryd.dev' const md = markdownIt() const normalizeWord = (word) => { + if (!word) return '' const wordMap = { 'ai': 'AI', 'css': 'CSS', @@ -14,12 +15,12 @@ const normalizeWord = (word) => { 'macos': 'macOS', 'tv': 'TV' } - return wordMap[word.toLowerCase()] || word.charAt(0).toUpperCase() + word.slice(1) + return wordMap[word?.toLowerCase()] || word?.charAt(0).toUpperCase() + word.slice(1) } const tagsToHashtags = (item) => { - const tags = item?.tags || [] - if (tags.length) return tags.map(tag => '#' + tag.split(' ').map(normalizeWord).join('')).join(' ') + const tags = item?.['tags'] || [] + if (tags.length) return tags.map(tag => '#' + normalizeWord(tag)).join(' ') return '' } @@ -40,7 +41,7 @@ export const processContent = (collection) => { { method: 'fromISO' }, { method: 'fromFormat', format: 'yyyy-MM-dd' }, { method: 'fromFormat', format: 'MM/dd/yyyy' }, - { method: 'fromFormat', format: 'dd-MM-yyyy' }, + { method: 'fromFormat', format: 'dd-MM-yyyy' } ] for (const { method, format } of formats) { @@ -115,16 +116,16 @@ export const processContent = (collection) => { if (item['type'] === 'album-release') hashTags = ' #Music #NewMusic' if (item['type'] === 'concert') hashTags = ' #Music #Concert' - if (item?.['authors']?.['mastodon']) { - const mastoUrl = new URL(item['authors']['mastodon']) + if (item?.['author']?.['mastodon']) { + const mastoUrl = new URL(item['author']['mastodon']) attribution = `${mastoUrl.pathname.replace('/', '')}@${mastoUrl.host}` - } else if (item?.['authors']?.['name']) { - attribution = item['authors']['name'] + } else if (item?.['author']?.['name']) { + attribution = item['author']['name'] } let url = item['url'] || item['link'] if (url && !isValidUrl(url)) url = absoluteUrl(url) - if (item['type'] === 'concert') url = `${item['artistUrl'] ? item['artistUrl'] : BASE_URL + '/music/concerts'}?t=${DateTime.fromISO(item['date']).toMillis()}${item['artistUrl'] ? '#concerts' : ''}` + if (item['type'] === 'concert') url = `${item['artist']?.['url'] ? item['artist']['url'] : BASE_URL + '/music/concerts'}?t=${DateTime.fromISO(item['date']).toMillis()}${item['artist']?.['url'] ? '#concerts' : ''}` const content = { url, @@ -149,12 +150,12 @@ export const processContent = (collection) => { } const movieData = movies['movies'].filter((movie) => movie['rating']) - const showData = tv['shows'].filter((show) => show['episodes']?.[0]?.['last_watched_at']) - const bookData = books.all.filter((book) => book['rating']) + const showData = tv['shows'].filter((show) => show?.['episode']?.['formatted_episode']) + const bookData = books['all'].filter((book) => book['rating']) addItemToIndex(posts, '📝', (item) => item['url'], (item) => item['title'], (item) => item['tags']) addItemToIndex(links, '🔗', (item) => item['link'], (item) => item['title'], (item) => item['tags']) - addItemToIndex(artists, '🎙️', (item) => item['url'], (item) => `${item['name']} (${item['country']}) - ${item['genre']['name']}`, (item) => `['${item['genre']}']`) + addItemToIndex(artists, '🎙️', (item) => item['url'], (item) => `${item['name']} (${item['country']}) - ${item['genre']?.['name']}`, (item) => `['${item['genre']}']`) addItemToIndex(genres, '🎵', (item) => item['url'], (item) => item['name'], (item) => item.artists.map(artist => artist['name_string'])) if (movieData) addItemToIndex(movieData, '🎥', (item) => item['url'], (item) => `${item['title']} (${item['rating']})`, (item) => item['tags']) if (showData) addItemToIndex(showData, '📺', (item) => item['url'], (item) => `${item['title']} (${item['year']})`, (item) => item['tags']) @@ -167,13 +168,13 @@ export const processContent = (collection) => { addContent(concerts, '🎤', (item) => `${item['artistNameString'] ? item['artistNameString'] : item['artist']['name']} at ${item['venue']['name'].split(',')[0].trim()}`, (item) => item['date']) addContent([...albumReleases['current']].reverse(), '📆', (item) => `${item['title']} by ${item['artist']['name']}`, (item) => item['release_date']) - addSiteMapContent(posts, (item) => item.title, (item) => item.date) - addSiteMapContent(pages, (item) => item.title, (item) => item.date) - addSiteMapContent(artists, (item) => item.name, (item) => item.date) - addSiteMapContent(genres, (item) => item.name, (item) => item.date) - addSiteMapContent(movies['movies'], (item) => item.title, (item) => item.date) - addSiteMapContent(books.all, (item) => item.title, (item) => item.date) - addSiteMapContent(tv?.['shows'], (item) => item.title, (item) => item.date) + addSiteMapContent(posts, (item) => item['title'], (item) => item['date']) + addSiteMapContent(pages, (item) => item['title'], (item) => item['date']) + addSiteMapContent(artists, (item) => item['name'], (item) => item['date']) + addSiteMapContent(genres, (item) => item['name'], (item) => item['date']) + addSiteMapContent(movies['movies'], (item) => item['title'], (item) => item['date']) + addSiteMapContent(books.all, (item) => item['title'], (item) => item['date']) + addSiteMapContent(tv?.['shows'], (item) => item['title'], (item) => item['date']) return { searchIndex, @@ -197,7 +198,7 @@ export const albumReleasesCalendar = (collection) => { if (!all || all.length === 0) return '' const events = all.map(album => { - const date = DateTime.fromFormat(album.date, 'MMMM d, yyyy') + const date = DateTime.fromFormat(album['date'], 'MMMM d, yyyy') if (!date.isValid) return null return { @@ -206,8 +207,8 @@ export const albumReleasesCalendar = (collection) => { startOutputType: 'local', title: `Release: ${album['artist']['name']} - ${album['title']}`, description: `Check out this new album release: ${album['url']}. Read more about ${album['artist']['name']} at https://coryd.dev${album['artist']['url']}`, - url: album.url, - uid: `${date.toFormat('yyyyMMdd')}-${album['artist']['name']}-${album.title}@coryd.dev`, + url: album['url'], + uid: `${date.toFormat('yyyyMMdd')}-${album['artist']['name']}-${album['title']}@coryd.dev`, timestamp: DateTime.now().toUTC().toFormat("yyyyMMdd'T'HHmmss'Z'") } }).filter(event => event !== null) diff --git a/config/filters/feeds.js b/config/filters/feeds.js index bfff211f..5b6756bc 100644 --- a/config/filters/feeds.js +++ b/config/filters/feeds.js @@ -14,13 +14,13 @@ export default { const md = markdownIt({ html: true, linkify: true }) md.use(markdownItAnchor, { level: [1, 2], - permalink: markdownItAnchor.permalink.headerLink({ safariReaderFix: true }) + permalink: markdownItAnchor['permalink']['headerLink']({ safariReaderFix: true }) }) md.use(markdownItFootnote) - md.renderer.rules.footnote_ref = (tokens, idx) => `${tokens[idx].meta.id + 1}` - md.renderer.rules.footnote_block_open = () => '
\n
\n
    \n' - md.renderer.rules.footnote_open = (tokens, idx) => `
  1. ` - md.renderer.rules.footnote_anchor = () => '' + md.renderer['rules']['footnote_ref'] = (tokens, idx) => `${tokens[idx]['meta']['id'] + 1}` + md.renderer['rules']['footnote_block_open'] = () => '
    \n
    \n
      \n' + md.renderer['rules']['footnote_open'] = (tokens, idx) => `
    1. ` + md.renderer['rules']['footnote_anchor'] = () => '' return md } @@ -30,7 +30,7 @@ export default { const md = mdGenerator() const dateKey = Object.keys(entry).find(key => key.includes('date')) const { - artist, authors, backdrop, content, description, image, link, rating, review, + artist, author, backdrop, content, description, image, link, rating, review, slug, title, url, tags, type } = entry @@ -41,36 +41,36 @@ export default { } const feedNote = '

      This is a full text feed, but not all content can be rendered perfectly within the feed. If something looks off, feel free to visit my site for the original post.

      ' - processedEntry.url = (url?.includes('http')) ? url : new URL(slug || url, BASE_URL).toString() + processedEntry['url'] = (url?.includes('http')) ? url : new URL(slug || url, BASE_URL).toString() if (link) { - processedEntry.title = `${title} via ${authors?.name || 'Unknown'}` - processedEntry.url = link - processedEntry.author = { - name: authors?.name || 'Unknown', - url: authors?.url || '', - mastodon: authors?.mastodon || '', - rss: authors?.rss_feed || '' + processedEntry['title'] = `${title} via ${author?.['name'] || 'Unknown'}` + processedEntry['url'] = link + processedEntry['author'] = { + name: author?.['name'] || 'Unknown', + url: author?.['url'] || '', + mastodon: author?.['mastodon'] || '', + rss: author?.['rss_feed'] || '' } - processedEntry.excerpt = sanitizeHtml(md.render(description || '')) + processedEntry['excerpt'] = sanitizeHtml(md.render(description || '')) } else if (['book', 'movie'].includes(type)) { - processedEntry.excerpt = sanitizeHtml(md.render(review || description || '')) + processedEntry['excerpt'] = sanitizeHtml(md.render(review || description || '')) } else if (type === 'album-release') { let sanitizedDescription = sanitizeHtml(md.render(description || '')) let truncatedDescription = truncate(sanitizedDescription, { length: 500, reserveLastWord: true, ellipsis: '...' }) - if (sanitizedDescription.length > 500) truncatedDescription += `

      Read more about ${artist?.name}

      ` - processedEntry.excerpt = truncatedDescription + if (artist?.['name'] && artist?.['url'] && sanitizedDescription.length > 500) truncatedDescription += `

      Read more about ${artist['name']}

      ` + processedEntry['excerpt'] = truncatedDescription } else if (slug && content) { - processedEntry.excerpt = sanitizeHtml(md.render(content) + feedNote, { disallowedTagsMode: 'completelyDiscard' }) + processedEntry['excerpt'] = sanitizeHtml(md.render(content) + feedNote, { disallowedTagsMode: 'completelyDiscard' }) } else if (description) { - processedEntry.excerpt = description + processedEntry['excerpt'] = description } - processedEntry.image = backdrop || image + processedEntry['image'] = backdrop || image - if (rating) processedEntry.rating = rating - if (tags) processedEntry.tags = tags - if (type === 'album-release' && artist) processedEntry.title = `${title} by ${artist['name']}` + if (rating) processedEntry['rating'] = rating + if (tags) processedEntry['tags'] = tags + if (type === 'album-release' && artist) processedEntry['title'] = `${title} by ${artist['name']}` posts.push(processedEntry) }) diff --git a/config/filters/media.js b/config/filters/media.js index 1a9dadae..69cbc6fb 100644 --- a/config/filters/media.js +++ b/config/filters/media.js @@ -10,6 +10,7 @@ export default { const mediaData = limit ? media.slice(0, limit) : media return mediaData.map((item) => { let normalized = { + title: item['title'], image: item['image'], url: item['url'], type: item['type'] @@ -17,22 +18,18 @@ export default { switch (item['type']) { case 'artist': - normalized.title = item['title'] normalized.alt = `${item['plays']} plays of ${item['title']}` normalized.subtext = `${item['plays']} plays` break case 'album': - normalized.title = item['title'] normalized.alt = `${item['title']} by ${item['artist']}` normalized.subtext = `${item['artist']}` break case 'album-release': - normalized.title = item['title'] normalized.alt = `${item['title']} by ${item['artist']['name']}` normalized.subtext = `${item['artist']['name']} / ${item['date']}` break case 'movie': - normalized.title = item['title'] normalized.alt = item['title'] normalized.rating = item['rating'] normalized.favorite = item['favorite'] @@ -46,10 +43,8 @@ export default { } break case 'tv': - case 'tv-range': - normalized.title = item['name'] - normalized.alt = `${item['subtext']} ${item['type'] === 'tv' ? 'of' : 'from'} ${item['name']}` - normalized.subtext = item['subtext'] + normalized.alt = item['formatted_episode'] + normalized.subtext = item['formatted_episode'] break } @@ -57,29 +52,16 @@ export default { }) }, calculatePlayPercentage: (plays, mostPlayed) => `${plays/mostPlayed * 100}%`, - bookStatus: (books, status) => books.filter(book => book.status === status), + bookStatus: (books, status) => books.filter(book => book['status'] === status), bookFavorites: (books) => books.filter(book => book.favorite === true), bookYearLinks: (years) => years.sort((a, b) => b.value - a.value).map((year, index) => { const separator = index < years.length - 1 ? ' / ' : '' return `${year.value}${separator}` }).join(''), - bookSortDescending: (books) => books.filter(book => !isNaN(DateTime.fromISO(book.date).toMillis())).sort((a, b) => { - const dateA = DateTime.fromISO(a.date) - const dateB = DateTime.fromISO(b.date) - return dateB - dateA - }), bookFinishedYear: (books, year) => books.filter(book => { - if (book.status === 'finished' && book.date) return parseInt(book.date.split('-')[0]) === year + if (book['status'] === 'finished' && book['year']) return parseInt(book['year']) === parseInt(year) return '' }), - currentBookCount: (books) => { - const year = DateTime.now().year - return books.filter(book => { - if (book.status === 'finished' && book.date) return parseInt(book.date.split('-')[0]) === year - return '' - }).length - }, - getLastWatched: (show) => show?.['episodes'][show['episodes']?.length - 1]?.['last_watched_at'], sortByPlaysDescending: (data, key) => data.sort((a, b) => b[key] - a[key]), mediaLinks: (data, type, count = 10) => { if (!data || !type) return '' diff --git a/package-lock.json b/package-lock.json index 532ff51c..9777230d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "coryd.dev", - "version": "1.0.6", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd.dev", - "version": "1.0.6", + "version": "1.0.0", "license": "MIT", "dependencies": { "@cdransf/api-text": "^1.5.0", @@ -1767,9 +1767,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.33", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", - "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", + "version": "1.5.35", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.35.tgz", + "integrity": "sha512-hOSRInrIDm0Brzp4IHW2F/VM+638qOL2CzE0DgpnGzKW27C95IqqeqgKz/hxHGnvPxvQGpHUGD5qRVC9EZY2+A==", "dev": true, "license": "ISC" }, @@ -4521,16 +4521,16 @@ "license": "MIT" }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.1.tgz", + "integrity": "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==", "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", @@ -4562,16 +4562,6 @@ "dev": true, "license": "MIT" }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", diff --git a/package.json b/package.json index 569656d4..53f06c82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coryd.dev", - "version": "1.0.6", + "version": "1.0.0", "description": "The source for my personal site. Built using 11ty (and other tools).", "type": "module", "scripts": { diff --git a/src/assets/styles/components/tab-buttons.css b/src/assets/styles/components/tab-buttons.css index 0421ce47..c11a3a6e 100644 --- a/src/assets/styles/components/tab-buttons.css +++ b/src/assets/styles/components/tab-buttons.css @@ -1,40 +1,40 @@ #tracks-recent, -#tracks-window, +#tracks-chart, #tracks-recent ~ .tracks-recent, -#tracks-window ~ .tracks-window { +#tracks-chart ~ .tracks-chart { display: none; } #tracks-recent:checked ~ .tracks-recent, -#tracks-window:checked ~ .tracks-window { +#tracks-chart:checked ~ .tracks-chart { display: block; } input[id="tracks-recent"] ~ .tracks-recent, -input[id="tracks-window"] ~ .tracks-window { +input[id="tracks-chart"] ~ .tracks-chart { margin-top: var(--spacing-base); } -input[id="tracks-recent"] ~ [for="tracks-recent"]:has(+ [for="tracks-window"]) { +input[id="tracks-recent"] ~ [for="tracks-recent"]:has(+ [for="tracks-chart"]) { margin-right: var(--spacing-xs); } #tracks-recent:checked ~ [for="tracks-recent"], -#tracks-window:checked ~ [for="tracks-window"] { +#tracks-chart:checked ~ [for="tracks-chart"] { cursor: not-allowed; border-color: var(--accent-color); background-color: var(--accent-color); } #tracks-recent:not(:checked) ~ [for="tracks-recent"], -#tracks-window:not(:checked) ~ [for="tracks-window"] { +#tracks-chart:not(:checked) ~ [for="tracks-chart"] { color: var(--accent-color); background: transparent; } #tracks-recent:not(:checked) ~ [for="tracks-recent"]:hover, #tracks-recent:not(:checked) ~ [for="tracks-recent"]:active, -#tracks-window:not(:checked) ~ [for="tracks-window"]:hover, -#tracks-window:not(:checked) ~ [for="tracks-window"]:active { +#tracks-chart:not(:checked) ~ [for="tracks-chart"]:hover, +#tracks-chart:not(:checked) ~ [for="tracks-chart"]:active { color: var(--accent-color-hover); } \ No newline at end of file diff --git a/src/data/albumReleases.js b/src/data/albumReleases.js index b61c8f3e..b265e935 100644 --- a/src/data/albumReleases.js +++ b/src/data/albumReleases.js @@ -6,21 +6,11 @@ const SUPABASE_KEY = process.env.SUPABASE_KEY const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) const fetchAlbumReleases = async () => { - const today = DateTime.utc().startOf('day') + const today = DateTime.utc().startOf('day').toSeconds() + const { data, error } = await supabase .from('optimized_album_releases') - .select(` - name, - release_date, - release_link, - total_plays, - art, - artist_name, - artist_description, - artist_total_plays, - artist_country, - artist_favorite - `) + .select('*') if (error) { console.error('Error fetching data:', error) @@ -28,31 +18,18 @@ const fetchAlbumReleases = async () => { } const all = data.map(album => { - const releaseDate = DateTime.fromISO(album['release_date']).toUTC().startOf('day') + const releaseDate = DateTime.fromSeconds(album['release_timestamp']).toUTC().startOf('day') return { - artist: { - name: album['artist_name'], - description: album['artist_description'], - total_plays: album['artist_total_plays'], - country: album['artist_country'], - favorite: album['artist_favorite'], - url: album['artist_url'], - }, - title: album['name'], + ...album, + description: album['artist']['description'], date: releaseDate.toLocaleString(DateTime.DATE_FULL), - description: album['artist_description'], - url: album['release_link'], - image: album['art'] ? `/${album['art']}` : '', - total_plays: album['total_plays'], - release_date: releaseDate, - type: 'album-release', - timestamp: releaseDate.toSeconds(), + timestamp: releaseDate.toSeconds() } }).sort((a, b) => a['timestamp'] - b['timestamp']) - const upcoming = all.filter(album => (!album['total_plays'] || album['total_plays'] <= 0) && album['release_date'] > today) - const current = all.filter(album => album['release_date'] <= today) + const upcoming = all.filter(album => album['release_timestamp'] > today) + const current = all.filter(album => album['release_timestamp'] <= today) return { all, upcoming, current } } diff --git a/src/data/artists.js b/src/data/artists.js index 31c4b6a7..c8ba947a 100644 --- a/src/data/artists.js +++ b/src/data/artists.js @@ -13,27 +13,7 @@ const fetchAllArtists = async () => { while (true) { const { data, error } = await supabase .from('optimized_artists') - .select(` - id, - name_string, - url, - tentative, - total_plays, - country, - description, - favorite, - genre, - emoji, - tattoo, - art, - albums, - concerts, - books, - movies, - posts, - related_artists, - shows - `) + .select('*') .range(rangeStart, rangeStart + PAGE_SIZE - 1) if (error) { @@ -51,49 +31,8 @@ const fetchAllArtists = async () => { const processArtists = (artists) => { return artists.map(artist => ({ - name: artist['name_string'], - tentative: artist['tentative'], - totalPlays: artist['total_plays'], + ...artist, country: parseCountryField(artist['country']), - description: artist['description'], - favorite: artist['favorite'], - genre: { - name: artist['genre']['name'], - url: artist['genre']['url'], - }, - emoji: artist['emoji'], - tattoo: artist['tattoo'], - image: artist['art'] ? `/${artist['art']}` : '', - url: artist['url'], - albums: (artist['albums'] || []).map(album => ({ - name: album['name'], - releaseYear: album['release_year'], - totalPlays: album['total_plays'], - art: album.art ? `/${album['art']}` : '' - })).sort((a, b) => a['release_year'] - b['release_year']), - concerts: artist['concerts'] ? artist['concerts'].sort((a, b) => new Date(b['date']) - new Date(a['date'])) : null, - books: artist['books'] ? artist['books'].map(book => ({ - title: book['title'], - author: book['author'], - description: book['description'], - url: `/books/${book['isbn']}`, - })).sort((a, b) => a['title'].localeCompare(b['title'])) : null, - movies: artist['movies'] ? artist['movies'].map(movie => ({ - title: movie['title'], - year: movie['year'], - url: `/watching/movies/${movie['tmdb_id']}`, - })).sort((a, b) => b['year'] - a['year']) : null, - shows: artist['shows'] ? artist['shows'].map(show => ({ - title: show['title'], - year: show['year'], - url: `/watching/shows/${show['tmdb_id']}`, - })).sort((a, b) => b['year'] - a['year']) : null, - posts: artist['posts'] ? artist['posts'].map(post => ({ - title: post['title'], - date: post['date'], - url: post['url'], - })).sort((a, b) => new Date(b['date']) - new Date(a['date'])) : null, - relatedArtists: artist['related_artists'] ? artist['related_artists'].sort((a, b) => a['name'].localeCompare(b['name'])) : null, })) } diff --git a/src/data/books.js b/src/data/books.js index d3860a86..0642e57c 100644 --- a/src/data/books.js +++ b/src/data/books.js @@ -12,33 +12,12 @@ const fetchAllBooks = async () => { while (true) { const { data, error } = await supabase .from('optimized_books') - .select(` - id, - isbn, - date_finished, - author, - description, - title, - progress, - read_status, - star_rating, - review, - art, - favorite, - tattoo, - tags, - artists, - genres, - movies, - posts, - shows, - related_books - `) + .select('*') .order('date_finished', { ascending: false }) .range(rangeStart, rangeStart + PAGE_SIZE - 1) if (error) { - console.error('Error fetching data from Supabase:', error) + console.error('Error fetching books:', error) break } @@ -52,45 +31,11 @@ const fetchAllBooks = async () => { const processBooks = (books) => { return books.map(book => { - const dateFinished = new Date(book['date_finished']) - const year = dateFinished.getUTCFullYear() + const dateFinished = book['date_finished'] ? new Date(book['date_finished']) : null + const year = dateFinished && !isNaN(dateFinished.getTime()) ? dateFinished.getUTCFullYear() : null return { - title: book['title'], - author: book['author'] || '', - review: book['review'], - rating: book['star_rating'] !== 'unrated' ? book['star_rating'] : '', - favorite: book['favorite'], - tattoo: book['tattoo'], - description: book['description'], - image: `/${book['art']}`, - url: `/books/${book['isbn']}`, - date: book['date_finished'], - status: book['read_status'], - progress: book['progress'], - tags: Array.isArray(book['tags']) ? book['tags'] : book['tags']?.split(',') || [], - type: 'book', - artists: book['artists'] ? book['artists'].sort((a, b) => a['name'].localeCompare(b['name'])) : null, - movies: book['movies'] ? book['movies'].map(movie => { - movie['url'] = `/watching/movies/${movie['tmdb_id']}` - return movie - }).sort((a, b) => b['year'] - a['year']) : null, - genres: book['genres'] ? book['genres'].sort((a, b) => a['name'].localeCompare(b['name'])) : null, - shows: book['shows'] ? book['shows'].map(show => { - show['url'] = `/watching/shows/${show['tmdb_id']}` - return show - }).sort((a, b) => b['year'] - a['year']) : null, - posts: book['posts'] ? book['posts'].map(post => ({ - title: post['title'], - date: post['date'], - url: post['url'], - })).sort((a, b) => new Date(b['date']) - new Date(a['date'])) : null, - relatedBooks: book['related_books'] ? book['related_books'].map(relatedBook => ({ - title: relatedBook['title'], - author: relatedBook['author'], - description: relatedBook['description'], - url: `/books/${relatedBook['isbn']}`, - })).sort((a, b) => a['title'].localeCompare(b['title'])) : null, // Add related books processing + ...book, year, } }) @@ -112,5 +57,6 @@ const sortBooksByYear = (books) => { export default async function () { const books = await fetchAllBooks() const processedBooks = processBooks(books) + return { all: processedBooks, years: sortBooksByYear(processedBooks) } } \ No newline at end of file diff --git a/src/data/concerts.js b/src/data/concerts.js index 8716c6e0..0d8dd3e1 100644 --- a/src/data/concerts.js +++ b/src/data/concerts.js @@ -12,13 +12,7 @@ const fetchAllConcerts = async () => { while (true) { const { data, error } = await supabase .from('optimized_concerts') - .select(` - id, - date, - artist, - venue, - concert_notes - `) + .select('*') .range(rangeStart, rangeStart + PAGE_SIZE - 1) if (error) { @@ -36,24 +30,9 @@ const fetchAllConcerts = async () => { const processConcerts = (concerts) => { return concerts.map(concert => ({ - id: concert['id'], - type: 'concert', - date: concert['date'], - artist: concert['artist'] && typeof concert['artist'] === 'object' ? { - name: concert['artist'].name, - url: concert['artist'].url - } : { name: concert['artist'], url: null }, - venue: concert['venue'] && typeof concert['venue'] === 'object' ? { - name: concert['venue'].name, - latitude: concert['venue'].latitude, - longitude: concert['venue'].longitude, - notes: concert['venue'].notes - } : null, - description: 'I went to (yet another) concert!', - notes: concert['concert_notes'], - url: `/music/concerts?id=${concert['id']}`, - artistUrl: concert['artist'] && typeof concert['artist'] === 'object' ? concert['artist'].url : null - })).sort((a, b) => new Date(b['date']) - new Date(a['date'])) + ...concert, + artist: concert.artist || { name: concert.artist_name_string, url: null }, + })) } export default async function () { diff --git a/src/data/genres.js b/src/data/genres.js index 9d641ab8..aa6f20a9 100644 --- a/src/data/genres.js +++ b/src/data/genres.js @@ -4,53 +4,22 @@ const SUPABASE_URL = process.env.SUPABASE_URL const SUPABASE_KEY = process.env.SUPABASE_KEY const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) -const fetchGenresWithArtists = async () => { +const fetchGenres = async () => { const { data, error } = await supabase .from('optimized_genres') - .select(` - name, - description, - total_plays, - wiki_link, - url, - artists, - books, - movies, - posts - `) - .order('id', { ascending: true }) + .select('*') if (error) { console.error('Error fetching genres with artists:', error) return [] } - return data.map(genre => ({ - ...genre, - artists: genre['artists'], - url: genre['url'], - books: genre['books'] ? genre['books'].map(book => ({ - title: book['title'], - author: book['author'], - description: book['description'], - url: `/books/${book['isbn']}`, - })).sort((a, b) => a['title'].localeCompare(b['title'])) : null, - movies: genre['movies'] ? genre['movies'].map(movie => ({ - title: movie['title'], - year: movie['year'], - url: `/watching/movies/${movie['tmdb_id']}`, - })).sort((a, b) => b['year'] - a['year']) : null, - posts: genre['posts'] ? genre['posts'].map(post => ({ - title: post['title'], - date: post['date'], - url: post['url'], - })).sort((a, b) => new Date(b['date']) - new Date(a['date'])) : null, - })) + return data } export default async function () { try { - return await fetchGenresWithArtists() + return await fetchGenres() } catch (error) { console.error('Error fetching and processing genres:', error) return [] diff --git a/src/data/links.js b/src/data/links.js index 7a73a908..e6d2a76a 100644 --- a/src/data/links.js +++ b/src/data/links.js @@ -5,24 +5,6 @@ const SUPABASE_KEY = process.env.SUPABASE_KEY const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) const PAGE_SIZE = 1000 -const fetchAllTags = async () => { - const { data, error } = await supabase - .from('links_tags') - .select('links_id, tags(name)') - - if (error) { - console.error('Error fetching all tags from Supabase:', error) - return {} - } - - return data.reduce((acc, { links_id, tags }) => { - if (!tags || !tags.name) return acc - if (!acc[links_id]) acc[links_id] = [] - acc[links_id].push(tags['name']) - return acc - }, {}) -} - const fetchAllLinks = async () => { let links = [] let page = 0 @@ -30,9 +12,8 @@ const fetchAllLinks = async () => { while (fetchMore) { const { data, error } = await supabase - .from('links') - .select('*, authors (name, url, mastodon)') - .order('date', { ascending: false }) + .from('optimized_links') + .select('*') .range(page * PAGE_SIZE, (page + 1) * PAGE_SIZE - 1) if (error) { @@ -49,15 +30,11 @@ const fetchAllLinks = async () => { return links } -const processLinks = (links, tagsByLinkId) => { - return links.map(link => { - link['tags'] = tagsByLinkId[link['id']] || [] - link['type'] = 'link' - return link - }) -} - export default async function () { - const [links, tagsByLinkId] = await Promise.all([fetchAllLinks(), fetchAllTags()]) - return processLinks(links, tagsByLinkId) + try { + return await fetchAllLinks() + } catch (error) { + console.error('Error fetching and processing links:', error) + return [] + } } \ No newline at end of file diff --git a/src/data/movies.js b/src/data/movies.js index 4a0c5855..981a1ea0 100644 --- a/src/data/movies.js +++ b/src/data/movies.js @@ -13,34 +13,11 @@ const fetchAllMovies = async () => { while (true) { const { data, error } = await supabase .from('optimized_movies') - .select(` - id, - tmdb_id, - last_watched, - title, - year, - collected, - plays, - favorite, - tattoo, - star_rating, - description, - review, - art, - backdrop, - tags, - artists, - books, - genres, - shows, - posts, - related_movies - `) - .order('last_watched', { ascending: false }) + .select('*') .range(rangeStart, rangeStart + PAGE_SIZE - 1) if (error) { - console.error(error) + console.error('Error fetching movies:', error) break } @@ -53,62 +30,20 @@ const fetchAllMovies = async () => { return movies } -const processMovies = (movies) => { - return movies.map(item => ({ - title: item['title'], - lastWatched: item['last_watched'], - dateAdded: item['last_watched'], - year: item['year'], - url: `/watching/movies/${item['tmdb_id']}`, - description: item['description'], - image: item['art'] ? `/${item['art']}` : '', - backdrop: item['backdrop'] ? `/${item['backdrop']}` : '', - plays: item['plays'], - collected: item['collected'], - favorite: item['favorite'], - tattoo: item['tattoo'], - rating: item['star_rating'], - review: item['review'], - type: 'movie', - tags: item['tags'] ? item['tags'].split(',') : [], - artists: item['artists'] ? item['artists'].sort((a, b) => a['name'].localeCompare(b['name'])) : null, - books: item['books'] ? item['books'].map(book => { - book['url'] = `/books/${book['isbn']}` - return book - }).sort((a, b) => a['title'].localeCompare(b['title'])) : null, - genres: item['genres'] ? item['genres'].sort((a, b) => a['title'].localeCompare(b['title'])) : null, - shows: item['shows'] ? item['shows'].map(show => { - show['url'] = `/watching/shows/${show['tmdb_id']}` - return show - }).sort((a, b) => b['year'] - a['year']) : null, - posts: item['posts'] ? item['posts'].map(post => ({ - title: post['title'], - date: post['date'], - url: post['url'], - })).sort((a, b) => new Date(b['date']) - new Date(a['date'])) : null, - relatedMovies: item['related_movies'] ? item['related_movies'].map(movie => { - movie['url'] = `/watching/movies/${movie['tmdb_id']}` - return movie - }).sort((a, b) => b['year'] - a['year']) : null, - })) -} - export default async function () { const year = DateTime.now().year try { const movies = await fetchAllMovies() - const processedMovies = processMovies(movies) - const filterMovies = (condition) => processedMovies.filter(condition) - const formatMovieData = (movies) => movies.map(movie => movie) - const favoriteMovies = filterMovies(movie => movie['favorite']) - const recentlyWatchedMovies = filterMovies(movie => movie['lastWatched'] && year - DateTime.fromISO(movie['lastWatched']).year <= 3).sort((a, b) => new Date(b['lastWatched']) - new Date(a['lastWatched'])) + const filterMovies = (condition) => movies.filter(condition) + const favoriteMovies = filterMovies(movie => movie.favorite) + const recentlyWatchedMovies = filterMovies(movie => movie.last_watched && year - DateTime.fromISO(movie.last_watched).year <= 3) return { - movies: formatMovieData(processedMovies), - watchHistory: formatMovieData(filterMovies(movie => movie['lastWatched'])), - recentlyWatched: formatMovieData(recentlyWatchedMovies), - favorites: formatMovieData(favoriteMovies).sort((a, b) => a['title'].localeCompare(b['title'])), + movies, + watchHistory: filterMovies(movie => movie.last_watched), + recentlyWatched: recentlyWatchedMovies, + favorites: favoriteMovies.sort((a, b) => a.title.localeCompare(b.title)), } } catch (error) { console.error('Error fetching and processing movies data:', error) @@ -116,7 +51,7 @@ export default async function () { movies: [], watchHistory: [], recentlyWatched: [], - favorites: [], + favorites: [] } } } \ No newline at end of file diff --git a/src/data/music.js b/src/data/music.js index f0391a8f..b4902222 100644 --- a/src/data/music.js +++ b/src/data/music.js @@ -5,14 +5,14 @@ const SUPABASE_KEY = process.env.SUPABASE_KEY const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) const PAGE_SIZE = 1000 -const fetchDataFromView = async (viewName, fields) => { +const fetchDataFromView = async (viewName) => { let rows = [] let rangeStart = 0 while (true) { const { data, error } = await supabase .from(viewName) - .select(fields) + .select('*') .order('listened_at', { ascending: false }) .range(rangeStart, rangeStart + PAGE_SIZE - 1) @@ -32,36 +32,40 @@ const fetchDataFromView = async (viewName, fields) => { return rows } -const fetchGenreMapping = async () => { - const { data, error } = await supabase - .from('genres') - .select('id, name') - - if (error) { - console.error('Error fetching genres:', error) - return {} - } - return data.reduce((acc, genre) => { - acc[genre['id']] = genre['name'] - return acc - }, {}) -} - -const aggregateData = (data, groupByField, groupByType, genreMapping) => { +const aggregateData = (data, groupByField, groupByType) => { const aggregation = {} + data.forEach(item => { const key = item[groupByField] if (!aggregation[key]) { + let imageField = '' + + switch (groupByType) { + case 'artist': + imageField = item['artist_art'] + break + case 'album': + imageField = item['album_art'] + break + case 'track': + imageField = item['album_art'] + break + default: + imageField = '' + } + aggregation[key] = { title: item[groupByField], plays: 0, url: item['artist_url'], - image: `/${item[groupByType]}`, - type: groupByType === 'artist_art' ? 'artist' : groupByType === 'album_art' ? 'album' : groupByType, - genre: genreMapping[item['artist_genres']] || '' + image: imageField, + genre: item['artist_genres'], + type: groupByType } - if (groupByType === 'track' || groupByType === 'album_art') aggregation[key]['artist'] = item['artist_name'] + + if (groupByType === 'track' || groupByType === 'album') aggregation[key]['artist'] = item['artist_name'] } + aggregation[key].plays++ }) @@ -74,66 +78,62 @@ const buildRecents = (data) => { artist: listen['artist_name'], url: listen['artist_url'], timestamp: listen['listened_at'], - image: `/${listen['album_art']}` - })).sort((a, b) => b.timestamp - a.timestamp) + image: listen['album_art'], + type: 'track' + })).sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp)) } -const aggregateGenres = (data, genreMapping) => { +const aggregateGenres = (data) => { const genreAggregation = {} data.forEach(item => { - const genre = genreMapping[item['artist_genres']] || '' - if (!genreAggregation[genre]) genreAggregation[genre] = { name: genre, url: item['genre_url'], plays: 0 } + const genre = item['genre_name'] || '' + const genreUrl = item['genre_url'] || '' + + if (!genreAggregation[genre]) { + genreAggregation[genre] = { + name: genre, + url: genreUrl, + plays: 0, + type: 'genre' + } + } + genreAggregation[genre]['plays']++ }) + return Object.values(genreAggregation).sort((a, b) => b['plays'] - a['plays']) } export default async function () { - const selectFields = ` - listened_at, - track_name, - artist_name, - album_name, - album_key, - artist_art, - artist_genres, - artist_country, - album_art, - artist_url, - genre_url - ` - try { - const genreMapping = await fetchGenreMapping() - const [recentTracks, monthTracks, threeMonthTracks] = await Promise.all([ - fetchDataFromView('recent_tracks', selectFields), - fetchDataFromView('month_tracks', selectFields), - fetchDataFromView('three_month_tracks', selectFields) + fetchDataFromView('recent_tracks'), + fetchDataFromView('month_tracks'), + fetchDataFromView('three_month_tracks') ]) return { recent: buildRecents(recentTracks), week: { - artists: aggregateData(recentTracks, 'artist_name', 'artist_art', genreMapping), - albums: aggregateData(recentTracks, 'album_name', 'album_art', genreMapping), - tracks: aggregateData(recentTracks, 'track_name', 'track', genreMapping), - genres: aggregateGenres(recentTracks, genreMapping), + artists: aggregateData(recentTracks, 'artist_name', 'artist'), + albums: aggregateData(recentTracks, 'album_name', 'album'), + tracks: aggregateData(recentTracks, 'track_name', 'track'), + genres: aggregateGenres(recentTracks), totalTracks: recentTracks.length.toLocaleString('en-US') }, month: { - artists: aggregateData(monthTracks, 'artist_name', 'artist_art', genreMapping), - albums: aggregateData(monthTracks, 'album_name', 'album_art', genreMapping), - tracks: aggregateData(monthTracks, 'track_name', 'track', genreMapping), - genres: aggregateGenres(monthTracks, genreMapping), + artists: aggregateData(monthTracks, 'artist_name', 'artist'), + albums: aggregateData(monthTracks, 'album_name', 'album'), + tracks: aggregateData(monthTracks, 'track_name', 'track'), + genres: aggregateGenres(monthTracks), totalTracks: monthTracks.length.toLocaleString('en-US') }, threeMonth: { - artists: aggregateData(threeMonthTracks, 'artist_name', 'artist_art', genreMapping), - albums: aggregateData(threeMonthTracks, 'album_name', 'album_art', genreMapping), - tracks: aggregateData(threeMonthTracks, 'track_name', 'track', genreMapping), - genres: aggregateGenres(threeMonthTracks, genreMapping), + artists: aggregateData(threeMonthTracks, 'artist_name', 'artist'), + albums: aggregateData(threeMonthTracks, 'album_name', 'album'), + tracks: aggregateData(threeMonthTracks, 'track_name', 'track'), + genres: aggregateGenres(threeMonthTracks), totalTracks: threeMonthTracks.length.toLocaleString('en-US') } } diff --git a/src/data/pages.js b/src/data/pages.js index 8715a521..6fb3e1d4 100644 --- a/src/data/pages.js +++ b/src/data/pages.js @@ -3,43 +3,8 @@ import { createClient } from '@supabase/supabase-js' const SUPABASE_URL = process.env['SUPABASE_URL'] const SUPABASE_KEY = process.env['SUPABASE_KEY'] const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) - const PAGE_SIZE = 250 -const fetchBlockData = async (collection, itemId) => { - const { data, error } = await supabase - .from(collection) - .select(collection === 'hero' ? '*, image(filename_disk)' : '*') - .eq('id', itemId) - .single() - - if (error) { - console.error(`Error fetching data from ${collection} for item ${itemId}:`, error) - return null - } - - return data -} - -const fetchAllBlocks = async () => { - const { data, error } = await supabase - .from('pages_blocks') - .select('pages_id, collection, item, sort') - - if (error) { - console.error('Error fetching all blocks from Supabase:', error) - return {} - } - - return data.reduce((acc, block) => { - if (!acc[block['pages_id']]) { - acc[block['pages_id']] = [] - } - acc[block['pages_id']].push(block) - return acc - }, {}) -} - const fetchAllPages = async () => { let pages = [] let page = 0 @@ -65,40 +30,9 @@ const fetchAllPages = async () => { return pages } -const processPages = async (pages, blocksByPageId) => { - return Promise.all(pages.map(async page => { - const blocks = blocksByPageId[page['id']] || [] - - page['blocks'] = await Promise.all(blocks.map(async block => { - const blockData = await fetchBlockData(block['collection'], block['item']) - - if (!blockData) return { - 'type': block['collection'], - 'sort': block['sort'] - } - - return { - 'type': block['collection'], - 'sort': block['sort'], - ...blockData - } - })).then(blocks => blocks.filter(block => block !== null)) - - page['blocks'].sort((a, b) => a['sort'] - b['sort']) - - if (page['open_graph_image']) page['open_graph_image'] = page['open_graph_image']['filename_disk'] - - return page - })) -} - export default async function () { try { - const [pages, blocksByPageId] = await Promise.all([ - fetchAllPages(), - fetchAllBlocks() - ]) - return await processPages(pages, blocksByPageId) + return await fetchAllPages() } catch (error) { console.error('Error fetching and processing pages:', error) return [] diff --git a/src/data/posts.js b/src/data/posts.js index 9871bd63..0574dd74 100644 --- a/src/data/posts.js +++ b/src/data/posts.js @@ -9,7 +9,6 @@ const fetchAllPosts = async () => { let posts = [] let page = 0 let fetchMore = true - const uniquePosts = new Set() while (fetchMore) { const { data, error } = await supabase @@ -25,44 +24,18 @@ const fetchAllPosts = async () => { if (data.length < PAGE_SIZE) fetchMore = false - for (const post of data) { - if (uniquePosts.has(post['url'])) continue - - uniquePosts.add(post['url']) - posts.push(post) - } - + posts = posts.concat(data) page++ } return posts } -const processPosts = async (posts) => { - return Promise.all(posts.map(async post => { - post['artists'] = post['artists'] ? post['artists'].sort((a, b) => a['name'].localeCompare(b['name'])) : null - post['books'] = post['books'] ? post['books'].map(book => ({ - title: book['title'], - author: book['author'], - description: book['description'], - url: `/books/${book['isbn']}`, - })).sort((a, b) => a['title'].localeCompare(b['title'])) : null - post['movies'] = post['movies'] ? post['movies'].map(movie => { - movie['url'] = `/watching/movies/${movie['tmdb_id']}` - return movie - }).sort((a, b) => b['year'] - a['year']) : null - post['genres'] = post['genres'] ? post['genres'].sort((a, b) => a['name'].localeCompare(b['name'])) : null - post['shows'] = post['shows'] ? post['shows'].map(show => { - show['url'] = `/watching/shows/${show['tmdb_id']}` - return show - }).sort((a, b) => b['year'] - a['year']) : null - if (post['image']) post['image'] = post['image']['filename_disk'] - - return post - })) -} - export default async function () { - const posts = await fetchAllPosts() - return await processPosts(posts) + try { + return await fetchAllPosts() + } catch (error) { + console.error('Error fetching and processing posts:', error) + return [] + } } \ No newline at end of file diff --git a/src/data/tv.js b/src/data/tv.js index 7957611d..4cf0135c 100644 --- a/src/data/tv.js +++ b/src/data/tv.js @@ -12,26 +12,7 @@ const fetchAllShows = async () => { while (true) { const { data, error } = await supabase .from('optimized_shows') - .select(` - id, - tmdb_id, - title, - year, - collected, - favorite, - tattoo, - description, - review, - art, - backdrop, - tags, - episodes, - artists, - books, - movies, - posts, - related_shows - `) + .select('*') .range(rangeStart, rangeStart + PAGE_SIZE - 1) if (error) { @@ -47,136 +28,31 @@ const fetchAllShows = async () => { return shows } -const prepareShowData = (show) => ({ - ...show, - image: show['art'] ? `/${show['art']}` : '', - backdrop: show['backdrop'] ? `/${show['backdrop']}` : '', - url: `/watching/shows/${show['tmdb_id']}`, - episodes: show['episodes'] || [], - tattoo: show['tattoo'], - tags: Array.isArray(show['tags']) ? show['tags'] : show['tags']?.split(',') || [], - movies: show['movies'] ? show['movies'].map(movie => { - movie['url'] = `/watching/movies/${movie['tmdb_id']}` - return movie - }).sort((a, b) => b['year'] - a['year']) : null, - books: show['books'] ? show['books'].map(book => ({ - title: book['title'], - author: book['author'], - description: book['description'], - url: `/books/${book['isbn']}`, - })).sort((a, b) => a['title'].localeCompare(b['title'])) : null, - posts: show['posts'] ? show['posts'].map(post => ({ - title: post['title'], - date: post['date'], - url: post['url'], - })).sort((a, b) => new Date(b['date']) - new Date(a['date'])) : null, - relatedShows: show['related_shows'] ? show['related_shows'].map(relatedShow => ({ - title: relatedShow['title'], - year: relatedShow['year'], - url: `/watching/shows/${relatedShow['tmdb_id']}`, - })).sort((a, b) => b['year'] - a['year']) : null, - artists: show['artists'] ? show['artists'].sort((a, b) => a['name'].localeCompare(b['name'])) : null -}) - -const prepareEpisodeData = (show) => show['episodes'].map(episode => ({ - ...episode, - show_title: show['title'], - show_tmdb_id: show['tmdb_id'], - show_year: show['year'], - collected: show['collected'], - favorite: show['favorite'], - image: show['image'], - backdrop: show['backdrop'], - episode_number: episode['episode_number'], - season_number: episode['season_number'], - last_watched_at: episode['last_watched_at'] -})) - -const formatEpisodeData = (episodes) => { - const showEpisodesMap = {} - - episodes.forEach(episode => { - const showTmdbId = episode['show_tmdb_id'] - const showYear = episode['show_year'] - - if (!showEpisodesMap[showTmdbId]) { - showEpisodesMap[showTmdbId] = { - title: episode['show_title'], - tmdbId: showTmdbId, - year: showYear, - collected: episode['collected'], - favorite: episode['favorite'], - dateAdded: episode['last_watched_at'], - lastWatchedAt: episode['last_watched_at'], - episodes: [], - image: episode['image'], - backdrop: episode['backdrop'], - } - } - - showEpisodesMap[showTmdbId].episodes.push({ - name: episode['show_title'], - url: `/watching/shows/${showTmdbId}`, - subtext: `S${episode['season_number']}E${episode['episode_number']}`, - episode: episode['episode_number'], - season: episode['season_number'], - tmdbId: showTmdbId, - year: showYear, - type: 'tv', - dateAdded: episode['last_watched_at'], - lastWatchedAt: episode['last_watched_at'], - image: episode['image'], - backdrop: episode['backdrop'], - }) - }) - - return Object.values(showEpisodesMap).sort((a, b) => new Date(b['episodes'][0]['lastWatchedAt']) - new Date(a['episodes'][0]['lastWatchedAt'])).flatMap(show => { - const startingEpisode = show['episodes'][show['episodes'].length - 1]['episode'] - const startingSeason = show['episodes'][show['episodes'].length - 1]['season'] - const endingEpisode = show['episodes'][0]['episode'] - const endingSeason = show['episodes'][0]['season'] - - if (show.episodes.length > 1) { - return { - name: show['title'], - url: `/watching/shows/${show['tmdbId']}`, - subtext: `S${startingSeason}E${startingEpisode} - S${endingSeason}E${endingEpisode}`, - startingEpisode, - startingSeason, - episode: endingEpisode, - season: endingSeason, - tmdbId: show['tmdbId'], - year: show['year'], - collected: show['collected'], - favorite: show['favorite'], - type: 'tv-range', - image: show['image'], - backdrop: show['backdrop'], - } - } else { - return show['episodes'][0] - } - }) -} - export default async function () { try { - const rawShows = await fetchAllShows() - const shows = rawShows.map(prepareShowData) - const episodes = shows.flatMap(prepareEpisodeData).sort((a, b) => new Date(b['last_watched_at']) - new Date(a['last_watched_at'])) - const favoriteShows = shows.filter(show => show.favorite) + const shows = await fetchAllShows() + const watchedShows = shows.filter(show => show['last_watched_at'] !== null) + const episodes = watchedShows.map(show => ({ + title: show['episode']['title'], + year: show['year'], + formatted_episode: show['episode']['formatted_episode'], + url: show['episode']['url'], + image: show['episode']['image'], + backdrop: show['episode']['backdrop'], + last_watched_at: show['episode']['last_watched_at'], + type: 'tv' + })) return { shows, - watchHistory: formatEpisodeData(episodes), - recentlyWatched: formatEpisodeData(episodes.slice(0, 225)), - favorites: formatEpisodeData(favoriteShows.flatMap(prepareEpisodeData)).sort((a, b) => a['name'].localeCompare(b['name'])), + recentlyWatched: episodes.slice(0, 225), + favorites: shows.filter(show => show.favorite).sort((a, b) => a.title.localeCompare(b.title)), } } catch (error) { console.error('Error fetching and processing shows data:', error) + return { shows: [], - watchHistory: [], recentlyWatched: [], favorites: [], } diff --git a/src/includes/base.liquid b/src/includes/base.liquid index 9afd77fc..f748fb7b 100644 --- a/src/includes/base.liquid +++ b/src/includes/base.liquid @@ -47,7 +47,7 @@ {%- assign pageDescription = description -%} {%- endif -%} -{%- assign ogImage = 'https://cdn.coryd.dev/' | append: globals.opengraph_default -%} +{%- assign ogImage = 'https://cdn.coryd.dev/' | append: globals.avatar | append: "?class=w800" -%} {%- case schema -%} {%- when 'music' -%} {%- assign ogImage = 'https://cdn.coryd.dev' | append: page.image -%} @@ -61,11 +61,20 @@ {%- when 'watching' -%} {%- assign featuredMovie = movies.recentlyWatched | first -%} {%- assign ogImage = 'https://cdn.coryd.dev' | append: featuredMovie.backdrop -%} + {%- when 'watching-shows' -%} + {%- assign featuredShow = tv.recentlyWatched | first -%} + {%- assign ogImage = 'https://cdn.coryd.dev' | append: featuredShow.backdrop -%} + {%- when 'favorite-movies' -%} + {%- assign featuredMovie = movies.favorites| shuffleArray | first -%} + {%- assign ogImage = 'https://cdn.coryd.dev' | append: featuredMovie.backdrop -%} + {%- when 'favorite-shows' -%} + {%- assign featuredShow = tv.favorites | shuffleArray | first -%} + {%- assign ogImage = 'https://cdn.coryd.dev' | append: featuredShow.backdrop -%} {%- when 'books' -%} {%- assign featuredBook = books.all | bookStatus: 'started' | reverse | first -%} {%- assign ogImage = 'https://cdn.coryd.dev' | append: featuredBook.image -%} {%- when 'books-year' -%} - {%- assign featuredBook = books.all | bookStatus: 'finished' | bookFinishedYear: year.value | bookSortDescending | first -%} + {%- assign featuredBook = books.all | bookStatus: 'finished' | bookFinishedYear: year.value | first -%} {%- assign ogImage = 'https://cdn.coryd.dev' | append: featuredBook.image -%} {%- when 'book' -%} {%- assign ogImage = 'https://cdn.coryd.dev' | append: book.image -%} @@ -95,12 +104,12 @@ - + - - - + + + diff --git a/src/includes/partials/blocks/hero.liquid b/src/includes/partials/blocks/hero.liquid index fe6bf52c..86953d47 100644 --- a/src/includes/partials/blocks/hero.liquid +++ b/src/includes/partials/blocks/hero.liquid @@ -1,13 +1,13 @@ {{ alt }} <![CDATA[{{ title }}]]> {{ permalink | absoluteUrl }} - {{ "https://cdn.coryd.dev/" | append: globals.feed_image | append: "?class=w200" }} + {{ "https://cdn.coryd.dev" | append: globals.avatar | append: "?class=w200" }} 144 144 diff --git a/src/includes/partials/home/recent-activity.liquid b/src/includes/partials/home/recent-activity.liquid index 078dd82e..cb16c826 100644 --- a/src/includes/partials/home/recent-activity.liquid +++ b/src/includes/partials/home/recent-activity.liquid @@ -1,7 +1,8 @@ +{%- assign currentYear = 'now' | date: "%Y" -%} {%- assign track = music.week.tracks | first -%} {%- assign show = tv.recentlyWatched | first -%} {%- assign movie = movies.recentlyWatched | first -%} -{%- assign book = books | bookStatus: 'finished' | bookSortDescending | first -%} +{%- assign book = books | bookFinishedYear: currentYear | first -%} {%- assign link = links | first -%}

      @@ -10,10 +11,10 @@

      {% render "partials/blocks/banners/rss.liquid", url: "/feeds", text: "Subscribe to my movies, books, links or activity feed(s)" %}
      \ No newline at end of file diff --git a/src/includes/partials/media/watching/grid.liquid b/src/includes/partials/media/watching/grid.liquid index 162ad26a..f58903f5 100644 --- a/src/includes/partials/media/watching/grid.liquid +++ b/src/includes/partials/media/watching/grid.liquid @@ -15,7 +15,7 @@ ({{ item.year }}) {%- else -%} -
      {{ item.name }}
      +
      {{ item.title }}
      ({{ item.year }})
      {%- endif -%} diff --git a/src/pages/dynamic/books/index.html b/src/pages/dynamic/books/index.html index 14b2ba7e..04440a62 100644 --- a/src/pages/dynamic/books/index.html +++ b/src/pages/dynamic/books/index.html @@ -6,8 +6,9 @@ permalink: "/books/index.html" updated: "now" schema: books --- +{%- assign currentYear = 'now' | date: "%Y" -%} {%- assign bookData = books.all | bookStatus: 'started' | reverse -%} -{%- assign currentBookCount = books.all | currentBookCount -%} +{%- assign currentBookCount = books.all | bookFinishedYear: currentYear | size -%}

      Currently reading

      Here's what I'm reading at the moment. I've finished {{ currentBookCount }} books this year.

      {{ books.years | bookYearLinks }}

      diff --git a/src/pages/dynamic/books/year.html b/src/pages/dynamic/books/year.html index eedfb09f..faaaa63c 100644 --- a/src/pages/dynamic/books/year.html +++ b/src/pages/dynamic/books/year.html @@ -7,7 +7,7 @@ pagination: permalink: "/books/years/{{ year.value }}.html" schema: books-year --- -{%- assign bookData = year.data | bookStatus: 'finished' | bookSortDescending -%} +{%- assign bookData = year.data | bookStatus: 'finished' -%} {%- assign bookDataFavorites = bookData | bookFavorites -%} {%- capture favoriteBooks -%}{{ bookDataFavorites | shuffleArray | mediaLinks: "book", 5 }}{%- endcapture -%} {%- capture currentYear -%}{% currentYear %}{%- endcapture -%} diff --git a/src/pages/dynamic/links.html b/src/pages/dynamic/links.html index 4487e602..1622b0a6 100644 --- a/src/pages/dynamic/links.html +++ b/src/pages/dynamic/links.html @@ -19,7 +19,7 @@ permalink: "/links/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }} {{ link.title }} - {% if link.authors %} via {{ link.authors.name }}{% endif %} + {% if link.author %} via {{ link.author.name }}{% endif %} {% endfor %} diff --git a/src/pages/dynamic/music/index.html b/src/pages/dynamic/music/index.html index 40f9b098..226ae244 100644 --- a/src/pages/dynamic/music/index.html +++ b/src/pages/dynamic/music/index.html @@ -34,13 +34,13 @@ schema: music-index
      - + - +
      {% render "partials/media/music/recent", data:music.recent %}
      -
      +
      {% render "partials/media/music/chart.liquid", data:music.week.tracks, mostPlayed:music.week.tracks[0].plays, count: 10 %}
      diff --git a/src/pages/dynamic/page.html b/src/pages/dynamic/page.html index 75960c76..01fa9591 100644 --- a/src/pages/dynamic/page.html +++ b/src/pages/dynamic/page.html @@ -6,7 +6,7 @@ pagination: alias: page description: "{{ page.description }}" permalink: "{{ page.permalink }}/index.html" -image: "{{ page.open_graph_image | prepend: 'https://cdn.coryd.dev/' | default: globals.meta_data.opengraph_default }}" +image: "{{ page.open_graph_image | prepend: 'https://cdn.coryd.dev' | default: globals.avatar }}" updated: {{ page.updated | default: null }} --- -{% render "partials/blocks/index.liquid", blocks:page.blocks, collections:collections, links:links %} \ No newline at end of file +{% render "partials/blocks/index.liquid", blocks:page.blocks %} \ No newline at end of file diff --git a/src/pages/dynamic/watching/favorites/movies.html b/src/pages/dynamic/watching/favorites/movies.html index 3ede29f2..ab1c3373 100644 --- a/src/pages/dynamic/watching/favorites/movies.html +++ b/src/pages/dynamic/watching/favorites/movies.html @@ -6,7 +6,7 @@ pagination: data: movies.favorites size: 24 permalink: "/watching/favorite-movies/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html" -schema: watching +schema: favorite-movies --- {% tablericon "arrow-left" %} Back to watching {% if pagination.pageNumber == 0 %} diff --git a/src/pages/dynamic/watching/favorites/shows.html b/src/pages/dynamic/watching/favorites/shows.html index 139d4281..e200acda 100644 --- a/src/pages/dynamic/watching/favorites/shows.html +++ b/src/pages/dynamic/watching/favorites/shows.html @@ -6,7 +6,7 @@ pagination: data: tv.favorites size: 24 permalink: "/watching/favorite-shows/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html" -schema: watching +schema: favorite-shows --- {% tablericon "arrow-left" %} Back to watching {% if pagination.pageNumber == 0 %} diff --git a/src/pages/dynamic/watching/index.html b/src/pages/dynamic/watching/index.html index 5641856e..1b37733a 100644 --- a/src/pages/dynamic/watching/index.html +++ b/src/pages/dynamic/watching/index.html @@ -32,7 +32,7 @@ schema: watching Favorite movies -{% assign favoriteMovies = movies.favorites | featuredWatching: 6 %} +{% assign favoriteMovies = movies.favorites | shuffleArray | featuredWatching: 6 %} {% render "partials/media/watching/grid.liquid", mediaItems:favoriteMovies, count: 6 %}

      @@ -40,5 +40,5 @@ schema: watching Favorite shows

      -{% assign favoriteShows = tv.favorites | featuredWatching: 6 %} +{% assign favoriteShows = tv.favorites | shuffleArray | featuredWatching: 6 %} {% render "partials/media/watching/grid.liquid", mediaItems:favoriteShows, count: 6 %} \ No newline at end of file diff --git a/src/pages/dynamic/watching/recent/shows.html b/src/pages/dynamic/watching/recent/shows.html index 427acd30..c90a439e 100644 --- a/src/pages/dynamic/watching/recent/shows.html +++ b/src/pages/dynamic/watching/recent/shows.html @@ -6,7 +6,7 @@ pagination: data: tv.recentlyWatched size: 24 permalink: "/watching/recent/shows/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html" -schema: watching +schema: watching-shows --- {% tablericon "arrow-left" %} Back to watching {% if pagination.pageNumber == 0 %} diff --git a/src/pages/dynamic/watching/show.html b/src/pages/dynamic/watching/show.html index 64f9359b..140d0045 100644 --- a/src/pages/dynamic/watching/show.html +++ b/src/pages/dynamic/watching/show.html @@ -10,7 +10,6 @@ schema: show {%- capture alt -%} {{ show.title }} / {{ show.year }} {%- endcapture -%} -{% assign lastWatched = show | getLastWatched %} {% tablericon "arrow-left" %} Back to watching
      {% tablericon "circle-check" %} This show is in my collection!

      {%- endif -%} - {%- if lastWatched -%} + {%- if show.episode.formatted_episode -%} {%- capture lastWatchedText -%} - {%- if show.episodes -%} - I last watched {{ show.episodes | lastWatchedEpisode }} on {{ lastWatched | date: "%B %e, %Y" }}. - {%- else -%} - Last watched on {{ lastWatched | date: "%B %e, %Y" }}. - {%- endif -%} + I last watched {{ show.episode.formatted_episode }} on {{ show.episode.last_watched_at | date: "%B %e, %Y" }}. {%- endcapture -%}

      {{ lastWatchedText }}

      {%- endif -%} diff --git a/src/pages/feeds/json/album-releases.liquid b/src/pages/feeds/json/album-releases.liquid index c7b566fa..ec953837 100644 --- a/src/pages/feeds/json/album-releases.liquid +++ b/src/pages/feeds/json/album-releases.liquid @@ -9,6 +9,6 @@ permalink: "/feeds/album-releases.json" title:"Album releases / Cory Dransfeldt" globals:globals data:releases - updated:releases[0].release_date + updated:releases[0].releaseDate appVersion:appVersion %} \ No newline at end of file diff --git a/src/pages/feeds/json/books.liquid b/src/pages/feeds/json/books.liquid index e99230c0..d9c8914a 100644 --- a/src/pages/feeds/json/books.liquid +++ b/src/pages/feeds/json/books.liquid @@ -3,7 +3,7 @@ layout: null eleventyExcludeFromCollections: true permalink: "/feeds/books.json" --- -{%- assign bookData = books.all | bookStatus: 'finished' | bookSortDescending -%} +{%- assign bookData = books.all | bookStatus: 'finished' -%} {% render "partials/feeds/json.liquid" permalink:"/feeds/books" title:"Books / Cory Dransfeldt" diff --git a/src/pages/feeds/rss/album-releases.liquid b/src/pages/feeds/rss/album-releases.liquid index a6e8e703..639572ea 100644 --- a/src/pages/feeds/rss/album-releases.liquid +++ b/src/pages/feeds/rss/album-releases.liquid @@ -9,5 +9,5 @@ permalink: "/feeds/album-releases" title:"Album releases / Cory Dransfeldt" globals:globals data:releases - updated:releases[0].release_date + updated:releases[0].releaseDate %} \ No newline at end of file diff --git a/src/pages/feeds/rss/books.liquid b/src/pages/feeds/rss/books.liquid index 2870e31f..094b8364 100644 --- a/src/pages/feeds/rss/books.liquid +++ b/src/pages/feeds/rss/books.liquid @@ -3,7 +3,7 @@ layout: null eleventyExcludeFromCollections: true permalink: "/feeds/books" --- -{%- assign bookData = books.all | bookStatus: 'finished' | bookSortDescending -%} +{%- assign bookData = books.all | bookStatus: 'finished' -%} {% render "partials/feeds/rss.liquid" permalink:"/feeds/books" title:"Books / Cory Dransfeldt"