bff0853177ca584409964bfa2b4018bba9a460b4
[watersofshiloah] / src / windows / magazines.py
1 import logging
2
3 import gobject
4 import gtk
5
6 import hildonize
7 import util.go_utils as go_utils
8 import util.misc as misc_utils
9 import banners
10 import presenter
11 import stream_index
12
13 import windows
14
15
16 _moduleLogger = logging.getLogger(__name__)
17
18
19 class MagazinesWindow(windows._base.ListWindow):
20
21         def __init__(self, app, player, store, node):
22                 windows._base.ListWindow.__init__(self, app, player, store, node)
23                 self._window.set_title(self._node.title)
24
25         @classmethod
26         def _get_columns(cls):
27                 yield gobject.TYPE_PYOBJECT, None
28
29                 pixrenderer = gtk.CellRendererPixbuf()
30                 column = gtk.TreeViewColumn("Covers")
31                 column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
32                 column.set_property("fixed-width", 96)
33                 column.pack_start(pixrenderer, expand=True)
34                 column.add_attribute(pixrenderer, "pixbuf", 1)
35                 yield gobject.TYPE_OBJECT, column
36
37                 textrenderer = gtk.CellRendererText()
38                 hildonize.set_cell_thumb_selectable(textrenderer)
39                 column = gtk.TreeViewColumn("Magazine")
40                 column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
41                 column.pack_start(textrenderer, expand=True)
42                 column.add_attribute(textrenderer, "text", 2)
43                 yield gobject.TYPE_STRING, column
44
45         def _refresh(self):
46                 windows._base.ListWindow._refresh(self)
47                 self._node.get_children(
48                         self._on_magazines,
49                         self._on_error,
50                 )
51
52         @misc_utils.log_exception(_moduleLogger)
53         def _on_magazines(self, programs):
54                 if self._isDestroyed:
55                         _moduleLogger.info("Download complete but window destroyed")
56                         return
57
58                 self._hide_loading()
59                 for i, programNode in enumerate(programs):
60                         program = programNode.get_properties()
61                         img = self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["nomagazineimage"])
62                         row = programNode, img, program["title"]
63                         self._model.append(row)
64
65                         programNode.get_children(self._create_on_issues(i), self._on_error)
66
67                 self._select_row()
68
69         def _create_on_issues(self, row):
70                 return lambda issues: self._on_issues(row, issues)
71
72         @misc_utils.log_exception(_moduleLogger)
73         def _on_issues(self, row, issues):
74                 for issue in issues:
75                         self._store.get_pixbuf_from_url(
76                                 issue.get_properties()["pictureURL"],
77                                 lambda pix: self._on_image(row, pix),
78                                 self._on_error,
79                         )
80                         break
81                 else:
82                         _moduleLogger.info("No issues for magazine %s" % row)
83
84         @misc_utils.log_exception(_moduleLogger)
85         def _on_image(self, row, pix):
86                 treeiter = self._model.iter_nth_child(None, row)
87                 self._model.set_value(treeiter, 1, pix)
88                 treeiter = self._model.iter_nth_child(None, row)
89                 self._model.row_changed((row, ), treeiter)
90
91         @misc_utils.log_exception(_moduleLogger)
92         def _on_error(self, exception):
93                 self._hide_loading()
94                 self._errorBanner.push_message(str(exception))
95
96         def _window_from_node(self, node):
97                 issuesWindow = MagazineIssuesWindow(self._app, self._player, self._store, node)
98                 issuesWindow.window.set_modal(True)
99                 issuesWindow.window.set_transient_for(self._window)
100                 issuesWindow.window.set_default_size(*self._window.get_size())
101                 issuesWindow.connect("quit", self._on_quit)
102                 issuesWindow.connect("home", self._on_home)
103                 issuesWindow.connect("jump-to", self._on_jump)
104                 issuesWindow.show()
105                 return issuesWindow
106
107
108 gobject.type_register(MagazinesWindow)
109
110
111 class MagazineIssuesWindow(windows._base.ListWindow):
112
113         def __init__(self, app, player, store, node):
114                 windows._base.ListWindow.__init__(self, app, player, store, node)
115                 self._window.set_title(self._node.title)
116
117         @classmethod
118         def _get_columns(cls):
119                 yield gobject.TYPE_PYOBJECT, None
120
121                 pixrenderer = gtk.CellRendererPixbuf()
122                 column = gtk.TreeViewColumn("Covers")
123                 column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
124                 column.set_property("fixed-width", 96)
125                 column.pack_start(pixrenderer, expand=True)
126                 column.add_attribute(pixrenderer, "pixbuf", 1)
127                 yield gobject.TYPE_OBJECT, column
128
129                 textrenderer = gtk.CellRendererText()
130                 hildonize.set_cell_thumb_selectable(textrenderer)
131                 column = gtk.TreeViewColumn("Issue")
132                 column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
133                 column.pack_start(textrenderer, expand=True)
134                 column.add_attribute(textrenderer, "text", 2)
135                 yield gobject.TYPE_STRING, column
136
137         def _refresh(self):
138                 windows._base.ListWindow._refresh(self)
139                 self._node.get_children(
140                         self._on_magazine_issues,
141                         self._on_error,
142                 )
143
144         @misc_utils.log_exception(_moduleLogger)
145         def _on_magazine_issues(self, programs):
146                 if self._isDestroyed:
147                         _moduleLogger.info("Download complete but window destroyed")
148                         return
149
150                 self._hide_loading()
151                 for programNode in programs:
152                         program = programNode.get_properties()
153                         img = self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["nomagazineimage"])
154                         row = programNode, img, program["title"]
155                         self._model.append(row)
156
157                         self._store.get_pixbuf_from_url(
158                                 program["pictureURL"],
159                                 self._create_on_image(programNode),
160                                 self._on_error,
161                         )
162
163                 self._select_row()
164
165         @misc_utils.log_exception(_moduleLogger)
166         def _on_error(self, exception):
167                 self._hide_loading()
168                 self._errorBanner.push_message(str(exception))
169
170         def _create_on_image(self, programNode):
171                 return lambda pix: self._on_image(programNode, pix)
172
173         @misc_utils.log_exception(_moduleLogger)
174         def _on_image(self, childNode, pix):
175                 for i, row in enumerate(self._model):
176                         if row[0] is childNode:
177                                 break
178                 else:
179                         raise RuntimeError("Could not find %r" % childNode)
180                 treeiter = self._model.iter_nth_child(None, i)
181                 self._model.set_value(treeiter, 1, pix)
182                 treeiter = self._model.iter_nth_child(None, i)
183                 self._model.row_changed((i, ), treeiter)
184
185         def _window_from_node(self, node):
186                 issuesWindow = MagazineArticlesWindow(self._app, self._player, self._store, node)
187                 issuesWindow.window.set_modal(True)
188                 issuesWindow.window.set_transient_for(self._window)
189                 issuesWindow.window.set_default_size(*self._window.get_size())
190                 issuesWindow.connect("quit", self._on_quit)
191                 issuesWindow.connect("home", self._on_home)
192                 issuesWindow.connect("jump-to", self._on_jump)
193                 issuesWindow.show()
194                 return issuesWindow
195
196
197 gobject.type_register(MagazineIssuesWindow)
198
199
200 class MagazineArticlesWindow(windows._base.ListWindow):
201
202         def __init__(self, app, player, store, node):
203                 windows._base.ListWindow.__init__(self, app, player, store, node)
204                 self._window.set_title(self._node.title)
205
206         @classmethod
207         def _get_columns(cls):
208                 yield gobject.TYPE_PYOBJECT, None
209
210                 textrenderer = gtk.CellRendererText()
211                 column = gtk.TreeViewColumn("Article")
212                 column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
213                 column.pack_start(textrenderer, expand=True)
214                 column.add_attribute(textrenderer, "markup", 1)
215                 yield gobject.TYPE_STRING, column
216
217         def _refresh(self):
218                 windows._base.ListWindow._refresh(self)
219                 self._node.get_children(
220                         self._on_magazine_articles,
221                         self._on_error,
222                 )
223
224         @misc_utils.log_exception(_moduleLogger)
225         def _on_magazine_articles(self, programs):
226                 if self._isDestroyed:
227                         _moduleLogger.info("Download complete but window destroyed")
228                         return
229
230                 self._hide_loading()
231                 for programNode in programs:
232                         program = programNode.get_properties()
233                         row = programNode, "%s\n<small>%s</small>" % (programNode.title, programNode.subtitle)
234                         self._model.append(row)
235
236                 self._select_row()
237
238         @misc_utils.log_exception(_moduleLogger)
239         def _on_error(self, exception):
240                 self._hide_loading()
241                 self._errorBanner.push_message(str(exception))
242
243         def _window_from_node(self, node):
244                 issuesWindow = MagazineArticleWindow(self._app, self._player, self._store, node)
245                 issuesWindow.window.set_modal(True)
246                 issuesWindow.window.set_transient_for(self._window)
247                 issuesWindow.window.set_default_size(*self._window.get_size())
248                 issuesWindow.connect("quit", self._on_quit)
249                 issuesWindow.connect("home", self._on_home)
250                 issuesWindow.connect("jump-to", self._on_jump)
251                 issuesWindow.show()
252                 return issuesWindow
253
254
255 gobject.type_register(MagazineArticlesWindow)
256
257
258 class MagazineArticleWindow(windows._base.PresenterWindow):
259
260         def __init__(self, app, player, store, node):
261                 windows._base.PresenterWindow.__init__(self, app, player, store, node)
262
263         def _get_background(self):
264                 return self._store.STORE_LOOKUP["magazine_background"]
265
266
267 gobject.type_register(MagazineArticleWindow)