1
# -*- coding: utf-8 -*-
2
# Moovida - Home multimedia server
3
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
6
# This file is available under one of two license agreements.
8
# This file is licensed under the GPL version 3.
9
# See "LICENSE.GPL" in the root of this distribution including a special
10
# exception to use Moovida with Fluendo's plugins.
12
# The GPL part of Moovida is also available under a commercial licensing
13
# agreement from Fluendo.
14
# See "LICENSE.Moovida" in the root directory of this distribution package
15
# for details on that license.
17
# Authors: Guillaume Emont <guillaume@fluendo.com>
19
from elisa.core import common
20
from elisa.core.utils import defer
21
from elisa.core.utils.i18n import install_translation
22
from elisa.core.media_uri import MediaUri
23
from elisa.plugins.base.messages.device import NewDeviceDetected, \
25
from elisa.plugins.base.models.device import DeviceModel
27
from elisa.plugins.dvd.actions import PlayDvdAction, EjectDvdAction, \
28
PlayPhysicalDvdAction, PlayVideoTsAction, PlayDvdIsoAction
30
_ = install_translation('dvd')
33
class SectionDecorator(object):
34
uri = MediaUri("volumes://?filter=dvd")
36
def __init__(self, controller):
37
super(SectionDecorator, self).__init__()
38
self.controller = controller
39
self.bus = common.application.bus
41
self._use_long_names = False
42
self._notifier_ids = []
45
id = self.controller.model.notifier.connect('items-inserted',
46
self.on_items_inserted)
47
self._notifier_ids.append(id)
48
id = self.controller.model.notifier.connect('items-deleted',
49
self.on_items_deleted)
50
self._notifier_ids.append(id)
51
self.bus.register(self.on_device_added, NewDeviceDetected)
52
self.bus.register(self.on_device_removed, DeviceRemoved)
54
self.controller.connect('clean', self.on_clean)
56
model, dfr = common.application.resource_manager.get(self.uri, None)
57
dfr.addCallback(self.do_list_hardware)
61
def decorate(klass, controller):
62
decorator = klass(controller)
63
return decorator.initialize()
65
def add_entry(self, model):
67
Adds an entry for model
69
if self._count >= 1 and not self._use_long_names:
70
self._use_long_names = 1
73
model.default_action = PlayPhysicalDvdAction(self.controller)
74
model.extra_actions = [EjectDvdAction(self.controller)]
75
model.label = self._get_label(model)
76
model.icon = "elisa.plugins.poblesec.glyphs.small.disc"
77
self.controller.model.append(model)
79
def do_list_hardware(self, model):
80
devices = sorted(model.devices, key=lambda i: i.name.lower())
85
def on_device_added(self, message, sender):
86
if message.model.protocol == 'dvd':
87
self.add_entry(message.model)
89
def on_device_removed(self, message, sender):
90
for item in self.controller.model:
91
if self._is_dvd(item) and item.udi == message.udi:
92
self.controller.model.remove(item)
95
def on_items_inserted(self, model, index, items):
96
old_count = self._count
97
new_dvds = [item for item in items if self._is_dvd(item)]
100
self._count += len(new_dvds)
102
def on_items_deleted(self, model, index, items):
103
old_count = self._count
104
removed_dvds = [item for item in items if self._is_dvd(item)]
107
self._count -= len(removed_dvds)
109
if self._count <= 1 and self._use_long_names:
110
self._use_long_names = False
114
def on_clean(self, controller):
115
self.bus.unregister(self.on_device_added)
116
self.bus.unregister(self.on_device_removed)
117
for id in self._notifier_ids:
118
controller.model.notifier.disconnect(id)
119
return defer.succeed(None)
121
def _is_dvd(self, item):
122
return isinstance(item, DeviceModel) and item.protocol == 'dvd'
124
def _rename_dvds(self):
125
dvds = (item for item in self.controller.model if self._is_dvd(item))
128
dvd.label = self._get_label(dvd)
130
index = self.controller.model.index(dvd)
131
self.controller.model[index] = dvd
133
def _get_label(self, dvd):
134
if self._use_long_names:
135
return _("DVD Disc: %s") % dvd.name
141
def _transform_model(controller, model):
142
lower_name = model.name.lower()
143
if lower_name.endswith('.iso'):
144
model.default_action = PlayDvdIsoAction(controller)
145
model.media_type = 'disc'
146
if lower_name == 'video_ts':
147
model.default_action = PlayVideoTsAction(controller)
148
model.media_type = 'disc'
152
def _hook_filesystem_controller():
153
from elisa.plugins.poblesec.filesystem import FilesystemController
154
FilesystemController.model_parsers.append(_transform_model)
156
def _unhook_filesystem_controller():
157
from elisa.plugins.poblesec.filesystem import FilesystemController
158
FilesystemController.model_parsers.remove(_transform_model)
160
def main_decorator(controller):
162
Add a pop-up when a dvd is inserted.
163
This should be used as a decorator on the main controller
165
play_action = PlayDvdAction(controller)
167
def new_device_detected_cb(message, sender):
168
model = message.model
169
if model.protocol != 'dvd':
173
dfr = controller.hide_popup()
175
def execute_action(result):
176
return play_action.execute(model)
177
return dfr.addCallback(execute_action)
179
title = _('DVD DISC INSERTED')
180
subtitle = _("The DVD Disc Entitled '%(name)s' Is Available") % \
182
text = _("A DVD Disc has been inserted into this computer. You may " \
183
"play this DVD now by selecting 'Play'. Alternatively " \
184
"select 'Cancel' to close this message.\n\n" \
185
"To access this device at a later date you can find it " \
186
"listed via the 'Attached Devices' subsection within the " \
187
"'Devices & Shares' section of the Main Menu." \
189
"<b>Note: DVD playback in Moovida is extremely experimental "\
190
"and there are known issues with a variety of DVD discs. "\
191
"Therefore, the playback experience may not be perfect.</b>")
192
buttons = ((_('Cancel'), controller.hide_popup),
193
(_('Play'), do_play))
194
controller.enqueue_popup(title, subtitle, text, buttons)
196
bus = common.application.bus
197
bus.register(new_device_detected_cb, NewDeviceDetected)
199
_hook_filesystem_controller()
201
def on_clean(controller):
202
bus.unregister(new_device_detected_cb)
203
_unhook_filesystem_controller()
204
return defer.succeed(None)
205
controller.connect('clean', on_clean)
207
return defer.succeed(None)