Merge lp:~joni-noplu/moovida/moovida-dvb into lp:moovida

Proposed by Jonathan Rauprich
Status: Needs review
Proposed branch: lp:~joni-noplu/moovida/moovida-dvb
Merge into: lp:moovida
Diff against target: 872 lines (+713/-30)
14 files modified
elisa-plugins/elisa/plugins/amp/protocol.py (+1/-1)
elisa-plugins/elisa/plugins/gdvbd/controller.py (+257/-0)
elisa-plugins/elisa/plugins/gdvbd/models.py (+85/-0)
elisa-plugins/elisa/plugins/gdvbd/resource_provider.py (+264/-0)
elisa-plugins/elisa/plugins/lirc/lirc_input.py (+1/-1)
elisa-plugins/elisa/plugins/pigment/widgets/panel.py (+36/-26)
elisa-plugins/elisa/plugins/poblesec/player_video.py (+45/-2)
elisa-plugins/elisa_plugin_gdvbd.egg-info/PKG-INFO (+10/-0)
elisa-plugins/elisa_plugin_gdvbd.egg-info/controller_mappings.txt (+4/-0)
elisa-plugins/elisa_plugin_gdvbd.egg-info/decorator_mappings.txt (+3/-0)
elisa-plugins/elisa_plugin_gdvbd.egg-info/dependency_links.txt (+1/-0)
elisa-plugins/elisa_plugin_gdvbd.egg-info/entry_points.txt (+3/-0)
elisa-plugins/elisa_plugin_gdvbd.egg-info/namespace_packages.txt (+2/-0)
elisa-plugins/elisa_plugin_gdvbd.egg-info/top_level.txt (+1/-0)
To merge this branch: bzr merge lp:~joni-noplu/moovida/moovida-dvb
Reviewer Review Type Date Requested Status
Moovida Developers Pending
Review via email: mp+26379@code.launchpad.net

Description of the change

Added plugin for gnome-dvb-daemon
Added support for deinterlacing of dvb streams and recordings
Filtered message about missing teletext decoder
Converted some exceptions into warnings

To post a comment you must log in.
Revision history for this message
Olivier Tilloy (osomon) wrote :

Hi Jonathan,
Support for DVB looks like an amazing feature (I recall it being discussed extensively but resources were never allocated for implementation).
I haven't tested your code, but I have a bunch of important remarks:

1) In case you didn't know, Moovida 1.x is not supported any longer by Fluendo Embedded (see http://www.moovida.com/blog/2010/03/26/moovida-update/ and an interesting thread on the developers' mailing list: http://lists.moovida.com/pipermail/developers-list/2010-March/001804.html). Basically that means that your best bet to get your work reviewed is to count on the community. However a large part of said community is now focused on the fork (temporarily named Elisa until a better name is agreed upon: https://launchpad.net/elisa), and the ongoing efforts are focused on:
  a) Fixing the outstanding issues in the 1.0 branch to keep it usable (no new features)
  b) Brainstorming and designing for the next version

2) Your patch mixes new features (the new gdvbd plugin) and unrelated fixes, I'd advise to submit each as separate merge requests, it will ease the life of potential reviewers.

3) For the reasons detailed in 1, you probably want to submit bug fixes against lp:elisa, you'll stand a better chance to have them reviewed and merged.

4) The fix for the amp plugin is already merged in lp:elisa, see http://bazaar.launchpad.net/~elisa-developers/elisa/1.0/revision/1616

5) A fix for bug #379409 (CSS values with no units) is already pending a review, see https://code.launchpad.net/~osomon/elisa/css_property_no_unit/+merge/26369

6) There is a bug report for the issue with teletext (bug #415031). It is in general a good practice to link to existing bug reports in the merge request. Again, this will make the life of the reviewer(s) much easier.

7) Your branch is missing the setup.py script for the new gdvbd plugin. If you haven't done so yet, I encourage you to go through the good practices detailed in the developers' guide at http://www.moovida.com/documentation/developers_guide/developers_guide.html

8) The plugin shouldn't be merged in elisa/moovida's tree: it is preferable to create a standalone project in Launchpad to host its code, track its issues separately and release it in an independent manner. This project should be declared as part of the Moovida Universe meta-project (https://launchpad.net/moovida-universe).

9) The change to the LIRC plugin seems unrelated, and in any case should be carefully explained, because it touches a sensitive piece of code.

Thanks for reading patiently my remarks! Some of them might sound picky, but please know that your effort is valued, as a former core developer on the project it is very rewarding to see such cool contributions coming in. If you're interested in the fork, drop by on irc://freenode.net/#elisa, there's always someone hanging around there.

Revision history for this message
Jonathan Rauprich (joni-noplu) wrote :
Download full text (4.4 KiB)

Hi Oliver,

thanks for the reply.

1) I read that Fluendo switch to Banshee for Moovida 2.0, and searched
for a fork but didn't found it. Maybe you could announce it anywhere?

2) The fixes are unrelated agreed, but i couldn't write the plugin on
Ubuntu 10.04 with tons of exceptions in the output. Since i didn't know
u already have a fork with some bugs fixed i thought it could help.

3) true

4/5) true too, thanks for fixing it, your code for the css problem
running well here, should i make a comment about that in your merge
proposal?

6) see 8

7) I added a setup.py script, thanks for the hint.

8) Ok about that, i did only the plugin as a separate project
https://launchpad.net/elisa-gdvbd
The Problem is that using the plugin without the changes i made on the
video_player.py (teletext issue and deinterlacing support) isn't funny
(at least here in Germany where we have DVB streams interlaced and with
teletext). For the teletext issue i can publish a patch and relate it to
the bug, and for deinterlacing support i write a new bug report, is that
the correct solution?

9) Strange none else got issues with the lirc plugin (at least i found
no bug report). On my machine its not working without that change, maybe
its because i am using inputlirc
( http://www.realh.co.uk/dvbhowto/ar01s08.html ) instead of lirc, I'll
try to track the problem and write a bug report.

I'm pretty new to launchpad and bzr and i din't fully understand the way
development is working there, so thanks again for the help.

greets

joni

On Sun, 2010-05-30 at 17:13 +0000, Olivier Tilloy wrote:
> Hi Jonathan,
> Support for DVB looks like an amazing feature (I recall it being discussed extensively but resources were never allocated for implementation).
> I haven't tested your code, but I have a bunch of important remarks:
>
> 1) In case you didn't know, Moovida 1.x is not supported any longer by Fluendo Embedded (see http://www.moovida.com/blog/2010/03/26/moovida-update/ and an interesting thread on the developers' mailing list: http://lists.moovida.com/pipermail/developers-list/2010-March/001804.html). Basically that means that your best bet to get your work reviewed is to count on the community. However a large part of said community is now focused on the fork (temporarily named Elisa until a better name is agreed upon: https://launchpad.net/elisa), and the ongoing efforts are focused on:
> a) Fixing the outstanding issues in the 1.0 branch to keep it usable (no new features)
> b) Brainstorming and designing for the next version
>
> 2) Your patch mixes new features (the new gdvbd plugin) and unrelated fixes, I'd advise to submit each as separate merge requests, it will ease the life of potential reviewers.
>
> 3) For the reasons detailed in 1, you probably want to submit bug fixes against lp:elisa, you'll stand a better chance to have them reviewed and merged.
>
> 4) The fix for the amp plugin is already merged in lp:elisa, see http://bazaar.launchpad.net/~elisa-developers/elisa/1.0/revision/1616
>
> 5) A fix for bug #379409 (CSS values with no units) is already pending a review, see https://code.launchpad.net/~osomon/elisa/css_property_no_unit/+merge/26369
>
> 6)...

Read more...

Revision history for this message
Jonathan Rauprich (joni-noplu) wrote :

Another short question: Should i delete this proposal?

On Sun, 2010-05-30 at 17:13 +0000, Olivier Tilloy wrote:
> Hi Jonathan,
> Support for DVB looks like an amazing feature (I recall it being discussed extensively but resources were never allocated for implementation).
> I haven't tested your code, but I have a bunch of important remarks:
>
> 1) In case you didn't know, Moovida 1.x is not supported any longer by Fluendo Embedded (see http://www.moovida.com/blog/2010/03/26/moovida-update/ and an interesting thread on the developers' mailing list: http://lists.moovida.com/pipermail/developers-list/2010-March/001804.html). Basically that means that your best bet to get your work reviewed is to count on the community. However a large part of said community is now focused on the fork (temporarily named Elisa until a better name is agreed upon: https://launchpad.net/elisa), and the ongoing efforts are focused on:
> a) Fixing the outstanding issues in the 1.0 branch to keep it usable (no new features)
> b) Brainstorming and designing for the next version
>
> 2) Your patch mixes new features (the new gdvbd plugin) and unrelated fixes, I'd advise to submit each as separate merge requests, it will ease the life of potential reviewers.
>
> 3) For the reasons detailed in 1, you probably want to submit bug fixes against lp:elisa, you'll stand a better chance to have them reviewed and merged.
>
> 4) The fix for the amp plugin is already merged in lp:elisa, see http://bazaar.launchpad.net/~elisa-developers/elisa/1.0/revision/1616
>
> 5) A fix for bug #379409 (CSS values with no units) is already pending a review, see https://code.launchpad.net/~osomon/elisa/css_property_no_unit/+merge/26369
>
> 6) There is a bug report for the issue with teletext (bug #415031). It is in general a good practice to link to existing bug reports in the merge request. Again, this will make the life of the reviewer(s) much easier.
>
> 7) Your branch is missing the setup.py script for the new gdvbd plugin. If you haven't done so yet, I encourage you to go through the good practices detailed in the developers' guide at http://www.moovida.com/documentation/developers_guide/developers_guide.html
>
> 8) The plugin shouldn't be merged in elisa/moovida's tree: it is preferable to create a standalone project in Launchpad to host its code, track its issues separately and release it in an independent manner. This project should be declared as part of the Moovida Universe meta-project (https://launchpad.net/moovida-universe).
>
> 9) The change to the LIRC plugin seems unrelated, and in any case should be carefully explained, because it touches a sensitive piece of code.
>
> Thanks for reading patiently my remarks! Some of them might sound picky, but please know that your effort is valued, as a former core developer on the project it is very rewarding to see such cool contributions coming in. If you're interested in the fork, drop by on irc://freenode.net/#elisa, there's always someone hanging around there.

Revision history for this message
Olivier Tilloy (osomon) wrote :

> 1) I read that Fluendo switch to Banshee for Moovida 2.0, and searched
> for a fork but didn't found it. Maybe you could announce it anywhere?

The reason it hasn't been announced very visibly is that we don't have anything to show off yet, merely a forked branch with a couple of patches in it.

> 4/5) true too, thanks for fixing it, your code for the css problem
> running well here, should i make a comment about that in your merge
> proposal?

Please do!

> 8) Ok about that, i did only the plugin as a separate project
> https://launchpad.net/elisa-gdvbd
> The Problem is that using the plugin without the changes i made on the
> video_player.py (teletext issue and deinterlacing support) isn't funny
> (at least here in Germany where we have DVB streams interlaced and with
> teletext). For the teletext issue i can publish a patch and relate it to
> the bug, and for deinterlacing support i write a new bug report, is that
> the correct solution?

Yes, definitely the way to go about those issues.

> 9) Strange none else got issues with the lirc plugin (at least i found
> no bug report). On my machine its not working without that change, maybe
> its because i am using inputlirc
> ( http://www.realh.co.uk/dvbhowto/ar01s08.html ) instead of lirc, I'll
> try to track the problem and write a bug report.

Cool. The LIRC plugin is a delicate beast, usually a fix for a set of configurations is likely to break for another set of configurations, which is why a change needs a solid justification, so your investigation will be welcome.

> I'm pretty new to launchpad and bzr and i din't fully understand the way
> development is working there, so thanks again for the help.

No problem! Thanks for your contributions.

> Another short question: Should i delete this proposal?

No need to do this, it can remain here for reference.

Unmerged revisions

1619. By Jonathan Rauprich

DVB plugin done now.
Support for basic deinterlacing of TV stuff in play_video.py
Doesn't show message about not finding a teletext decoder.

1618. By Jonathan Rauprich

Support for EPG program guide and recordings. Code needs to be cleaned
up, documentated, and made nicer, but features working so far.

1617. By Jonathan Rauprich <joni@bb>

Fixed bug in lirc module.
Added initial dvb support.
Added initial recording support.

1616. By Jonathan Rauprich <joni@bb>

Convertet some exceptions to warnings, since they dosn't seem to make things bad

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'elisa-plugins/elisa/plugins/amp/protocol.py'
--- elisa-plugins/elisa/plugins/amp/protocol.py 2009-11-09 15:44:51 +0000
+++ elisa-plugins/elisa/plugins/amp/protocol.py 2010-05-30 10:34:24 +0000
@@ -106,7 +106,7 @@
106 if diff < self.ping_period:106 if diff < self.ping_period:
107 return107 return
108108
109 dfr = self.callRemote(Ping, cookie=self._cookie)109 dfr = self.callRemote(Ping)
110 self._startTimeout()110 self._startTimeout()
111 dfr.addCallback(self._pingCb)111 dfr.addCallback(self._pingCb)
112 dfr.addErrback(self._pingEb)112 dfr.addErrback(self._pingEb)
113113
=== added directory 'elisa-plugins/elisa/plugins/gdvbd'
=== added file 'elisa-plugins/elisa/plugins/gdvbd/__init__.py'
=== added file 'elisa-plugins/elisa/plugins/gdvbd/controller.py'
--- elisa-plugins/elisa/plugins/gdvbd/controller.py 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa/plugins/gdvbd/controller.py 2010-05-30 10:34:24 +0000
@@ -0,0 +1,257 @@
1from elisa.core.utils import defer
2from elisa.core.utils.i18n import install_translation
3
4from elisa.core.media_uri import MediaUri
5from elisa.core.common import application
6
7from elisa.plugins.poblesec.base.preview_list import \
8 DoubleLineMenuItemPreviewListController, SimpleListController
9from elisa.plugins.poblesec.base.list import GenericListViewMode
10from elisa.plugins.poblesec.actions import OpenControllerActionWithItem, \
11 ContextualAction
12from elisa.plugins.database.actions import PlayVideoAction
13
14from elisa.plugins.poblesec.link import Link
15
16from datetime import datetime
17
18_ = install_translation('gdvbd')
19_p = install_translation('poblesec')
20
21def timestamp_to_day_time(timestamp):
22 d = datetime.fromtimestamp(timestamp)
23 return d.strftime('%a %H:%M')
24
25def channels_decorator(controller):
26 link = Link()
27 link.controller_path = '/gdvbd/devicegroups'
28 link.label = _('TV Stations')
29 controller.model.append(link)
30 return defer.succeed(None)
31
32def recordings_decorator(controller):
33 link = Link()
34 link.controller_path = '/gdvbd/recordings'
35 link.label = _('Recordings')
36 controller.model.append(link)
37 return defer.succeed(None)
38
39class OpenControllerActionWithItemAndName(OpenControllerActionWithItem):
40 def __init__(self, controller, path):
41 return super(OpenControllerActionWithItemAndName, self).__init__(\
42 controller, path)
43
44 def execute(self, item):
45 self._kwargs['item'] = item
46 return self.open_controller(self.path, item.name, **self._kwargs)
47
48class DeviceGroupViewMode(GenericListViewMode):
49 """
50 Implementation of the common view modes API.
51 """
52 def get_label(self, item):
53 return defer.succeed(item.name)
54
55 def get_sublabel(self, item):
56 return defer.succeed("")
57
58 def get_default_image(self, item):
59 return 'elisa.plugins.poblesec.glyphs.small.video'
60
61 def get_image(self, item, theme):
62 return None
63
64 def get_preview_image(self, item, theme):
65 return None
66
67class ScheduleViewMode(GenericListViewMode):
68 """
69 Implementation of the common view modes API.
70 """
71 def get_label(self, item):
72 return defer.succeed("%s: %s" % (timestamp_to_day_time(\
73 item.start_timestamp), item.name))
74
75 def get_sublabel(self, item):
76 return defer.succeed(item.short_description)
77
78 def get_default_image(self, item):
79 return 'elisa.plugins.poblesec.glyphs.small.video'
80
81 def get_image(self, item, theme):
82 return None
83
84 def get_preview_image(self, item, theme):
85 return None
86
87class ChannelViewMode(GenericListViewMode):
88 """
89 Implementation of the common view modes API.
90 """
91 def get_label(self, item):
92 if len(item.network) > 0:
93 return defer.succeed("%s (%s)" % (item.name, item.network))
94 else:
95 return defer.succeed("%s" % item.name)
96
97 def get_sublabel(self, item):
98 if len(item.now_playing_name) > 0:
99 return defer.succeed("%s %s" % (timestamp_to_day_time(
100 item.now_playing_start_timestamp), item.now_playing_name))
101 else:
102 return defer.succeed("")
103
104
105 def get_default_image(self, item):
106 if item.is_radio_channel:
107 return 'elisa.plugins.poblesec.glyphs.small.music'
108 return 'elisa.plugins.poblesec.glyphs.small.video'
109
110 def get_image(self, item, theme):
111 return None
112
113 def get_preview_image(self, item, theme):
114 return None
115
116class RecordingViewMode(GenericListViewMode):
117 """
118 Implementation of the common view modes API.
119 """
120 def get_label(self, item):
121 return defer.succeed(item.name)
122
123 def get_sublabel(self, item):
124 return defer.succeed("%s %s %d min" % (item.channel_name, \
125 timestamp_to_day_time(item.start_timestamp), item.length/60))
126
127 def get_default_image(self, item):
128 return 'elisa.plugins.poblesec.glyphs.small.video'
129
130 def get_image(self, item, theme):
131 return None
132
133 def get_preview_image(self, item, theme):
134 return None
135
136class RecordScheduleAction(ContextualAction):
137 name = "more"
138
139 def execute(self, item):
140 def _close():
141 main_controller.hide_popup()
142
143 def _record():
144 muri = MediaUri("gdvbd://device-group/%d/channel/%d/schedule/%d" % \
145 (self.controller.dg_id, self.controller.ch_id, item.id))
146 application.resource_manager.post(muri)
147 main_controller.hide_popup()
148
149 frontend = self.controller.frontend
150 main_controller = frontend.controller
151 caption = _('Record %s' % item.name )
152 title = caption
153
154 text = _('%s Duration: %d min.' % (item.extended_description, \
155 item.duration/60))
156 buttons = [
157 (_('Record this'), _record),
158 (_('Close'), _close)
159 ]
160 return defer.succeed(main_controller.enqueue_popup(caption, \
161 title, text, buttons))
162
163class DeleteRecordingAction(ContextualAction):
164 name = "remove"
165
166 def execute(self, item):
167 def _close():
168 main_controller.hide_popup()
169
170 def _delete():
171 muri = MediaUri("gdvbd://recording/%d" % item.id)
172 application.resource_manager.delete(muri)
173 self.controller.model.remove(item)
174 main_controller.hide_popup()
175
176 frontend = self.controller.frontend
177 main_controller = frontend.controller
178 caption = _('%s' % item.name )
179 title = caption
180
181 text = _('You sure u want to delete this recording?')
182 buttons = [
183 (_('Delete it'), _delete),
184 (_('Close'), _close)
185 ]
186 return defer.succeed(main_controller.enqueue_popup(caption, \
187 title, text, buttons))
188
189class DeviceGroupController(DoubleLineMenuItemPreviewListController):
190 view_mode = DeviceGroupViewMode
191 empty_label = _('No registered device groups found.')
192 item_widget_kwargs = {'with_artwork_box': False}
193
194 def populate_model(self):
195 muri = MediaUri("gdvbd://device-group/list")
196 model, dfr = application.resource_manager.get(muri)
197 return dfr
198
199 def create_actions(self):
200 to_channels = OpenControllerActionWithItemAndName(self, \
201 '/gdvbd/channels')
202 return (to_channels, [])
203
204class ChannelsController(DoubleLineMenuItemPreviewListController):
205 view_mode = ChannelViewMode
206 empty_label = _('No Stations found.')
207
208 def initialize(self, item):
209 self.dg_id = item.id
210 return super(ChannelsController, self).initialize()
211
212 def populate_model(self):
213 muri = MediaUri("gdvbd://device-group/%d/channel/list" % self.dg_id)
214 model, dfr = application.resource_manager.get(muri)
215 return dfr
216
217 def create_actions(self):
218 play_tv = PlayVideoAction(self)
219 show_epg = OpenControllerActionWithItemAndName(self, '/gdvbd/schedule')
220 show_epg.name = "list"
221 return (play_tv, [show_epg])
222
223class ScheduleController(DoubleLineMenuItemPreviewListController):
224 view_mode = ScheduleViewMode
225 empty_label = _("There is currently no schedule available for this channel")
226
227 def initialize(self, item):
228 self.ch_id = item.id
229 self.dg_id = item.device_group.id
230 return super(ScheduleController, self).initialize()
231
232 def populate_model(self):
233 muri = MediaUri("gdvbd://device-group/%d/channel/%d/schedule/list" % \
234 (self.dg_id, self.ch_id))
235 model, dfr = application.resource_manager.get(muri)
236 return dfr
237
238 def create_actions(self):
239 record_item = RecordScheduleAction(self)
240 return (record_item, [])
241
242class RecordingController(DoubleLineMenuItemPreviewListController):
243 view_mode = RecordingViewMode
244 item_widget_kwargs = {'with_artwork_box': False}
245
246 empty_label = _("There is currently no recording available")
247
248 def populate_model(self):
249 muri = MediaUri("gdvbd://recording/list")
250 model, dfr = application.resource_manager.get(muri)
251 return dfr
252
253 def create_actions(self):
254 play_recording = PlayVideoAction(self)
255 delete_recording = DeleteRecordingAction(self)
256 return (play_recording, [delete_recording])
257
0258
=== added directory 'elisa-plugins/elisa/plugins/gdvbd/i18n'
=== added file 'elisa-plugins/elisa/plugins/gdvbd/i18n/__init__.py'
=== added directory 'elisa-plugins/elisa/plugins/gdvbd/icons'
=== added file 'elisa-plugins/elisa/plugins/gdvbd/icons/icon1.png'
1Binary files elisa-plugins/elisa/plugins/gdvbd/icons/icon1.png 1970-01-01 00:00:00 +0000 and elisa-plugins/elisa/plugins/gdvbd/icons/icon1.png 2010-05-30 10:34:24 +0000 differ259Binary files elisa-plugins/elisa/plugins/gdvbd/icons/icon1.png 1970-01-01 00:00:00 +0000 and elisa-plugins/elisa/plugins/gdvbd/icons/icon1.png 2010-05-30 10:34:24 +0000 differ
=== added file 'elisa-plugins/elisa/plugins/gdvbd/icons/icon2.png'
2Binary files elisa-plugins/elisa/plugins/gdvbd/icons/icon2.png 1970-01-01 00:00:00 +0000 and elisa-plugins/elisa/plugins/gdvbd/icons/icon2.png 2010-05-30 10:34:24 +0000 differ260Binary files elisa-plugins/elisa/plugins/gdvbd/icons/icon2.png 1970-01-01 00:00:00 +0000 and elisa-plugins/elisa/plugins/gdvbd/icons/icon2.png 2010-05-30 10:34:24 +0000 differ
=== added file 'elisa-plugins/elisa/plugins/gdvbd/models.py'
--- elisa-plugins/elisa/plugins/gdvbd/models.py 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa/plugins/gdvbd/models.py 2010-05-30 10:34:24 +0000
@@ -0,0 +1,85 @@
1# -*- coding: utf-8 -*-
2#
3# This file is licensed under the GPL version 3.
4# See "LICENSE.GPL" in the root of this distribution including a special
5# exception to use Moovida with Fluendo's plugins.
6#
7# Author: Jonathan Rauprich <joni@noplu.de>
8
9from elisa.core.utils import defer
10from elisa.core.components.model import Model
11from elisa.plugins.base.models.media import PlayableModel
12from elisa.core.media_uri import MediaUri
13
14class DeviceGroupModel(Model):
15 def __init__(self):
16 """
17 Constructor. Initialize all the fields.
18 """
19 super(DeviceGroupModel, self).__init__()
20 self.id = None
21 self.name = None
22 self.client = None
23 self.recorder = None
24 self.channel_list = None
25
26class ChannelModel(Model):
27 def __init__(self):
28 """
29 Constructor. Initialize all the fields.
30 """
31 super(ChannelModel, self).__init__()
32 self.id = None
33 self.name = None
34 self.network = None
35 self.is_radio_channel = None
36 self.url = None
37 self.device_group = None
38 self.now_playing_name = None
39 self.now_playing_start_timestamp = None
40
41 def get_playable_model(self):
42 playable_model = PlayableModel()
43 playable_model.title = self.name
44 playable_model.uri = MediaUri(self.url)
45 playable_model.do_deinterlace = True
46 return defer.succeed(playable_model)
47
48
49class ScheduleModel(Model):
50 def __init__(self):
51 """
52 Constructor. Initialize all the fields.
53 """
54 super(ScheduleModel, self).__init__()
55 self.id = None
56 self.name = None
57 self.short_description = None
58 self.extended_description = None
59 self.duration = None
60 self.start_time = None
61 self.start_timestamp = None
62 self.is_running = None
63 self.is_scrambled = None
64
65class RecordingModel(Model):
66 def __init__(self):
67 """
68 Constructor. Initialize all the fields.
69 """
70 super(RecordingModel, self).__init__()
71 self.id = None
72 self.name = None
73 self.location = None
74 self.description = None
75 self.length = None
76 self.start_time = None
77 self.start_timestamp = None
78 self.channel_name = None
79
80 def get_playable_model(self):
81 playable_model = PlayableModel()
82 playable_model.title = self.name
83 playable_model.uri = MediaUri("file://%s" % self.location)
84 playable_model.do_deinterlace = True
85 return defer.succeed(playable_model)
086
=== added file 'elisa-plugins/elisa/plugins/gdvbd/resource_provider.py'
--- elisa-plugins/elisa/plugins/gdvbd/resource_provider.py 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa/plugins/gdvbd/resource_provider.py 2010-05-30 10:34:24 +0000
@@ -0,0 +1,264 @@
1# -*- coding: utf-8 -*-
2#
3# This file is licensed under the GPL version 3.
4# See "LICENSE.GPL" in the root of this distribution including a special
5# exception to use Moovida with Fluendo's plugins.
6#
7# Author: Jonathan Rauprich <joni@noplu.de>
8
9"""
10Provide access to resources served by gnome-dvb-daemon over DBUS.
11"""
12
13from elisa.core.components.resource_provider import ResourceProvider, \
14 ResourceNotFound
15from elisa.plugins.gdvbd.models import DeviceGroupModel, ChannelModel, \
16 ScheduleModel, RecordingModel
17from elisa.core.utils import defer
18
19from gnomedvb import DVBManagerClient, DVBRecordingsStoreClient
20import re
21
22
23
24class GdvbdResourceProvider(ResourceProvider):
25 """
26 Implements REST access to gnome-dvb-daemon, with simple urls.
27
28 The interresting part of the gnome-dvb-daemon is like the following:
29
30 gdvbd
31 |-> Device Groups
32 | |-> Device Group 1
33 | | |-> Channel List
34 | | | |-> Channel 1
35 | | | | |-> schedule
36 | | | |-> Channel 2
37 | | | | |-> ...
38 | |-> Device Group 2
39 | | |-> ....
40 |-> Recordings
41 | |-> Recording 1
42 | |-> Recording 2
43 | |-> ....
44
45 This REST implementation allows u the following actions
46
47 GET gdvbd://device-group/list
48 Return list of device groups
49 GET gdvbd://device-group/<GROUP_ID>/channel/list
50 Return list of channels for device group
51 GET gdvbd://device-group/<GROUP_ID>/channel/<CHANNEL_ID>/schedule/list
52 Return list of schedules for channel
53 GET gdvbd://recording/list
54 Returns a list of recordings
55
56 POST gdvbd://device-group/<GROUP_ID>/channel/<CHANNEL_ID>/schedule/<schedule_ID>
57 Recording the schedule on the channel
58
59 DELETE gdvbd://recording/<RECORDING_ID>
60 Delete the recording
61 """
62
63 base_uri = "gdvbd://"
64 dev_groups = "%sdevice-group/list" % base_uri
65 dev_groups_re = re.compile(dev_groups)
66 channel_list = "%sdevice-group/(\d*)/channel/list" % base_uri
67 channel_list_re = re.compile(channel_list)
68 schedule_list = "%sdevice-group/(\d*)/channel/(\d*)/schedule/list" % base_uri
69 schedule_list_re = re.compile(schedule_list)
70 recording_list = "%srecording/list" % base_uri
71 recording_list_re = re.compile(recording_list)
72 create_recording = "%sdevice-group/(\d*)/channel/(\d*)/schedule/(\d*)" \
73 % base_uri
74 create_recording_re = re.compile(create_recording)
75 delete_recording = "%srecording/(\d*)" % base_uri
76 delete_recording_re = re.compile(delete_recording)
77
78 supported_uri = dev_groups + "|" + channel_list + "|" + schedule_list + "|" \
79 + recording_list + "|" + create_recording + "|" + delete_recording
80
81 RELOAD_TIME = 300.0
82
83 def initialize(self):
84 """
85 Init the data stucture and register callbacks, but since this is
86 taking a time, do it threaded.
87 """
88 dfr = super(GdvbdResourceProvider, self).initialize()
89 # get a manager
90 self.manager = DVBManagerClient()
91 self.recorder = DVBRecordingsStoreClient()
92 # load device groups, also do that if they change
93 self._init_dgs()
94 self.manager.connect("group-added", self._init_dgs)
95 self.manager.connect("group-removed", self._init_dgs)
96 self._init_recordings()
97 self.recorder.connect("changed", self._init_recordings)
98 return dfr
99
100 def _init_dgs(self, *args):
101 self.device_groups = []
102 for device_group in self.manager.get_registered_device_groups():
103 dgmodel = self._create_dg_model(device_group)
104 self.device_groups.append(dgmodel)
105
106 def _init_recordings(self, *args):
107 self.recordings = []
108 for rid in self.recorder.get_recordings():
109 #informations -> 0 -> rid # 1 -> title # 2 -> description
110 # 3 -> length # 4 -> start_timestamp # 5 -> channel_name
111 # 6 -> location
112 (informations, success) = self.recorder.get_all_informations(rid)
113 if success:
114 rmodel = RecordingModel()
115 rmodel.id = rid
116 rmodel.name = informations[1]
117 rmodel.description = informations[2]
118 rmodel.length = informations[3]
119 rmodel.start_timestamp = informations[4]
120 rmodel.channel_name = informations[5]
121 rmodel.location = informations[6]
122 (start_time, success) = self.recorder.get_start_time(rid)
123 if success:
124 rmodel.start_time = start_time
125 self.recordings.append(rmodel)
126
127
128 def _create_dg_model(self, device_group):
129 dgmodel = DeviceGroupModel()
130 dgmodel.id = device_group.get_id()
131 dgmodel.name = device_group.get_name()
132 dgmodel.client = device_group
133 dgmodel.recorder = device_group.get_recorder()
134 dgmodel.channels = []
135 dgmodel.channel_list = device_group.get_channel_list()
136 return dgmodel
137
138 def _create_chan_model(self, cid, cl):
139 cm = ChannelModel()
140 cm.id = cid
141 (name, success) = cl.get_channel_name(cid)
142 if success:
143 cm.name = name
144 (network, success) = cl.get_channel_network(cid)
145 if success:
146 cm.network = network
147 (is_radio_channel, success) = cl.is_radio_channel(cid)
148 if success:
149 cm.is_radio_channel = is_radio_channel
150 (url, success) = cl.get_channel_url(cid)
151 if success:
152 cm.url = url
153 return cm
154
155 def _create_schedule(self, dg, cid):
156 shed = dg.client.get_schedule(cid)
157 schedule = []
158 for eid in shed.get_all_events():
159 smodel = ScheduleModel()
160 smodel.id = eid
161 (name, success) = shed.get_name(eid)
162 if success:
163 smodel.name = name
164 (short_description, success) = shed.get_short_description(eid)
165 if success:
166 smodel.short_description = short_description
167 (extended_description, success) = shed.get_extended_description(eid)
168 if success:
169 smodel.extended_description = extended_description
170 (duration, success) = shed.get_duration(eid)
171 if success:
172 smodel.duration = duration
173 (start_time, success) = shed.get_local_start_time(eid)
174 if success:
175 smodel.start_time = start_time
176 (start_timestamp, success) = shed.get_local_start_timestamp(eid)
177 if success:
178 smodel.start_timestamp = start_timestamp
179 (is_running, success) = shed.is_running(eid)
180 if success:
181 smodel.is_running = is_running
182 (is_scrambled, success) = shed.is_scrambled(eid)
183 if success:
184 smodel.is_scrambled = is_scrambled
185 schedule.append(smodel)
186 return schedule
187
188 def _get_dg_for_dgid(self, dgid):
189 for dg in self.device_groups:
190 if dg.id == dgid:
191 return dg
192 return None
193
194
195 def get(self, uri, context_model=None):
196 url = str(uri)
197
198 m = self.dev_groups_re.match(url)
199 if m:
200 self._init_dgs()
201 return (self.device_groups, defer.succeed(self.device_groups))
202
203 m = self.channel_list_re.match(url)
204 if m:
205 dg = self._get_dg_for_dgid(int(m.group(1)))
206 if dg:
207 channels = []
208 for cid in dg.client.get_channel_list().get_channels():
209 chmodel = self._create_chan_model(cid, dg.channel_list)
210 chmodel.device_group = dg
211 # Look whats on now
212 shed = dg.client.get_schedule(chmodel.id)
213 now = shed.now_playing()
214 (chmodel.now_playing_name, success) = shed.get_name(now)
215 (chmodel.now_playing_start_timestamp, success) = shed.\
216 get_local_start_timestamp(now)
217 channels.append(chmodel)
218 return (channels, defer.succeed(channels))
219 return (None, defer.fail(ResourceNotFound()))
220
221 m = self.schedule_list_re.match(url)
222 if m:
223
224 dg = self._get_dg_for_dgid(int(m.group(1)))
225 if dg:
226 schedule = self._create_schedule(dg, int(m.group(2)))
227 return (schedule, defer.succeed(schedule))
228 return (None, defer.fail(ResourceNotFound()))
229
230 m = self.recording_list_re.match(url)
231 if m:
232 return (self.recordings, defer.succeed(self.recordings))
233
234 return (None, defer.fail(ResourceNotFound()))
235
236 def delete(self, uri):
237 url = str(uri)
238 m = self.delete_recording_re.match(url)
239 if m:
240 if self.recorder.delete(int(m.group(1))) == 1:
241 return defer.succeed(None)
242 return defer.fail(ResourceNotFound())
243
244 def post(self, uri, **parameters):
245 url = str(uri)
246 m = self.create_recording_re.match(url)
247 if m:
248 dg = self._get_dg_for_dgid(int(m.group(1)))
249 (rec_id, success) = dg.recorder.add_timer_for_epg_event(
250 int(m.group(3)), int(m.group(2)))
251 if success:
252 return defer.succeed(None)
253 return defer.fail(ResourceNotFound())
254
255
256
257
258
259
260
261
262
263
264
0265
=== modified file 'elisa-plugins/elisa/plugins/lirc/lirc_input.py'
--- elisa-plugins/elisa/plugins/lirc/lirc_input.py 2009-11-09 15:44:51 +0000
+++ elisa-plugins/elisa/plugins/lirc/lirc_input.py 2010-05-30 10:34:24 +0000
@@ -141,7 +141,7 @@
141141
142 def _got_event(self, hex_key, repeat, key_value, remote):142 def _got_event(self, hex_key, repeat, key_value, remote):
143 now = time.time()143 now = time.time()
144 if repeat != '00':144 if repeat != '0':
145 # If the remote sends a repeat signal, ie. repeat different from 00145 # If the remote sends a repeat signal, ie. repeat different from 00
146 elapsed_since_first_event = now - self._first_event_time146 elapsed_since_first_event = now - self._first_event_time
147 elapsed_since_last_repeat = now - self._last_repeat_time147 elapsed_since_last_repeat = now - self._last_repeat_time
148148
=== modified file 'elisa-plugins/elisa/plugins/pigment/widgets/panel.py'
--- elisa-plugins/elisa/plugins/pigment/widgets/panel.py 2009-11-17 22:55:46 +0000
+++ elisa-plugins/elisa/plugins/pigment/widgets/panel.py 2010-05-30 10:34:24 +0000
@@ -14,6 +14,8 @@
14# See "LICENSE.Moovida" in the root directory of this distribution package14# See "LICENSE.Moovida" in the root directory of this distribution package
15# for details on that license.15# for details on that license.
1616
17from elisa.core import log
18
17from elisa.plugins.pigment.graph.node import Node19from elisa.plugins.pigment.graph.node import Node
18from elisa.plugins.pigment.graph.image import Image20from elisa.plugins.pigment.graph.image import Image
19from elisa.plugins.pigment.graph import keysyms21from elisa.plugins.pigment.graph import keysyms
@@ -210,37 +212,45 @@
210 self.bottom_right.set_position(x, y, az)212 self.bottom_right.set_position(x, y, az)
211213
212 def _compute_border_sizes(self):214 def _compute_border_sizes(self):
213 fx, fy = self.get_factors_absolute(self.left_width.unit)215 try:
214 self._left_width = fx*self.left_width.value216 fx, fy = self.get_factors_absolute(self.left_width.unit)
215217 self._left_width = fx*self.left_width.value
216 fx, fy = self.get_factors_absolute(self.right_width.unit)218
217 self._right_width = fx*self.right_width.value219 fx, fy = self.get_factors_absolute(self.right_width.unit)
218220 self._right_width = fx*self.right_width.value
219 fx, fy = self.get_factors_absolute(self.top_height.unit)221
220 self._top_height = fy*self.top_height.value222 fx, fy = self.get_factors_absolute(self.top_height.unit)
221223 self._top_height = fy*self.top_height.value
222 fx, fy = self.get_factors_absolute(self.bottom_height.unit)224
223 self._bottom_height = fy*self.bottom_height.value225 fx, fy = self.get_factors_absolute(self.bottom_height.unit)
224 self._sizes_computed = True226 self._bottom_height = fy*self.bottom_height.value
227
228 self._sizes_computed = True
229
230 except AttributeError as e:
231 log.warning('panel', e.message)
225232
226 def _update_size(self):233 def _update_size(self):
227 if not self.is_mapped:234 if not self.is_mapped:
228 return235 return
229 self._compute_border_sizes()236 self._compute_border_sizes()
230 self.top_left.set_size(self._left_width, self._top_height)237
231 self.top_right.set_size(self._right_width, self._top_height)238 try:
232 self.bottom_left.set_size(self._left_width, self._bottom_height)239 self.top_left.set_size(self._left_width, self._top_height)
233 self.bottom_right.set_size(self._right_width, self._bottom_height)240 self.top_right.set_size(self._right_width, self._top_height)
234241 self.bottom_left.set_size(self._left_width, self._bottom_height)
235 self._middle_width = self.absolute_width - self._left_width - self._right_width242 self.bottom_right.set_size(self._right_width, self._bottom_height)
236 self._middle_height = self.absolute_height - self._top_height - self._bottom_height243
237244 self._middle_width = self.absolute_width - self._left_width - self._right_width
238 self.top_middle.set_size(self._middle_width, self._top_height)245 self._middle_height = self.absolute_height - self._top_height - self._bottom_height
239 self.middle_left.set_size(self._left_width, self._middle_height)246
240 self.middle_middle.set_size(self._middle_width, self._middle_height)247 self.top_middle.set_size(self._middle_width, self._top_height)
241 self.middle_right.set_size(self._right_width, self._middle_height)248 self.middle_left.set_size(self._left_width, self._middle_height)
242 self.bottom_middle.set_size(self._middle_width, self._bottom_height)249 self.middle_middle.set_size(self._middle_width, self._middle_height)
243250 self.middle_right.set_size(self._right_width, self._middle_height)
251 self.bottom_middle.set_size(self._middle_width, self._bottom_height)
252 except AttributeError as e:
253 log.warning('panel', e.message)
244254
245255
246 @classmethod256 @classmethod
247257
=== modified file 'elisa-plugins/elisa/plugins/poblesec/player_video.py'
--- elisa-plugins/elisa/plugins/poblesec/player_video.py 2010-01-28 17:18:54 +0000
+++ elisa-plugins/elisa/plugins/poblesec/player_video.py 2010-05-30 10:34:24 +0000
@@ -489,7 +489,33 @@
489489
490 self.pgm_sink = gst.element_factory_make('pgmimagesink')490 self.pgm_sink = gst.element_factory_make('pgmimagesink')
491 self.pipeline = gst.element_factory_make('playbin')491 self.pipeline = gst.element_factory_make('playbin')
492 self.pipeline.set_property('video-sink', self.pgm_sink)492 # Here we go now and add deinteralcing support for the pipeline
493 # This is done, by adding the following pipeline as video-sink
494 #
495 # -> ffmpegcolorspace -> deinterlace -> ffmpegcolorspace -> pgmimagesink
496 # csc1 deinterlacde csc2 pgm_sink
497 #
498 # ffdeinterlace could do this without colorspaceconversion, but it can't
499 # be disabled that simple and has no further options
500 bin = gst.Bin("deinterlacebin")
501 csc = gst.element_factory_make("ffmpegcolorspace")
502 csc2 = gst.element_factory_make("ffmpegcolorspace")
503
504 self.deinterlace = gst.element_factory_make("deinterlace")
505 # Disable deinterlacing by default
506 self.deinterlace.set_property("mode", 2)
507
508 bin.add(csc)
509 bin.add(self.deinterlace)
510 bin.add(self.pgm_sink)
511 bin.add(csc2)
512
513 pad = csc.get_pad("sink")
514 ghostpad = gst.GhostPad("sink", pad)
515 bin.add_pad(ghostpad)
516
517 gst.element_link_many(csc, self.deinterlace, csc2, self.pgm_sink)
518 self.pipeline.set_property("video-sink", bin)
493519
494 self.status = self.STOPPED520 self.status = self.STOPPED
495 self.target_status = self.STOPPED521 self.target_status = self.STOPPED
@@ -654,7 +680,12 @@
654 details = caps.to_string().split(', ')680 details = caps.to_string().split(', ')
655 mimetype = details[0]681 mimetype = details[0]
656 decoder = pbutils.get_decoder_description(mimetype)682 decoder = pbutils.get_decoder_description(mimetype)
657 self.emit('player-missing-decoder', mimetype, decoder)683 # Gestreamer complains that teletext decoder is missing, but there
684 # is no teletext decoder and ints not realy a problem as long as u
685 # don't care for teletext. So this is to prevent the warning message
686 # poping up everytime a videostream with teletext is played.
687 if mimetype != "private/teletext":
688 self.emit('player-missing-decoder', mimetype, decoder)
658 elif message.structure.get_name() == 'redirect':689 elif message.structure.get_name() == 'redirect':
659 new_location = message.structure['new-location']690 new_location = message.structure['new-location']
660 if '://' not in new_location:691 if '://' not in new_location:
@@ -821,6 +852,18 @@
821 self.filename = model.title or model.uri.filename852 self.filename = model.title or model.uri.filename
822 self.stop()853 self.stop()
823 uri = unicode(model.uri).encode(locale_helper.gst_file_encoding())854 uri = unicode(model.uri).encode(locale_helper.gst_file_encoding())
855
856 # Here we enable deinterlacing if the model got a attribute
857 # do deinterlace set to True
858 try:
859 if model.do_deinterlace:
860 self.deinterlace.set_property("mode", 1)
861 self.debug("Enabling deinterlacing for this video")
862 else:
863 self.deinterlace.set_property("mode", 2)
864 except AttributeError:
865 self.deinterlace.set_property("mode", 2)
866
824 if uri.startswith('file://'):867 if uri.startswith('file://'):
825 # Hack to workaround the messy handling of file paths using MediaUri868 # Hack to workaround the messy handling of file paths using MediaUri
826 # objects. In various places in the code, file paths are not869 # objects. In various places in the code, file paths are not
827870
=== added directory 'elisa-plugins/elisa_plugin_gdvbd.egg-info'
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/PKG-INFO'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/PKG-INFO 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/PKG-INFO 2010-05-30 10:34:24 +0000
@@ -0,0 +1,10 @@
1Metadata-Version: 1.0
2Name: elisa-plugin-gdvbd
3Version: 0.1
4Summary: Gnome DVB Daemon Plugin
5Home-page: https://code.launchpad.net/~joni-noplu/moovida/moovida-dvb
6Author: Jonathan Rauprich
7Author-email: joni@noplu.de
8License: GPL3
9Description: Watch TV, Record Shows, View ur Recordings via gnome-dvb-daemon, now availible in moovida.
10Platform: UNKNOWN
011
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/controller_mappings.txt'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/controller_mappings.txt 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/controller_mappings.txt 2010-05-30 10:34:24 +0000
@@ -0,0 +1,4 @@
1/gdvbd/channels = elisa.plugins.gdvbd.controller:ChannelsController
2/gdvbd/devicegroups = elisa.plugins.gdvbd.controller:DeviceGroupController
3/gdvbd/schedule = elisa.plugins.gdvbd.controller:ScheduleController
4/gdvbd/recordings = elisa.plugins.gdvbd.controller:RecordingController
05
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/decorator_mappings.txt'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/decorator_mappings.txt 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/decorator_mappings.txt 2010-05-30 10:34:24 +0000
@@ -0,0 +1,3 @@
1/poblesec/tv_menu = elisa.plugins.gdvbd.controller:recordings_decorator
2/poblesec/tv_menu = elisa.plugins.gdvbd.controller:channels_decorator
3
04
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/dependency_links.txt'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/dependency_links.txt 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/dependency_links.txt 2010-05-30 10:34:24 +0000
@@ -0,0 +1,1 @@
1
02
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/entry_points.txt'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/entry_points.txt 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/entry_points.txt 2010-05-30 10:34:24 +0000
@@ -0,0 +1,3 @@
1 [elisa.core.components.resource_provider]
2 YoutubeResourceProvider = elisa.plugins.gdvbd.resource_provider:GdvbdResourceProvider
3
04
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/namespace_packages.txt'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/namespace_packages.txt 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/namespace_packages.txt 2010-05-30 10:34:24 +0000
@@ -0,0 +1,2 @@
1elisa
2elisa.plugins
03
=== added file 'elisa-plugins/elisa_plugin_gdvbd.egg-info/top_level.txt'
--- elisa-plugins/elisa_plugin_gdvbd.egg-info/top_level.txt 1970-01-01 00:00:00 +0000
+++ elisa-plugins/elisa_plugin_gdvbd.egg-info/top_level.txt 2010-05-30 10:34:24 +0000
@@ -0,0 +1,1 @@
1elisa

Subscribers

People subscribed via source and target branches