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