aboutsummaryrefslogtreecommitdiff
path: root/doc/todo/fancypodcast.mdwn
blob: ccf08eeaf904fddf8518d481412b7ddeb2ff1760 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
ikiwiki's simple podcasting, while elegant and minimal, doesn't (as
mentioned in [[todo/blogging]]) produce full-featured feeds. In
fancy podcasts, episodes are accompanied by text content. The feeds
also have lots more metadata.

[[!toc]]

## Status

[[!template id=gitbranch branch=schmonz/fancypodcast author="[[schmonz]]"]]
[[!tag patch]]

In summary, the branch preserves ikiwiki's existing podcast behavior,
adds more featureful behavior, and has been tested to work well in
some common podcatchers. I believe it is ready for review and
possible integration, and I'd like to get feedback to that effect
(or to the contrary) before making further enhancements. I know
[[joey]]'s the final arbiter here, but I'd appreciate any qualified,
critical eyes ([[smcv]]?) raking over my diffs. --[[schmonz]]

## Features

[[!table data="""
Feature            |iTunes RSS|iTunes Atom|Downcast RSS|Downcast Atom
Feed image         |{X}       |{X}        |{X}         |{X}
Feed title         |(./)      |(./)       |(./)        |(./)
Feed publisher     |{X}       |{X}        |{X}         |{X}
Feed "category"    |{X}       |{X}        |{X}         |{X}
Feed date          |(./)      |(./)       |(./)        |(./)
Feed description   |(./)      |(./)       |(./)        |{X}
Episode image      |{X}       |{X}        |{X}         |{X}
Episode title      |(./)      |(./)       |(./)        |(./)
Episode date       |(./)      |(./)       |(./)        |(./)
Episode duration   |{X}       |{X}        |{X}         |{X}
Episode author     |{X}       |{X}        |{X}         |{X}
Episode description|(./)      |(./)       |(./)        |{X}
Episode enclosure  |(./)      |(./)       |(./)        |(./)
"""]]

## Design

7. For each fancy podcast episode, write a blog post containing
   `\[[!meta enclosure="WikiLink/to/media.mp3"]]`. (Don't specify
   more than one enclosure -- but if you do, last one wins.)
7. When rendering to HTML (single-page or inlined), append a link
   to the media file.
7. When rendering to RSS/Atom, the text is the entry's content and
   the media file is its enclosure.
7. Don't break simple podcasts in pursuit of fancy podcasts.

## Implementation

### Completed

* Cover the existing simple podcast behavior with tests.
* Add an `enclosure` field to [[plugins/meta]] that expands the
  given [[ikiwiki/WikiLink]] to an absolute URL (feed enclosures
  pretty much need to be, and the reference feeds I've looked at
  all do this).
* Write failing tests for the desired single-page and inlined
  HTML behavior, then make them pass by adding enclosure stanzas
  to `{,inline}page.tmpl`.
* Write failing tests for the desired RSS/Atom behavior, then make
  them pass via changes to `{atom,rss}item.tmpl` and [[plugins/inline]].
* Match feature-for-feature with
  [tru_podcast](http://www.rainskit.com/blog/542/tru_podcast-a-podcasting-plugin-for-textpattern)
  (what [[schmonz]] will be migrating from).
* Enrich [feed metadata](http://cyber.law.harvard.edu/rss/rss.html)
  by catching up `rsspage.tmpl` to `atompage.tmpl`.
* Verify that [[plugins/more]] plays well with fancy podcasts.
* Verify that the feeds validate.
* Subscribe to a fancy feed in some common podcatchers and verify
  display details against a reference podcast.
* Verify smooth transitions for two common use cases (see testing
  details below).

### Must-have (for [[schmonz]], anyway)

* Think carefully about UTF-8.
* Verify that _all_ the tests pass (not just my new ones).

## Migration

### Upgrading within ikiwiki: from simple to fancy

#### My test podcast

For this test, I chose a podcast that tries to work around ikiwiki's
current limitations by issuing two separate `inline`s:

* One with `feedonly=yes` that includes `.mdwn`, `.pdf`, and `.mp3`
* One with `feeds=no` that includes only `.mdwn` (and makes a trail)

This has the following effects:

* Browser: sees just the articles (each of which has a manually
  created link to its corresponding media file)
* Feedreader: sees all the articles and media in one flat stream
* Podcatcher: sees just the media (sans articles)

I want instead to write one `inline` with these effects:

* Browser: sees just the articles (each of which automatically links
  to its enclosure)
* Feedreader: sees just the articles (each of which specifies its
  enclosure)
* Podcatcher: sees just the enclosures (each of which has an enclosing
  article, rendered as the media's "description")

#### Upgrade steps

7. Set up a non-production copy of the podcast.
    7. Visually diff RSS and Atom feeds against production.
    7. Subscribe to the copy (both feeds) in `r2e`, iTunes, Downcast.
7. Apply fancypodcast patch to the installed ikiwiki:
    7. `cd ~/Documents/trees/ikiwiki && git checkout fancypodcast`
    7. `git diff --no-prefix master > ~/Documents/trees/localpatches/www/ikiwiki/fancypodcast.diff`
    7. `cd ~/Documents/trees/pkgsrc-current/www/ikiwiki && make deinstall && make install clean`
7. Verify that simple podcasts are unaffected:
    7. Rerun `ikiwiki --setup`.
    7. `diff -uB simple-before.rss simple-after.rss`
        * A few new elements and attributes, as expected.
    7. `diff -uB simple-before.atom simple-after.atom`
        * No change.
7. Remove the feed-only `inline` and enable feeds on the remaining one.
7. Convert articles' manual download links to `\[[!meta enclosure=""]]`.
7. I want existing and future podcatchers to get my new fancy
   episodes, and I know my podcast isn't in any planets, so I'm
   going to skip [[tips/howto avoid flooding aggregators]].
7. Rerun `ikiwiki --setup`.
7. Verify browser shows the same stuff.
7. `diff -uB simple-after.rss fancy-after.rss   # and atom`
    * MP3s and PDFs are no longer naked enclosures, but belong to
      articles as they should.
    * Articles have updated modification times, as they should.
7. `r2e run` (both RSS and Atom)
    * Nothing new with the default `trust-guid = True` (otherwise
      would expect updated articles).
7. iTunes "Update Podcast" (both RSS and Atom)
    * Added one episode per article, with article text as the episode
      description.
    * Kept old naked-enclosure episodes around.
7. Downcast refresh (RSS):
    * Added one episode per article, with article text as the episode
      description.
    * Kept old naked-enclosure episodes around.
7. Downcast refresh (Atom):
    * Added one episode per article, with no episode description
      (expected, see feature table).
    * Kept old naked-enclosure episodes around.

Different tradeoffs are possible. These seem okay to me.

### Importing into ikiwiki: fancy (from another CMS)

#### My test podcast

For this test, I chose a podcast currently being published with
Textpattern and tru_podcast, because I'd strongly prefer to publish
it with ikiwiki instead.

#### Upgrade steps

7. Set up a non-production copy of the podcast.
    7. Visually diff RSS and Atom feeds against production.
    7. Subscribe to the copy (both feeds) in `r2e`, iTunes, Downcast.
7. With a fancypodcast-enabled ikiwiki installed:
    7. Copy content from Textpattern to ikiwiki:
        7. Match article paths to preserve `/YYYY/MM/DD/post-title` permalinks.
        7. Match enclosure paths (or redirect) to preserve Textpattern's URLs.
        7. Match titles, post dates, and guids with `\[[!meta]]`.
	    7. Match feed paths with permanent redirects from `/atom/` to
           `/index.atom` (and same for RSS).
        7. `\[[!inline]]` the articles.
    7. Rerun `ikiwiki --setup`.
7. Stop Textpattern, start ikiwiki.
7. Verify that podcatchers see the feeds and don't redownload anything.
7. Naively add two new blog posts, one with an enclosure.
7. Verify that podcatchers download the new enclosures.

-----

## Future improvements

### iTunes fancy podcasting

* [iTunes-specific tags](https://www.apple.com/itunes/podcasts/specs.html)
  appear to be RSS-only
    * If they work in Atom, teach `inline` to optionally iTunesify RSS/Atom.
    * Else, add `itunes` as a third kind of feed (RSS plus more stuff).
* Notable tags for feeds:
    * `itunes:subtitle`
    * `itunes:author`
    * `itunes:summary` (same as `description`)
    * `itunes:owner` (includes `itunes:name` and `itunes:email`)
    * `itunes:image href=''`
    * `itunes:publisher`
    * `itunes:category text=''` (can contain subcategories)
    * `itunes:keywords`
* Notable tags for entries:
    * `itunes:duration`
        * [[!cpan Audio::TagLib]] might be fastest, if present and applicable
        * [ffprobe](http://ffmpeg.org/ffprobe.html) is reasonably fast
        * [mediainfo](http://mediainfo.sourceforge.net/) is way slower
        * Cache computed durations as pagestate

### Fancy podcast aggregating

* Write tests comparing a fancy podcast (HTML and feeds) against
  the same podcast aggregated and republished, then make them pass
  via changes to `aggregatepost.impl` and [[plugins/aggregate]].

### Other ideas

* Don't render template text (e.g., "Use this template to insert a
  note into a page") in feeds.
* Optionally specify the enclosure's:
    * MIME type, in case `File::MimeInfo` guesses wrong.
    * Duration, in case `ffprobe` guesses wrong.
* Optionally specify enclosures outside the wiki:
    * Some people don't want to store big unchanging files in the VCS.
    * Other people like [podcasting found media](http://huffduffer.com/about).
    * We'd have to download the file just to compute some metadata
      about it, and then somehow not frequently re-download it.
* Configurably generate additional subscription links (such as
  iTunes) alongside the RSS/Atom ones in [[plugins/inline]].
* Support Apple's "enhanced podcasts" (if they're still relevant).