jekyll-octopod 0.20.1 → 0.22.0
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.
- checksums.yaml +4 -4
- data/lib/jekyll/podlove_player_tag.rb +75 -1
- data/lib/octopod/version.rb +2 -2
- metadata +1 -2
- data/assets/_config.yml +0 -47
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 24977665ce521eb079a357fb865df920bccd0fed95bddf6b33c28022305d58ce
|
|
4
|
+
data.tar.gz: 5b1626a963311fcdb716f95ad3251a6dd4901398988450ac87c266c9614e720c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8318ee2181c3e65b494edb97f399c812b993ed8ccffe62c3b7ba58d016ff063d75725dcd25eb3174fce351943c35b983b77a46046715e6130e507efc34f34e6e
|
|
7
|
+
data.tar.gz: c85acaa2673dea3dedafdec6a84c8c3a19f2da26cb211fe7fbbd913efb93187f645ebad63aafedd442cd4be928276bfa93f67a07447d3ae75c1590827cbe350f
|
|
@@ -4,6 +4,11 @@ module Jekyll
|
|
|
4
4
|
class PodlovePlayerTag < Liquid::Tag
|
|
5
5
|
include Jekyll::OctopodFilters
|
|
6
6
|
|
|
7
|
+
# Every channel the player itself supports (per the config docs below) - sent unconditionally
|
|
8
|
+
# rather than exposed as a site/post setting, so the share tab always has something to offer
|
|
9
|
+
# instead of defaulting to the player's own empty channel list.
|
|
10
|
+
SHARE_CHANNELS = %w[twitter facebook whats-app linkedin pinterest xing mail link].freeze
|
|
11
|
+
|
|
7
12
|
# From here: https://docs.podlove.org/podlove-web-player/v5/configuration
|
|
8
13
|
def playerconfig(context)
|
|
9
14
|
config = context.registers[:site].config
|
|
@@ -39,10 +44,79 @@ module Jekyll
|
|
|
39
44
|
publicationDate: page["date"].respond_to?(:xmlschema) ? page["date"].xmlschema : page["date"].to_s,
|
|
40
45
|
duration: page["duration"],
|
|
41
46
|
audio: audio,
|
|
42
|
-
chapters: page["chapters"] ? page["chapters"].map { |chapter| split_chapter(chapter) }.compact : nil
|
|
47
|
+
chapters: page["chapters"] ? page["chapters"].map { |chapter| split_chapter(chapter) }.compact : nil,
|
|
48
|
+
transcripts: transcripts_for(page),
|
|
49
|
+
share: { channels: SHARE_CHANNELS }
|
|
43
50
|
}.to_json
|
|
44
51
|
end
|
|
45
52
|
|
|
53
|
+
# Finds a WebVTT transcript for this episode and parses it into the cue list Podlove Web
|
|
54
|
+
# Player's "transcripts" config field expects (see the same docs link above the config
|
|
55
|
+
# method: a plain list of { start, start_ms, end, end_ms, speaker, voice, text } cues - the
|
|
56
|
+
# player has no native understanding of WebVTT itself, so this is doing that conversion, not
|
|
57
|
+
# just passing the file through). Looks for an explicit page["transcript"] filename first,
|
|
58
|
+
# then falls back to the audio file's own basename with a .vtt extension (i.e.
|
|
59
|
+
# "episode1.mp3" -> "episode1.vtt"), resolved on disk the same way file_size() locates audio
|
|
60
|
+
# files: relative to the site root if the filename already contains a "/", otherwise under
|
|
61
|
+
# episodes/. Returns nil if there's no matching, parseable file, so the config field is
|
|
62
|
+
# simply omitted rather than sent empty.
|
|
63
|
+
def transcripts_for(page)
|
|
64
|
+
filename = page["transcript"] || vtt_sibling_of(page["audio"])
|
|
65
|
+
return nil unless filename
|
|
66
|
+
|
|
67
|
+
path = filename =~ /\// ? filename : File.join('episodes', filename)
|
|
68
|
+
return nil unless File.exist?(path)
|
|
69
|
+
|
|
70
|
+
cues = parse_vtt(File.read(path, encoding: 'UTF-8'))
|
|
71
|
+
cues.empty? ? nil : cues
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def vtt_sibling_of(audio_hash)
|
|
75
|
+
return nil unless audio_hash
|
|
76
|
+
primary = audio(audio_hash)
|
|
77
|
+
return nil unless primary
|
|
78
|
+
|
|
79
|
+
primary.sub(/\.[^.\/]+\z/, '.vtt')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Parses WebVTT cues, including Auphonic's "<v Speaker>text</v>" voice-tag convention. Not a
|
|
83
|
+
# full WebVTT implementation (no styling, regions, or nested tags) - just enough to turn
|
|
84
|
+
# timed, optionally speaker-tagged captions into Podlove's transcript-cue shape.
|
|
85
|
+
def parse_vtt(content)
|
|
86
|
+
content = content.sub(/\A\xEF\xBB\xBF/, '').gsub("\r\n", "\n")
|
|
87
|
+
|
|
88
|
+
content.split(/\n\n+/).filter_map do |block|
|
|
89
|
+
lines = block.strip.split("\n")
|
|
90
|
+
next nil if lines.empty?
|
|
91
|
+
|
|
92
|
+
# Discard the "WEBVTT" header, NOTE/STYLE/REGION blocks, and any cue identifier line -
|
|
93
|
+
# everything up to the "start --> end" timing line, which is left in place once found.
|
|
94
|
+
lines.shift while lines.first && !lines.first.include?('-->')
|
|
95
|
+
timing = lines.shift
|
|
96
|
+
next nil unless timing
|
|
97
|
+
|
|
98
|
+
match = timing.match(/((?:\d{2}:)?\d{2}:\d{2}\.\d{3})\s*-->\s*((?:\d{2}:)?\d{2}:\d{2}\.\d{3})/)
|
|
99
|
+
next nil unless match
|
|
100
|
+
|
|
101
|
+
text = lines.join(' ').strip
|
|
102
|
+
voice = text[/\A<v\s+([^>]+)>/, 1]
|
|
103
|
+
text = text.sub(/\A<v\s+[^>]+>/, '').sub(%r{</v>\z}, '').strip
|
|
104
|
+
|
|
105
|
+
{ start: match[1], start_ms: ms_from_vtt_timestamp(match[1]),
|
|
106
|
+
end: match[2], end_ms: ms_from_vtt_timestamp(match[2]),
|
|
107
|
+
speaker: nil, voice: voice, text: text }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def ms_from_vtt_timestamp(timestamp)
|
|
112
|
+
parts = timestamp.split(':')
|
|
113
|
+
seconds, millis = parts.pop.split('.')
|
|
114
|
+
minutes = parts.pop.to_i
|
|
115
|
+
hours = parts.empty? ? 0 : parts.pop.to_i
|
|
116
|
+
|
|
117
|
+
(((hours * 60) + minutes) * 60 + seconds.to_i) * 1000 + millis.to_i
|
|
118
|
+
end
|
|
119
|
+
|
|
46
120
|
def playerbaseconfig(context)
|
|
47
121
|
config = context.registers[:site].config
|
|
48
122
|
{ version: 5, base: "#{config["url"]}/assets/podlove-player/" }.to_json
|
data/lib/octopod/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-octopod
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.22.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Arne Eilermann
|
|
@@ -105,7 +105,6 @@ extra_rdoc_files: []
|
|
|
105
105
|
files:
|
|
106
106
|
- README.md
|
|
107
107
|
- Rakefile
|
|
108
|
-
- assets/_config.yml
|
|
109
108
|
- assets/_config.yml.sample
|
|
110
109
|
- assets/_posts/2016-03-22-episode0.md
|
|
111
110
|
- assets/_sass/_overrides.scss
|
data/assets/_config.yml
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# You have to configure this ###################################################
|
|
2
|
-
title: Octopod
|
|
3
|
-
# You should configure this ####################################################
|
|
4
|
-
url: http://localhost:4000
|
|
5
|
-
subtitle: Static Site Podcast Publishing for Geeks
|
|
6
|
-
description: My super duper cool podcast.
|
|
7
|
-
author: Uncle Octopod
|
|
8
|
-
email: octopod@example.com
|
|
9
|
-
keywords: [octopod, podcast, magic]
|
|
10
|
-
itunes_categories: [Technology]
|
|
11
|
-
# additional_feeds:
|
|
12
|
-
# itunes: http://itunes.apple.com/de/podcast/podcast_name/id42424242
|
|
13
|
-
# torrent_m4a: http://bitlove.org/example_user/example_podcast_m4a/feed
|
|
14
|
-
# torrent_mp3: http://bitlove.org/example_user/example_podcast_mp3/feed
|
|
15
|
-
episodes_per_feed_page: 100
|
|
16
|
-
## Rsync Deploy config #########################################################
|
|
17
|
-
### Be sure your public key is listed in your server's ~/.ssh/authorized_keys
|
|
18
|
-
### file.
|
|
19
|
-
ssh_host: user@host.org
|
|
20
|
-
ssh_port: 22
|
|
21
|
-
document_root: /path/to/your/htdocs/
|
|
22
|
-
rsync_delete: true
|
|
23
|
-
# You can configure this #######################################################
|
|
24
|
-
twitter_nick: my_twitter_handle
|
|
25
|
-
language: en
|
|
26
|
-
explicit: 'no' # 'yes'/'no'/clean
|
|
27
|
-
license: CC BY 4.0
|
|
28
|
-
license_url: https://creativecommons.org/licenses/by/4.0/
|
|
29
|
-
license_image_url: https://i.creativecommons.org/l/by/4.0/88x31.png
|
|
30
|
-
## Flattr ######################################################################
|
|
31
|
-
flattr_uid: # Flattr will not be used unless this is set
|
|
32
|
-
flattr_button: compact # compact | default
|
|
33
|
-
flattr_mode: auto # auto | manual(default)
|
|
34
|
-
flattr_popout: 1 # 1 | 0 (show popout when hovering mouse over button)
|
|
35
|
-
flattr_language: en_GB # available languages - https://api.flattr.com/rest/v2/languages.txt
|
|
36
|
-
flattr_category: audio # available categories - https://api.flattr.com/rest/v2/categories.txt
|
|
37
|
-
## Disqus comments #############################################################
|
|
38
|
-
disqus_shortname: # Disqus will not be used unless this is set
|
|
39
|
-
disqus_developer: 0 # 1 / 0
|
|
40
|
-
## Feed links ###########################################################
|
|
41
|
-
itunes_url: https://itunes.apple.com/at/podcast/myname/id#myid#
|
|
42
|
-
bitlove_url: https://bitlove.org/myaccount
|
|
43
|
-
fyyd_url: https://fyyd.de/podcast/myaccount/myid
|
|
44
|
-
gpodder_url: https://gpodder.net/podcast/mypodcast
|
|
45
|
-
|
|
46
|
-
gems: [jekyll-octopod]
|
|
47
|
-
theme: jekyll-bootflat
|