~osomon/moovida/plugin_dependencies_graph

« back to all changes in this revision

Viewing changes to elisa-plugins/elisa/plugins/dvd/decorators.py

  • Committer: Olivier Tilloy
  • Date: 2009-09-30 10:45:35 UTC
  • mfrom: (1074.1.464 moovida)
  • Revision ID: olivier@fluendo.com-20090930104535-0szf1k61gabhqoa8
Merged the latest Moovida.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
# Moovida - Home multimedia server
 
3
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
 
4
# All rights reserved.
 
5
#
 
6
# This file is available under one of two license agreements.
 
7
#
 
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.
 
11
#
 
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.
 
16
#
 
17
# Authors: Guillaume Emont <guillaume@fluendo.com>
 
18
 
 
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, \
 
24
         DeviceRemoved
 
25
from elisa.plugins.base.models.device import DeviceModel
 
26
 
 
27
from elisa.plugins.dvd.actions import PlayDvdAction, EjectDvdAction, \
 
28
         PlayPhysicalDvdAction, PlayVideoTsAction, PlayDvdIsoAction
 
29
 
 
30
_ = install_translation('dvd')
 
31
 
 
32
 
 
33
class SectionDecorator(object):
 
34
    uri = MediaUri("volumes://?filter=dvd")
 
35
 
 
36
    def __init__(self, controller):
 
37
        super(SectionDecorator, self).__init__()
 
38
        self.controller = controller
 
39
        self.bus = common.application.bus
 
40
        self._count = 0
 
41
        self._use_long_names = False
 
42
        self._notifier_ids = []
 
43
 
 
44
    def initialize(self):
 
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)
 
53
 
 
54
        self.controller.connect('clean', self.on_clean)
 
55
 
 
56
        model, dfr = common.application.resource_manager.get(self.uri, None)
 
57
        dfr.addCallback(self.do_list_hardware)
 
58
        return dfr
 
59
 
 
60
    @classmethod
 
61
    def decorate(klass, controller):
 
62
        decorator = klass(controller)
 
63
        return decorator.initialize()
 
64
 
 
65
    def add_entry(self, model):
 
66
        """
 
67
        Adds an entry for model
 
68
        """
 
69
        if self._count >= 1 and not self._use_long_names:
 
70
            self._use_long_names = 1
 
71
            self._rename_dvds()
 
72
 
 
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)
 
78
 
 
79
    def do_list_hardware(self, model):
 
80
        devices = sorted(model.devices, key=lambda i: i.name.lower())
 
81
 
 
82
        for dev in devices:
 
83
            self.add_entry(dev)
 
84
        
 
85
    def on_device_added(self, message, sender):
 
86
        if message.model.protocol == 'dvd':
 
87
            self.add_entry(message.model)
 
88
 
 
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)
 
93
                break
 
94
 
 
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)]
 
98
        if not new_dvds:
 
99
            return
 
100
        self._count += len(new_dvds)
 
101
 
 
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)]
 
105
        if not removed_dvds:
 
106
            return
 
107
        self._count -= len(removed_dvds)
 
108
 
 
109
        if self._count <= 1 and self._use_long_names:
 
110
                self._use_long_names = False
 
111
                if self._count == 1:
 
112
                    self._rename_dvds()
 
113
 
 
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)
 
120
 
 
121
    def _is_dvd(self, item):
 
122
        return isinstance(item, DeviceModel) and item.protocol == 'dvd'
 
123
 
 
124
    def _rename_dvds(self):
 
125
        dvds = (item for item in self.controller.model if self._is_dvd(item))
 
126
 
 
127
        for dvd in dvds:
 
128
            dvd.label = self._get_label(dvd)
 
129
            # trigger a refresh
 
130
            index = self.controller.model.index(dvd)
 
131
            self.controller.model[index] = dvd
 
132
 
 
133
    def _get_label(self, dvd):
 
134
        if self._use_long_names:
 
135
            return _("DVD Disc: %s") % dvd.name
 
136
        else:
 
137
            return _("DVD Disc")
 
138
 
 
139
 
 
140
 
 
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'
 
149
    return model
 
150
 
 
151
 
 
152
def _hook_filesystem_controller():
 
153
    from elisa.plugins.poblesec.filesystem import FilesystemController
 
154
    FilesystemController.model_parsers.append(_transform_model)
 
155
 
 
156
def _unhook_filesystem_controller():
 
157
    from elisa.plugins.poblesec.filesystem import FilesystemController
 
158
    FilesystemController.model_parsers.remove(_transform_model)
 
159
 
 
160
def main_decorator(controller):
 
161
    """
 
162
    Add a pop-up when a dvd is inserted.
 
163
    This should be used as a decorator on the main controller
 
164
    """
 
165
    play_action = PlayDvdAction(controller)
 
166
 
 
167
    def new_device_detected_cb(message, sender):
 
168
        model = message.model
 
169
        if model.protocol != 'dvd':
 
170
            return
 
171
 
 
172
        def do_play():
 
173
            dfr = controller.hide_popup()
 
174
 
 
175
            def execute_action(result):
 
176
                return play_action.execute(model)
 
177
            return dfr.addCallback(execute_action)
 
178
 
 
179
        title = _('DVD DISC INSERTED')
 
180
        subtitle = _("The DVD Disc Entitled '%(name)s' Is Available") % \
 
181
                                                        {'name': model.name}
 
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 &amp; Shares' section of the Main Menu." \
 
188
                 "\n\n" \
 
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)
 
195
 
 
196
    bus = common.application.bus
 
197
    bus.register(new_device_detected_cb, NewDeviceDetected)
 
198
 
 
199
    _hook_filesystem_controller()
 
200
 
 
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)
 
206
 
 
207
    return defer.succeed(None)