eleventy-plugin-podcaster 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,5 @@
1
- ---
2
- title: eleventy-plugin-podcaster 🕚⚡️🎈🐀🎤📲
3
- ---
1
+ # eleventy-plugin-podcaster 🕚⚡️🎈🐀🎤📲
2
+
4
3
  `eleventy-plugin-podcaster` — or **Podcaster**, as we will call it from now on — is an Eleventy plugin that helps you create a podcast and a website to accompany it. You provide **Podcaster** with information about your podcast and its episodes, and it creates a feed for you to submit to podcast directories like Apple Podcasts or Spotify. And you can use all the information you have provided to create your site, with pages for individual episodes, guests, topics, seasons or anything else at all.
5
4
 
6
5
  Plenty of services exist to host your podcast online — [Spotify][], [Acast][], [Podbean][], [Buzzsprout][], [Blubrry][]. But none of these will allow you to own and control your podcast's presence on the web, and none of them will give you the freedom to create a site that presents your podcast in a way that reflects its premise, tone and style.
package/TODO.md ADDED
@@ -0,0 +1,24 @@
1
+ # TODO
2
+
3
+ ## Warnings and errors for missing data
4
+
5
+ Add consistent warnings and errors when required data is missing. This should be opt-in via a plugin option to avoid a breaking change.
6
+
7
+ Behaviour:
8
+
9
+ - In development (`ELEVENTY_RUN_MODE === 'serve'`): log warnings but continue the build
10
+ - In production: throw errors and stop the build
11
+
12
+ Cases to handle:
13
+
14
+ - Missing `podcast.json` or required fields within it
15
+ - Episode post without a matching audio file
16
+ - Malformed episode numbering in filenames
17
+ - Incomplete S3 configuration (some keys but not others)
18
+ - Missing audio file when calculating duration/size
19
+
20
+ Implementation notes:
21
+
22
+ - Use a consistent prefix like `[podcaster]` so messages are identifiable
23
+ - New plugin option (e.g., `strictMode` or `validateData`) to enable this
24
+ - The draft system may already cover some cases (e.g., incomplete episodes marked as drafts)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eleventy-plugin-podcaster",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "An Eleventy plugin that allows you to create a podcast and its accompanying website",
5
5
  "main": "eleventy.config.js",
6
6
  "exports": {
@@ -34,7 +34,6 @@
34
34
  "@tsmx/human-readable": "^2.0.3",
35
35
  "dom-serializer": "^2.0.0",
36
36
  "htmlparser2": "^9.1.0",
37
- "luxon": "^3.4.4",
38
37
  "markdown-it": "^14.1.0",
39
38
  "music-metadata": "^11.7.1"
40
39
  },
@@ -1,4 +1,3 @@
1
- import { DateTime } from 'luxon'
2
1
  import readableDuration from './readableDuration.js'
3
2
  import path from 'node:path'
4
3
  import { existsSync, readFileSync } from 'node:fs'
@@ -96,7 +95,7 @@ async function getCachedEpisodeDataFromS3Bucket (s3Storage, s3Bucket) {
96
95
  async function calculateEpisodeDataFromS3Bucket (s3Storage, s3Bucket) {
97
96
  const cachedEpisodeData = await getCachedEpisodeDataFromS3Bucket(s3Storage, s3Bucket)
98
97
  const cachedEpisodeDataLastModifiedDate = (cachedEpisodeData.lastModified)
99
- ? DateTime.fromISO(cachedEpisodeData.lastModified)
98
+ ? new Date(cachedEpisodeData.lastModified)
100
99
  : null
101
100
 
102
101
  console.log(`Reading episode data from S3 bucket ${s3Bucket}`)
@@ -111,7 +110,7 @@ async function calculateEpisodeDataFromS3Bucket (s3Storage, s3Bucket) {
111
110
  !('size' in result[filename]) ||
112
111
  !('duration' in result[filename]) ||
113
112
  !cachedEpisodeDataLastModifiedDate ||
114
- cachedEpisodeDataLastModifiedDate < DateTime.fromISO(lastModified)) {
113
+ cachedEpisodeDataLastModifiedDate < new Date(lastModified)) {
115
114
  const { buffer } = await getObjectFromS3Bucket(s3Storage, s3Bucket, filename)
116
115
  const metadata = await parseBufferMetadata(buffer, null, { duration: true })
117
116
  const duration = metadata.format.duration
@@ -1,5 +1,3 @@
1
- import { DateTime } from 'luxon'
2
-
3
1
  export default function (eleventyConfig) {
4
2
  eleventyConfig.addGlobalData('eleventyComputed.podcast.feedPath', () => {
5
3
  return data => data.podcast.feedPath || '/feed/podcast.xml'
@@ -23,7 +21,7 @@ export default function (eleventyConfig) {
23
21
  })
24
22
 
25
23
  function constructCopyrightNotice (data) {
26
- const thisYear = DateTime.now().year
24
+ const thisYear = new Date().getFullYear()
27
25
  let yearRange
28
26
  if (!data.podcast.startingYear || data.podcast.startingYear === thisYear) {
29
27
  yearRange = thisYear
@@ -40,5 +38,5 @@ export default function (eleventyConfig) {
40
38
  eleventyConfig.addGlobalData('eleventyComputed.copyrightNotice', () => {
41
39
  return constructCopyrightNotice
42
40
  })
43
- eleventyConfig.addGlobalData('podcast.feedLastBuildDate', DateTime.now().toRFC2822())
41
+ eleventyConfig.addGlobalData('podcast.feedLastBuildDate', new Date().toUTCString().replace('GMT', '+0000'))
44
42
  }
@@ -1,10 +1,29 @@
1
- import { Duration } from 'luxon'
1
+ function pluralise (value, unit) {
2
+ return `${value} ${unit}${value === 1 ? '' : 's'}`
3
+ }
4
+
5
+ function toComponents (seconds) {
6
+ return {
7
+ d: Math.floor(seconds / 86400),
8
+ h: Math.floor((seconds % 86400) / 3600),
9
+ m: Math.floor((seconds % 3600) / 60),
10
+ s: Math.round((seconds % 60) * 1000) / 1000
11
+ }
12
+ }
2
13
 
3
14
  export default {
4
- convertFromSeconds (seconds) {
5
- return Duration.fromMillis(seconds * 1000)
6
- .shiftTo('days', 'hours', 'minutes', 'seconds')
7
- .toHuman()
15
+ longFormat (seconds) {
16
+ const { d, h, m, s } = toComponents(seconds)
17
+ return [pluralise(d, 'day'), pluralise(h, 'hour'), pluralise(m, 'minute'), pluralise(s, 'second')].join(', ')
18
+ },
19
+ shortFormat (seconds) {
20
+ const h = Math.floor(seconds / 3600)
21
+ const m = Math.floor((seconds % 3600) / 60)
22
+ const s = Math.floor(seconds % 60)
23
+ if (h === 0) {
24
+ return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
25
+ }
26
+ return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
8
27
  },
9
28
  convertToSeconds (duration) {
10
29
  const durationPattern = /^(?:(?<hours>\d+):)?(?<minutes>\d{1,2}):(?<seconds>\d{2}(?:\.\d+)?)$/
@@ -1,29 +1,24 @@
1
- import { DateTime, Duration } from 'luxon'
2
1
  import hr from '@tsmx/human-readable'
2
+ import readableDuration from './readableDuration.js'
3
3
 
4
4
  export default function (eleventyConfig, options = {}) {
5
5
  eleventyConfig.addFilter('readableDate', function (date) {
6
6
  const readableDateLocale = options.readableDateLocale ?? 'en-AU'
7
- if (date instanceof Date) {
8
- date = date.toISOString()
9
- }
10
- const result = DateTime.fromISO(date, {
11
- zone: 'UTC'
7
+ return new Date(date).toLocaleDateString(readableDateLocale, {
8
+ weekday: 'long',
9
+ year: 'numeric',
10
+ month: 'long',
11
+ day: 'numeric',
12
+ timeZone: 'UTC'
12
13
  })
13
- return result.setLocale(readableDateLocale).toLocaleString(DateTime.DATE_HUGE)
14
14
  })
15
15
 
16
16
  eleventyConfig.addFilter('readableDuration', (seconds, length) => {
17
17
  if (!seconds) return '0:00'
18
18
  if (length === 'long') {
19
- return Duration.fromMillis(seconds * 1000)
20
- .shiftTo('days', 'hours', 'minutes', 'seconds')
21
- .toHuman()
22
- } else if (seconds < 60 * 60) {
23
- return Duration.fromMillis(seconds * 1000).toFormat('mm:ss')
24
- } else {
25
- return Duration.fromMillis(seconds * 1000).toFormat('h:mm:ss')
19
+ return readableDuration.longFormat(seconds)
26
20
  }
21
+ return readableDuration.shortFormat(seconds)
27
22
  })
28
23
 
29
24
  eleventyConfig.addFilter('readableSize', (bytes, fixedPrecision = 1) =>