aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--setup.cfg2
-rw-r--r--youtube_podcaster/__init__.py28
-rw-r--r--youtube_podcaster/__main__.py8
-rw-r--r--youtube_podcaster/podcastfeeder.py43
-rw-r--r--[-rwxr-xr-x]youtube_podcaster/podcastupdater.py (renamed from youtube_podcaster/youtube-podcaster)81
-rw-r--r--youtube_podcaster/youtube/__init__.py4
7 files changed, 103 insertions, 69 deletions
diff --git a/.gitignore b/.gitignore
index f41c0ad..55cf740 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,9 @@ docs/api/*
39docs/_build/* 39docs/_build/*
40cover/* 40cover/*
41MANIFEST 41MANIFEST
42
43# Outputted files by youtube-podcaster
44*.xml
45*.save
46downloads/
47youtube-podcaster.json
diff --git a/setup.cfg b/setup.cfg
index 1d3b7c5..f1b8f8c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -13,6 +13,8 @@ classifiers = Development Status :: 3 - Alpha,
13 Programming Language :: Python :: 3 :: Only 13 Programming Language :: Python :: 3 :: Only
14 14
15[entry_points] 15[entry_points]
16console_scripts =
17 youtube-podcaster = youtube_podcaster:main
16# Add here console scripts like: 18# Add here console scripts like:
17# console_scripts = 19# console_scripts =
18# hello_world = youtube_podcaster.module:function 20# hello_world = youtube_podcaster.module:function
diff --git a/youtube_podcaster/__init__.py b/youtube_podcaster/__init__.py
new file mode 100644
index 0000000..32aee7c
--- /dev/null
+++ b/youtube_podcaster/__init__.py
@@ -0,0 +1,28 @@
1#!/usr/bin/env python3
2
3import json
4
5from http.server import (
6 HTTPServer,
7)
8
9from . import (
10 youtube,
11)
12
13from .podcastfeeder import (
14 create_feeder
15)
16
17
18def main():
19 config = json.load(open("youtube-podcaster.json"))
20
21 try:
22 PodcastFeeder = create_feeder(config["youtube"], config["podcasts"])
23 server = HTTPServer(("", 8888), PodcastFeeder)
24 server.serve_forever()
25 except KeyboardInterrupt:
26 server.socket.close()
27
28# vim: set ts=8 sw=4 tw=0 et :
diff --git a/youtube_podcaster/__main__.py b/youtube_podcaster/__main__.py
new file mode 100644
index 0000000..941a79a
--- /dev/null
+++ b/youtube_podcaster/__main__.py
@@ -0,0 +1,8 @@
1#!/usr/bin/env python3
2
3import youtube_podcaster
4
5if __name__ == "__main__":
6 youtube_podcaster.main()
7
8# vim: set ts=8 sw=4 tw=0 et :
diff --git a/youtube_podcaster/podcastfeeder.py b/youtube_podcaster/podcastfeeder.py
new file mode 100644
index 0000000..3f752d2
--- /dev/null
+++ b/youtube_podcaster/podcastfeeder.py
@@ -0,0 +1,43 @@
1from http.server import BaseHTTPRequestHandler
2
3from .podcastupdater import (
4 PodcastUpdater
5)
6
7
8def create_feeder(youtube_config, podcast_config):
9 class PodcastFeeder(BaseHTTPRequestHandler):
10 def __init__(self, request, client_address, server):
11 self.updater = PodcastUpdater(youtube_config, podcast_config)
12 super(PodcastFeeder, self).__init__(request, client_address, server)
13
14 def do_GET(self):
15 path = self.path.split('/')
16
17 if len(path) == 3:
18 channel = path[1]
19 playlist = path[2]
20 else:
21 return self.return_error(404)
22
23 xml = self.updater.get_xml(channel, playlist)
24
25 if not xml:
26 return self.return_error(404)
27 else:
28 self.send_response(200)
29 self.send_header("Content-type", "text/xml")
30 self.end_headers()
31 self.wfile.write(bytes(xml, 'UTF-8'))
32
33 def return_error(self, code):
34 self.send_response(code)
35 self.send_header("Content-type", "text/html")
36 self.end_headers()
37
38 reponse = "<body>Error: %s</body>" % (code)
39 self.wfile.write(bytes(reponse, 'UTF-8'))
40
41 return PodcastFeeder
42
43# vim: set ts=8 sw=4 tw=0 et :
diff --git a/youtube_podcaster/youtube-podcaster b/youtube_podcaster/podcastupdater.py
index bb2db26..4a0a017 100755..100644
--- a/youtube_podcaster/youtube-podcaster
+++ b/youtube_podcaster/podcastupdater.py
@@ -1,29 +1,19 @@
1#!/usr/bin/env python3
2import time
3import os
4import pickle 1import pickle
5import json 2import os
6 3import time
7from http.server import HTTPServer, BaseHTTPRequestHandler 4import hashlib
8from hashlib import sha1
9 5
10from feedgen.feed import FeedGenerator 6from feedgen.feed import FeedGenerator
11 7
12import youtube 8from . import (
9 youtube,
10)
13 11
14 12
15class PodcastUpdater: 13class PodcastUpdater:
16 instance = None 14 def __init__(self, youtube_config, podcast_config):
17 15 self.podcasts = podcast_config
18 def get_instance(): 16 self.youtube = youtube.Youtube(youtube_config["api-key"])
19 if PodcastUpdater.instance:
20 return PodcastUpdater.instance
21 else:
22 PodcastUpdater.instance = PodcastUpdater()
23 return PodcastUpdater.instance
24
25 def __init__(self):
26 self.podcasts = config["podcasts"]
27 17
28 self.feeds_file = "feeds.save" 18 self.feeds_file = "feeds.save"
29 if os.path.isfile(self.feeds_file): 19 if os.path.isfile(self.feeds_file):
@@ -51,9 +41,9 @@ class PodcastUpdater:
51 return open(xml).read() 41 return open(xml).read()
52 42
53 def update_podcast(self, channel, playlist): 43 def update_podcast(self, channel, playlist):
54 feed_id = sha1(bytes("%s %s" % (channel, playlist), "UTF-8")).hexdigest() 44 feed_id = hashlib.sha1(bytes("%s %s" % (channel, playlist), "UTF-8")).hexdigest()
55 yt_channel = yt.get_channel(channel)[0] 45 yt_channel = self.youtube.get_channel(channel)[0]
56 yt_playlists = yt.get_playlists(yt_channel, 50) 46 yt_playlists = self.youtube.get_playlists(yt_channel, 50)
57 47
58 for yt_playlist in yt_playlists: 48 for yt_playlist in yt_playlists:
59 if yt_playlist["snippet"]["title"] == playlist: 49 if yt_playlist["snippet"]["title"] == playlist:
@@ -92,12 +82,12 @@ class PodcastUpdater:
92 return feed 82 return feed
93 83
94 def populate_feed(self, feed, feed_id, yt_playlist, max_results=5): 84 def populate_feed(self, feed, feed_id, yt_playlist, max_results=5):
95 videos = yt.get_playlist_items(yt_playlist, max_results) 85 videos = self.youtube.get_playlist_items(yt_playlist, max_results)
96 downloader = youtube.Downloader.get_instance("vorbis", "downloads", "192.168.178.100") 86 downloader = youtube.Downloader.get_instance("vorbis", "downloads", "192.168.178.100")
97 87
98 entries = feed.entry() 88 entries = feed.entry()
99 for video in videos: 89 for video in videos:
100 video_id = sha1(bytes(video["id"], "UTF-8")).hexdigest() 90 video_id = hashlib.sha1(bytes(video["id"], "UTF-8")).hexdigest()
101 for entry in entries: 91 for entry in entries:
102 if entry.id() == video_id: 92 if entry.id() == video_id:
103 break 93 break
@@ -113,47 +103,4 @@ class PodcastUpdater:
113 103
114 feed.last_updated = time.time() 104 feed.last_updated = time.time()
115 105
116
117class PodcastFeeder(BaseHTTPRequestHandler):
118 def do_GET(self):
119 updater = PodcastUpdater.get_instance()
120 path = self.path.split('/')
121
122 if len(path) == 3:
123 channel = path[1]
124 playlist = path[2]
125 else:
126 return self.return_error(404)
127
128 xml = updater.get_xml(channel, playlist)
129
130 if not xml:
131 return self.return_error(404)
132 else:
133 self.send_response(200)
134 self.send_header("Content-type", "text/xml")
135 self.end_headers()
136 self.wfile.write(bytes(xml, 'UTF-8'))
137
138 def return_error(self, code):
139 self.send_response(code)
140 self.send_header("Content-type", "text/html")
141 self.end_headers()
142
143 reponse = "<body>Error: %s</body>" % (code)
144 self.wfile.write(bytes(reponse, 'UTF-8'))
145
146
147def main():
148 try: