diff --git a/config/collections/index.js b/config/collections/index.js
index 06d673fe..3781a944 100644
--- a/config/collections/index.js
+++ b/config/collections/index.js
@@ -87,6 +87,8 @@ export const processContent = (collection) => {
items.forEach((item) => {
let attribution
let hashTags = tagsToHashtags(item) ? ' ' + tagsToHashtags(item) : ''
+ if (item['type'] === 'album-release') hashTags = ' #Music #NewMusic'
+ if (item['type'] === 'concert') hashTags = ' #Music #Concert'
// link attribution if properties exist
if (item?.['authors']?.['mastodon']) {
@@ -108,6 +110,8 @@ export const processContent = (collection) => {
// set url for posts - identified as slugs here
if (item?.['slug']) content['url'] = new URL(item['slug'], BASE_URL).toString()
+ // set unique concert urls
+ if (item?.['type'] === 'concert') content['url'] = `${item['artistUrl']}?t=${DateTime.fromISO(item['date']).toMillis()}#concerts`
if (item?.['description']) {
content['description'] = `${item['description'].split(' ').length >= 25 ? item['description'].split(' ').slice(0, 25).join(' ') + '...' : item['description']}`
} else if (item?.['notes']) {
@@ -135,6 +139,8 @@ export const processContent = (collection) => {
addContent(links, '🔗', (item) => item['title'], (item) => item['date'])
addContent(books.all.filter((book) => book['status'] === 'finished'), '📖', (item) => `${item['title']}${item['rating'] ? ' (' + item['rating'] + ')' : ''}`, (item) => item['date'])
addContent(movies['movies'], '🎥', (item) => `${item['title']}${item['rating'] ? ' (' + item['rating'] + ')' : ''}`, (item) => item['lastWatched'])
+ 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)
@@ -173,10 +179,10 @@ export const albumReleasesCalendar = (collection) => {
start: [date.year, date.month, date.day],
startInputType: 'local',
startOutputType: 'local',
- title: `Release: ${album.artist} - ${album.title}`,
- description: `Check out this new album release: ${album.url}`,
+ 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}-${album.title}@coryd.dev`,
+ 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 e2b15c66..d6ecb807 100644
--- a/config/filters/feeds.js
+++ b/config/filters/feeds.js
@@ -3,6 +3,7 @@ import markdownIt from 'markdown-it'
import markdownItAnchor from 'markdown-it-anchor'
import markdownItFootnote from 'markdown-it-footnote'
import sanitizeHtml from 'sanitize-html'
+import truncate from 'truncate-html'
const BASE_URL = 'https://coryd.dev'
@@ -63,6 +64,16 @@ export default {
} else if (['book', 'movie'].includes(type)) {
processedEntry['excerpt'] = sanitizeHtml(`${md.render(description)}`)
}
+ 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 ${entry['artist']['name']}`
+ processedEntry['excerpt'] = truncatedDescription
+ }
if (slug && content) processedEntry['excerpt'] = sanitizeHtml(`${md.render(content)}${feedNote}`, {
disallowedTagsMode: 'completelyDiscard'
})
@@ -71,6 +82,8 @@ export default {
if (rating) processedEntry['rating'] = rating
if (tags) processedEntry['tags'] = tags
+ if (type === 'album-release' && artist) processedEntry['title'] = `${title} by ${artist}`
+
if (entry) posts.push(processedEntry)
})
diff --git a/config/filters/media.js b/config/filters/media.js
index 7c603e62..c86981fc 100644
--- a/config/filters/media.js
+++ b/config/filters/media.js
@@ -28,8 +28,8 @@ export default {
break
case 'album-release':
normalized.title = item['title']
- normalized.alt = `${item['title']} by ${item['artist']}`
- normalized.subtext = `${item['artist']} / ${item['date']}`
+ normalized.alt = `${item['title']} by ${item['artist']['name']}`
+ normalized.subtext = `${item['artist']['name']} / ${item['date']}`
break
case 'movie':
normalized.title = item['title']
diff --git a/package-lock.json b/package-lock.json
index 85755699..571c727c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "coryd.dev",
- "version": "24.11.0",
+ "version": "24.13.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "coryd.dev",
- "version": "24.11.0",
+ "version": "24.13.0",
"license": "MIT",
"dependencies": {
"@cdransf/api-text": "^1.5.0",
@@ -23,6 +23,7 @@
"autoprefixer": "^10.4.20",
"cssnano": "^7.0.6",
"dotenv-flow": "^4.1.0",
+ "fast-xml-parser": "^4.5.0",
"html-entities": "^2.5.2",
"html-minifier-terser": "^7.2.0",
"ics": "^3.7.6",
@@ -38,7 +39,8 @@
"rimraf": "^6.0.1",
"sanitize-html": "^2.13.0",
"slugify": "^1.6.6",
- "terser": "^5.32.0"
+ "terser": "^5.32.0",
+ "truncate-html": "^1.1.2"
}
},
"node_modules/@11ty/dependency-tree": {
@@ -1093,6 +1095,158 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "htmlparser2": "^8.0.1",
+ "parse5": "^7.0.0",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/htmlparser2": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "entities": "^4.4.0"
+ }
+ },
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -1939,6 +2093,29 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-xml-parser": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
+ "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/naturalintelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "strnum": "^1.0.5"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
"node_modules/fastq": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
@@ -3152,6 +3329,49 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^4.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+ "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "^5.0.2",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -4631,6 +4851,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/strnum": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
+ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/stylehacks": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.4.tgz",
@@ -4774,6 +5001,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/truncate-html": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/truncate-html/-/truncate-html-1.1.2.tgz",
+ "integrity": "sha512-BiLzO594/Quf0wu3jHnVxHA4X5tl4Gunhqe2mlGTa5ElwHJGw7M/N5JdBvU8OPtR+MaEIvmyUdNxnoEi3YI5Yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio": "1.0.0-rc.12"
+ }
+ },
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
diff --git a/package.json b/package.json
index fd11a0d6..98e71cc9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "coryd.dev",
- "version": "24.11.0",
+ "version": "24.13.0",
"description": "The source for my personal site. Built using 11ty (and other tools).",
"type": "module",
"scripts": {
@@ -10,11 +10,8 @@
"update:deps": "npm upgrade && ncu",
"debug": "DEBUG=Eleventy* npx @11ty/eleventy --serve",
"clean": "rimraf _site",
- "publish:analytics": "node scripts/worker-build.mjs analytics && wrangler deploy --env production --config workers/analytics/wrangler.toml",
- "publish:contact": "node scripts/worker-build.mjs contact && wrangler deploy --env production --config workers/contact/wrangler.toml",
- "publish:playing": "node scripts/worker-build.mjs playing && wrangler deploy --env production --config workers/playing/wrangler.toml",
- "publish:rebuild": "node scripts/worker-build.mjs rebuild && wrangler deploy --env production --config workers/rebuild/wrangler.toml",
- "publish:scrobble": "node scripts/worker-build.mjs scrobble && wrangler deploy --env production --config workers/scrobble/wrangler.toml"
+ "build:worker": "node scripts/worker-build.mjs $WORKER_NAME",
+ "deploy:worker": "wrangler deploy --env production --config workers/$npm_config_worker/wrangler.toml"
},
"keywords": [
"11ty",
@@ -39,6 +36,7 @@
"autoprefixer": "^10.4.20",
"cssnano": "^7.0.6",
"dotenv-flow": "^4.1.0",
+ "fast-xml-parser": "^4.5.0",
"html-entities": "^2.5.2",
"html-minifier-terser": "^7.2.0",
"ics": "^3.7.6",
@@ -54,6 +52,7 @@
"rimraf": "^6.0.1",
"sanitize-html": "^2.13.0",
"slugify": "^1.6.6",
- "terser": "^5.32.0"
+ "terser": "^5.32.0",
+ "truncate-html": "^1.1.2"
}
}
diff --git a/scripts/worker-build.mjs b/scripts/worker-build.mjs
index 092b58fe..bc21a566 100644
--- a/scripts/worker-build.mjs
+++ b/scripts/worker-build.mjs
@@ -1,22 +1,28 @@
-import fs from 'fs/promises';
-import dotenv from 'dotenv-flow';
+import fs from 'fs/promises'
+import dotenv from 'dotenv-flow'
-dotenv.config();
+dotenv.config()
-const workerName = process.argv[2];
+const workerName = process.argv[2]
if (!workerName) {
- console.error('Please specify a worker name.');
- process.exit(1);
+ console.error('Please specify a worker name.')
+ process.exit(1)
}
-const templatePath = `workers/${workerName}/wrangler.template.toml`;
-const outputPath = `workers/${workerName}/wrangler.toml`;
-const template = await fs.readFile(templatePath, 'utf8');
-const output = template
- .replace(/\${CF_ACCOUNT_ID}/g, process.env.CF_ACCOUNT_ID)
- .replace(/\${CF_ZONE_ID}/g, process.env.CF_ZONE_ID);
+const templatePath = `workers/${workerName}/wrangler.template.toml`
+const outputPath = `workers/${workerName}/wrangler.toml`
-await fs.writeFile(outputPath, output);
+try {
+ const template = await fs.readFile(templatePath, 'utf8')
+ const output = template
+ .replace(/\${CF_ACCOUNT_ID}/g, process.env.CF_ACCOUNT_ID)
+ .replace(/\${CF_ZONE_ID}/g, process.env.CF_ZONE_ID)
-console.log(`Generated wrangler.toml for ${workerName}`);
\ No newline at end of file
+ await fs.writeFile(outputPath, output)
+
+ console.log(`Generated wrangler.toml for ${workerName}`)
+} catch (error) {
+ console.error('Error generating wrangler.toml:', error)
+ process.exit(1)
+}
\ No newline at end of file
diff --git a/src/assets/styles/feed.xsl b/src/assets/styles/feed.xsl
index 4899495c..52e33a05 100644
--- a/src/assets/styles/feed.xsl
+++ b/src/assets/styles/feed.xsl
@@ -45,11 +45,11 @@
-
+