Adding date support so we can navigate programming
[watersofshiloah] / src / backend.py
1 #!/usr/bin/env python
2
3 import urllib
4 from xml.etree import ElementTree
5 import logging
6
7 import browser_emu
8
9
10 _moduleLogger = logging.getLogger(__name__)
11
12
13 class Backend(object):
14
15         def __init__(self):
16                 self._browser = browser_emu.MozillaEmulator()
17
18         def get_languages(self):
19                 tree = self._get_page_with_validation(
20                         action="lds.radio.languages.query",
21                 )
22                 languages = tree.find("languages")
23                 return self._process_list(languages, ["name"])
24
25         def get_radio_channels(self):
26                 tree = self._get_page_with_validation(
27                         action="lds.radio.radiochannels.query",
28                 )
29                 channels = tree.find("channels")
30                 return self._process_list(channels, ["description", "url", "port"])
31
32         def get_radio_channel_programming(self, chanId, date=None):
33                 if date is not None:
34                         date = date.strftime("%Y-%m-%d")
35                         tree = self._get_page_with_validation(
36                                 action="lds.radio.radiochannels.programming.query",
37                                 channelID=chanId,
38                                 date=date,
39                         )
40                 else:
41                         tree = self._get_page_with_validation(
42                                 action="lds.radio.radiochannels.programming.query",
43                                 channelID=chanId,
44                         )
45                 programs = tree.find("programs")
46                 return self._process_list(programs, ["date", "time", "title", "shortdescription", "artist"])
47
48         def get_conferences(self, langId):
49                 tree = self._get_page_with_validation(
50                         action="lds.radio.conferences.query",
51                         languageID=langId,
52                 )
53                 conferences = tree.find("conferences")
54                 return self._process_list(conferences, ["title", "full_title", "month", "year"])
55
56         def get_conference_sessions(self, confId):
57                 tree = self._get_page_with_validation(
58                         action="lds.radio.conferences.sessions.query",
59                         conferenceID=confId,
60                 )
61                 items = tree.find("sessions")
62                 return self._process_list(items, ["title", "short_title", "order"])
63
64         def get_conference_talks(self, sessionId):
65                 tree = self._get_page_with_validation(
66                         action="lds.radio.conferences.sessions.talks.query",
67                         sessionID=sessionId,
68                 )
69                 items = tree.find("talks")
70                 return self._process_list(items, ["title", "order", "url", "speaker"])
71
72         def get_magazines(self, langId):
73                 tree = self._get_page_with_validation(
74                         action="lds.radio.magazines.query",
75                         languageID=langId,
76                 )
77                 magazines = tree.find("magazines")
78                 return self._process_list(magazines, ["title"])
79
80         def get_magazine_issues(self, magId):
81                 tree = self._get_page_with_validation(
82                         action="lds.radio.magazines.issues.query",
83                         magazineID=magId,
84                 )
85                 items = tree.find("issues")
86                 return self._process_list(items, ["title", "year", "month", "pictureURL"])
87
88         def get_magazine_articles(self, issueId):
89                 tree = self._get_page_with_validation(
90                         action="lds.radio.magazines.issues.articles.query",
91                         issueID=issueId,
92                 )
93                 items = tree.find("articles")
94                 return self._process_list(items, ["title", "author", "url"])
95
96         def get_scriptures(self, langId):
97                 tree = self._get_page_with_validation(
98                         action="lds.radio.scriptures.query",
99                         languageID=langId,
100                 )
101                 scriptures = tree.find("scriptures")
102                 return self._process_list(scriptures, ["title"])
103
104         def get_scripture_books(self, scriptId):
105                 tree = self._get_page_with_validation(
106                         action="lds.radio.scriptures.books.query",
107                         scriptureID=scriptId,
108                 )
109                 items = tree.find("books")
110                 return self._process_list(items, ["title"])
111
112         def get_scripture_chapters(self, bookId):
113                 tree = self._get_page_with_validation(
114                         action="lds.radio.scriptures.books.chapters.query",
115                         bookID=bookId,
116                 )
117                 items = tree.find("chapters")
118                 return self._process_list(items, ["title", "url"])
119
120         def _get_page_with_validation(self, **params):
121                 encodedParams = urllib.urlencode(params)
122                 page = self._browser.download("http://tech.lds.org/radio?%s" % encodedParams)
123                 if not page:
124                         raise RuntimeError("Blank page")
125                 tree = ElementTree.fromstring(page)
126
127                 if tree.tag == "apiresults":
128                         desc = tree.find("ErrorDescription")
129                         raise RuntimeError(desc.text)
130                 else:
131                         results = tree.find("apiresults")
132                         if not results.attrib["success"]:
133                                 raise RuntimeError("Could not determine radio languages")
134
135                 return tree
136
137         def _process_list(self, tree, elements):
138                 for item in tree.getchildren():
139                         data = {"id": item.attrib["ID"]}
140                         for element in elements:
141                                 data[element] = item.find(element).text
142                         yield data
143
144
145 if __name__ == "__main__":
146         b = Backend()
147
148         print list(b.get_languages())
149
150         if False:
151                 channels = list(b.get_radio_channels())
152                 print channels
153                 for chanData in channels:
154                         programs = list(b.get_radio_channel_programming(chanData["id"]))
155                         print programs
156
157         if False:
158                 confs = list(b.get_conferences(1))
159                 print confs
160                 for confData in confs:
161                         sessions = list(b.get_conference_sessions(confData["id"]))
162                         for sessionData in sessions:
163                                 talks = list(b.get_conference_talks(sessionData["id"]))
164                                 print talks
165
166         if False:
167                 mags = list(b.get_magazines(1))
168                 print mags
169                 for magData in mags:
170                         issues = list(b.get_magazine_issues(magData["id"]))
171                         issues
172                         for issueData in issues:
173                                 articles = list(b.get_magazine_articles(issueData["id"]))
174                                 print articles
175
176         if False:
177                 mags = list(b.get_scriptures(1))
178                 print mags
179                 for magData in mags:
180                         books = list(b.get_scripture_books(magData["id"]))
181                         print books
182                         for bookData in books:
183                                 chapters = list(b.get_scripture_chapters(bookData["id"]))
184                                 print chapters