diff options
Diffstat (limited to 'youtube_podcaster/podcastupdater.py')
| -rw-r--r-- | youtube_podcaster/podcastupdater.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/youtube_podcaster/podcastupdater.py b/youtube_podcaster/podcastupdater.py new file mode 100644 index 0000000..4a0a017 --- /dev/null +++ b/youtube_podcaster/podcastupdater.py | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | import pickle | ||
| 2 | import os | ||
| 3 | import time | ||
| 4 | import hashlib | ||
| 5 | |||
| 6 | from feedgen.feed import FeedGenerator | ||
| 7 | |||
| 8 | from . import ( | ||
| 9 | youtube, | ||
| 10 | ) | ||
| 11 | |||
| 12 | |||
| 13 | class PodcastUpdater: | ||
| 14 | def __init__(self, youtube_config, podcast_config): | ||
| 15 | self.podcasts = podcast_config | ||
| 16 | self.youtube = youtube.Youtube(youtube_config["api-key"]) | ||
| 17 | |||
| 18 | self.feeds_file = "feeds.save" | ||
| 19 | if os.path.isfile(self.feeds_file): | ||
| 20 | with open(self.feeds_file, "rb") as feeds: | ||
| 21 | self.feeds = pickle.load(feeds) | ||
| 22 | else: | ||
| 23 | self.feeds = {} | ||
| 24 | |||
| 25 | def get_xml(self, channel, playlist): | ||
| 26 | channel = channel.replace('_', ' ') | ||
| 27 | playlist = playlist.replace('_', ' ') | ||
| 28 | |||
| 29 | for podcast in self.podcasts: | ||
| 30 | if podcast["username"] == channel: | ||
| 31 | break | ||
| 32 | else: | ||
| 33 | return None | ||
| 34 | |||
| 35 | if playlist not in podcast["playlists"]: | ||
| 36 | return None | ||
| 37 | |||
| 38 | xml = self.update_podcast(channel, playlist) | ||
| 39 | |||
| 40 | if xml: | ||
| 41 | return open(xml).read() | ||
| 42 | |||
| 43 | def update_podcast(self, channel, playlist): | ||
| 44 | feed_id = hashlib.sha1(bytes("%s %s" % (channel, playlist), "UTF-8")).hexdigest() | ||
| 45 | yt_channel = self.youtube.get_channel(channel)[0] | ||
| 46 | yt_playlists = self.youtube.get_playlists(yt_channel, 50) | ||
| 47 | |||
| 48 | for yt_playlist in yt_playlists: | ||
| 49 | if yt_playlist["snippet"]["title"] == playlist: | ||
| 50 | break | ||
| 51 | else: | ||
| 52 | return None | ||
| 53 | |||
| 54 | if feed_id in self.feeds: | ||
| 55 | feed = self.feeds[feed_id] | ||
| 56 | else: | ||
| 57 | feed = self.add_feed(feed_id, yt_playlist) | ||
| 58 | |||
| 59 | if feed.last_updated < time.time() - 600: | ||
| 60 | self.populate_feed(feed, feed_id, yt_playlist) | ||
| 61 | |||
| 62 | feed_file = "%s.xml" % (feed_id) | ||
| 63 | self.feeds[feed_id].rss_file(feed_file) | ||
| 64 | |||
| 65 | with open(self.feeds_file, "wb") as feed: | ||
| 66 | pickle.dump(self.feeds, feed) | ||
| 67 | |||
| 68 | return "%s.xml" % (feed_id) | ||
| 69 | |||
| 70 | def add_feed(self, feed_id, yt_playlist): | ||
| 71 | feed = FeedGenerator() | ||
| 72 | feed.load_extension("podcast") | ||
| 73 | feed.id(feed_id) | ||
| 74 | feed.title(yt_playlist["snippet"]["title"]) | ||
| 75 | feed.author({"name": yt_playlist["snippet"]["channelTitle"]}) | ||
| 76 | feed.description(yt_playlist["snippet"]["description"]) | ||
| 77 | feed.logo(yt_playlist["snippet"]["thumbnails"]["standard"]["url"]) | ||
| 78 | feed.link(href="https://www.youtube.com/playlist?list=%s" % (yt_playlist["id"])) | ||
| 79 | feed.rss_str(pretty=True) | ||
| 80 | feed.last_updated = 0 | ||
| 81 | self.feeds[feed_id] = feed | ||
| 82 | return feed | ||
| 83 | |||
| 84 | def populate_feed(self, feed, feed_id, yt_playlist, max_results=5): | ||
| 85 | videos = self.youtube.get_playlist_items(yt_playlist, max_results) | ||
| 86 | downloader = youtube.Downloader.get_instance("vorbis", "downloads", "192.168.178.100") | ||
| 87 | |||
| 88 | entries = feed.entry() | ||
| 89 | for video in videos: | ||
| 90 | video_id = hashlib.sha1(bytes(video["id"], "UTF-8")).hexdigest() | ||
| 91 | for entry in entries: | ||
| 92 | if entry.id() == video_id: | ||
| 93 | break | ||
| 94 | else: | ||
| 95 | url, size, mime = downloader.download(video, video_id, feed_id) | ||
| 96 | feed_entry = feed.add_entry() | ||
| 97 | feed_entry.id(video_id) | ||
| 98 | feed_entry.guid(video_id) | ||
| 99 | feed_entry.title(video["snippet"]["title"]) | ||
| 100 | feed_entry.description(video["snippet"]["description"]) | ||
| 101 | feed_entry.published(video["snippet"]["publishedAt"]) | ||
| 102 | feed_entry.enclosure(url, size, mime) | ||
| 103 | |||
| 104 | feed.last_updated = time.time() | ||
| 105 | |||
| 106 | # vim: set ts=8 sw=4 tw=0 et : | ||
