aboutsummaryrefslogtreecommitdiffstats
path: root/youtube_podcaster/podcastupdater.py
blob: 75b8b107ee7a2af69fcd45c5e98ddbaa86dbe533 (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
import pickle
import os
import time
import hashlib
import sys

from feedgen.feed import FeedGenerator

from . import (
    youtube,
)


class PodcastUpdater:
    def __init__(self, config):
        self.podcasts = config.podcasts
        self.youtube = youtube.Youtube(config.youtube["api-key"])

        if sys.platform == "linux" and not hasattr(sys, "real_prefix"):
            self.data_dir = "/var/lib/youtube-podcaster"
        else:
            self.data_dir = "%s/var/lib/youtube-podcaster" % (sys.prefix)

        os.makedirs(self.data_dir, 0o755, True)

        self.feeds_file = "%s/feeds.dump" % (self.data_dir)

        if os.path.isfile(self.feeds_file):
            with open(self.feeds_file, "rb") as feeds:
                self.feeds = pickle.load(feeds)
        else:
            self.feeds = {}

    def get_xml(self, channel, playlist):
        channel = channel.replace('_', ' ')
        playlist = playlist.replace('_', ' ')

        for podcast in self.podcasts:
            if podcast["username"] == channel:
                break
        else:
            return None

        if playlist not in podcast["playlists"]:
            return None

        xml = self.update_podcast(channel, playlist)

        if xml:
            return open(xml).read()

    def update_podcast(self, channel, playlist):
        feed_id = hashlib.sha1(bytes("%s %s" % (channel, playlist), "UTF-8")).hexdigest()
        feed_file = "%s/%s.xml" % (self.data_dir, feed_id)

        yt_channel = self.youtube.get_channel(channel)[0]
        yt_playlists = self.youtube.get_playlists(yt_channel, 50)

        for yt_playlist in yt_playlists:
            if yt_playlist["snippet"]["title"] == playlist:
                break
        else:
            return None

        if feed_id in self.feeds:
            feed = self.feeds[feed_id]
        else:
            feed = self.add_feed(feed_id, yt_playlist)

        if feed.last_updated < time.time() - 600:
            self.populate_feed(feed, feed_id, yt_playlist)
            feed.rss_file(feed_file)

            with open(self.feeds_file, "wb") as feeds:
                pickle.dump(self.feeds, feeds)

        return feed_file

    def add_feed(self, feed_id, yt_playlist):
        feed = FeedGenerator()

        feed.load_extension("podcast")
        feed.id(feed_id)
        feed.title(yt_playlist["snippet"]["title"])
        feed.author({"name": yt_playlist["snippet"]["channelTitle"]})
        feed.description(yt_playlist["snippet"]["description"])
        feed.logo(yt_playlist["snippet"]["thumbnails"]["standard"]["url"])
        feed.link(href="https://www.youtube.com/playlist?list=%s" % (yt_playlist["id"]))
        feed.rss_str(pretty=True)
        feed.last_updated = 0

        self.feeds[feed_id] = feed

        return feed

    def populate_feed(self, feed, feed_id, yt_playlist, max_results=5):
        videos = self.youtube.get_playlist_items(yt_playlist, max_results)
        downloader = youtube.Downloader.get_instance("vorbis", "downloads", "192.168.178.100")

        entries = feed.entry()
        for video in videos:
            video_id = hashlib.sha1(bytes(video["id"], "UTF-8")).hexdigest()
            for entry in entries:
                if entry.id() == video_id:
                    break
            else:
                url, size, mime = downloader.download(video, video_id, feed_id)

                feed_entry = feed.add_entry()

                feed_entry.id(video_id)
                feed_entry.guid(video_id)
                feed_entry.title(video["snippet"]["title"])
                feed_entry.description(video["snippet"]["description"])
                feed_entry.published(video["snippet"]["publishedAt"])
                feed_entry.enclosure(url, size, mime)

        feed.last_updated = time.time()

#  vim: set ts=8 sw=4 tw=0 et :