def play(self, arg=None, menuw=None): self.elapsed = 0 if not self.menuw: self.menuw = menuw self.player = PodCastPlayerGUI(self, menuw) #LastFM error = self.player.play() if error and menuw: AlertBox(text=error).show() rc.post_event(rc.PLAY_END)
def play(self, arg=None, menuw=None): _debug_('station=%r station_index=%r name=%r' % (self.station, self.station_index, self.name)) # self.parent.current_item = self self.elapsed = 0 if not self.menuw: self.menuw = menuw if self.checktv(): AlertBox(text=_('Cannot play - recording in progress'), handler=self.confirm).show() return 'Cannot play with RadioPlayer - recording in progress' self.player = PlayerGUI(self, menuw) error = self.player.play() if error and menuw: AlertBox(text=error).show() rc.post_event(rc.PLAY_END)
def play(self, arg=None, menuw=None): logger.debug('%s.play(arg=%r, menuw=%r)', self.__module__, arg, menuw) self.elapsed = 0 if not self.menuw: self.menuw = menuw self.player = PodCastPlayerGUI(self, menuw) #LastFM error = self.player.play() if error and menuw: AlertBox(text=error).show() rc.post_event(rc.PLAY_END)
def play(self, arg=None, menuw=None): """ Play this Podcast """ download_failed = False self.download_url = self.item_url if not os.path.exists( self.filename) or os.path.getsize(self.filename) < 1024: try: background = BGDownload(self.download_url, self.filename, self.results) background.start() popup = PopupBox(text=_('Fetching "%s"...' % self.name)) popup.show() try: size = 0 for i in range(int(config.VPODCAST_BUFFERING_TIME)): if os.path.exists(self.filename): size = os.stat(self.filename)[stat.ST_SIZE] if size > config.VPODCAST_BUFFERING_SIZE: break time.sleep(1.0) else: if size < config.VPODCAST_BUFFERING_SIZE: download_failed = True finally: popup.destroy() if download_failed: AlertBox(text=_('Fetching "%s" failed\nNo data') % self.filename).show() return except youtube.DownloadError, why: AlertBox(text=_('Fetching "%(filename)s" failed:\n%(why)s') % ({ 'filename': self.filename, 'why': why })).show() return
def eventhandler(self, event, menuw=None): """ eventhandler for this item """ # when called from mplayer.py, there is no menuw if not menuw: menuw = self.menuw if self.plugin_eventhandler(event, menuw): return True # PLAY_END: do we have to play another file? if self.subitems and not self.variants: if event == PLAY_END: if not hasattr(self, 'error_in_subitem'): # I have no idea how this can happen, but it does self.error_in_subitem = 0 self.set_next_available_subitem() # Loop until we find a subitem which plays without error while self.current_subitem: _debug_('playing next item') error = self.current_subitem.play(menuw=menuw) if error: self.last_error_msg = error self.error_in_subitem = 1 self.set_next_available_subitem() else: return True if self.error_in_subitem: # No more subitems to play, and an error occured self.menuw.show() AlertBox(text=self.last_error_msg).show() elif event == USER_END: pass # show configure menu if event == MENU: if self.player: self.player.stop() self.settings(menuw=menuw) menuw.show() return True # give the event to the next eventhandler in the list if isstring(self.parent): self.parent = None return Item.eventhandler(self, event, menuw)
def removeFavorite(self): _debug_('removeFavorite()', 2) (result, reason) = self.recordclient.removeFavoriteNow(self.oldname) if result: searcher = None if self.parent and self.context == 'favorites': for child in self.parent.children: if isinstance(child, ViewFavorites): searcher = child break if searcher: searcher.refreshList() self.destroy() if searcher: searcher.draw() self.osd.update() else: AlertBox(parent=self, text=_('Remove favorite failed')+(':\n%s' % reason)).show()
def play(self, arg=None, menuw=None): """ Play the item. """ if not self.player or self.player_rating < 10: AlertBox(text=_('No player for this item found')).show() return if not self['resume'] and self['autobookmark_resume']: self.__play_args = (arg, menuw) dialog.show_confirmation( _('Do you want to resume play back or play from the start?'), cancel_handler=self.resume_play, cancel_text=_('From Start'), proceed_handler=self.resume_resume, proceed_text=_('Resume')) else: self.__play(arg, menuw)
def removeFavorite(self): (result, msg) = record_client.removeFavorite(self.oldname) if result: searcher = None if self.parent and self.context == 'favorites': for child in self.parent.children: if isinstance(child, ViewFavorites): searcher = child break if searcher: searcher.refreshList() self.destroy() if searcher: searcher.draw() self.osd.update() else: AlertBox(parent=self, text=_('Remove Failed') + (': %s' % msg)).show()
def eventhandler(self, event, menuw=None): """ Processes events detect the video start and stop events so that the alert box will work correctly """ self.lock.acquire() try: _debug_('eventhandler(self, %s, %s) name=%s arg=%s context=%s handler=%s' % \ (event, menuw, event.name, event.arg, event.context, event.handler), 2) finally: self.lock.release() if (event.name == 'VIDEO_START'): self.stopped = False if (event.name == 'VIDEO_END'): if self.stopped: # upsoon stopped the tv, now display a msgbox AlertBox(text=_('TV stopped, a recording is about to start!'), height=200).show() return 0
def event_handler(self, event): """ Processes events, detect the video start and stop events so that the alert box will work correctly """ logger.log( 9, 'event_handler(event=%r)', event.name) try: logger.log( 9, 'event_handler(%s) name=%s arg=%s context=%s handler=%s', event, event.name, event.arg, event.context, event.handler) finally: pass if (event.name == 'VIDEO_START'): self.stopped = None if (event.name == 'VIDEO_END'): if self.stopped: # upsoon stopped the tv, now display a msgbox if not self.standalone: AlertBox(text=_('%s stopped, a recording is about to start!') % self.stopped, height=200).show() self.stopped = None return 0
def play(self, arg=None, menuw=None, alternateplayer=False): """ execute commands if defined """ if config.VIDEO_PRE_PLAY: os.system(config.VIDEO_PRE_PLAY) """ play the item. """ if not self.possible_player: for p in plugin.getbyname(plugin.VIDEO_PLAYER, True): rating = p.rate(self) * 10 if config.VIDEO_PREFERED_PLAYER == p.name: rating += 1 if hasattr(self, 'force_player') and p.name == self.force_player: rating += 100 self.possible_player.append((rating, p)) self.possible_player.sort(lambda l, o: -cmp(l[0], o[0])) if alternateplayer: self.possible_player.reverse() if not self.possible_player: return self.player_rating, self.player = self.possible_player[0] if self.parent: self.parent.current_item = self if not self.menuw: self.menuw = menuw # if we have variants, play the first one as default if self.variants: self.variants[0].play(arg, menuw) return # if we have subitems (a movie with more than one file), # we start playing the first that is physically available if self.subitems: self.error_in_subitem = 0 self.last_error_msg = '' self.current_subitem = None result = self.set_next_available_subitem() if self.current_subitem: # 'result' is always 1 in this case # The media is available now for playing # Pass along the options, without loosing the subitem's own # options if self.current_subitem.mplayer_options: if self.mplayer_options: self.current_subitem.mplayer_options += ' ' + self.mplayer_options else: self.current_subitem.mplayer_options = self.mplayer_options # When playing a subitem, the menu must be hidden. If it is not, # the playing will stop after the first subitem, since the # PLAY_END/USER_END event is not forwarded to the parent # videoitem. # And besides, we don't need the menu between two subitems. self.menuw.hide() self.last_error_msg = self.current_subitem.play( arg, self.menuw) if self.last_error_msg: self.error_in_subitem = 1 # Go to the next playable subitem, using the loop in # eventhandler() self.eventhandler(PLAY_END) elif not result: # No media at all was found: error ConfirmBox(text=(_('No media found for "%s".\n') + _('Please insert the media.')) % self.name, handler=self.play).show() return # normal plackback of one file if self.url.startswith('file://'): file = self.filename if self.media_id: mountdir, file = util.resolve_media_mountdir( self.media_id, file) if mountdir: util.mount(mountdir) else: self.menuw.show() ConfirmBox(text=(_('No media found for "%s".\n') + _('Please insert the media.')) % file, handler=self.play).show() return elif self.media: util.mount(os.path.dirname(self.filename)) elif self.mode in ('dvd', 'vcd') and not self.filename and not self.media: media = util.check_media(self.media_id) if media: self.media = media else: self.menuw.show() ConfirmBox(text=(_('No media found for "%s".\n') + _('Please insert the media.')) % self.url, handler=self.play).show() return if self.player_rating < 10: AlertBox(text=_('No player for this item found')).show() return mplayer_options = self.mplayer_options.split(' ') if not mplayer_options: mplayer_options = [] if arg: mplayer_options += arg.split(' ') if self.menuw.visible: self.menuw.hide() self.plugin_eventhandler(PLAY, menuw) error = self.player.play(mplayer_options, self) if error: # If we are a subitem we don't show any error message before # having tried all the subitems if hasattr(self.parent, 'subitems') and self.parent.subitems: return error else: AlertBox(text=error, handler=self.error_handler).show()
def __play(self, arg=None, menuw=None): # execute commands if defined if config.VIDEO_PRE_PLAY: os.system(config.VIDEO_PRE_PLAY) if self.parent: self.parent.current_item = self if not self.menuw: self.menuw = menuw # if we have variants, play the first one as default if self.variants: self.variants[0].play(arg, menuw) return # if we have subitems (a movie with more than one file), # we start playing the first that is physically available if self.subitems: self.error_in_subitem = 0 self.last_error_msg = '' self.current_subitem = None result = self.set_next_available_subitem() if self.current_subitem: # 'result' is always 1 in this case # The media is available now for playing # Pass along the options, without loosing the subitem's own # options if self.current_subitem.mplayer_options: if self.mplayer_options: # With this set the player options are incorrect when there is more than 1 item #self.current_subitem.mplayer_options += ' ' + self.mplayer_options pass else: self.current_subitem.mplayer_options = self.mplayer_options # When playing a subitem, the menu must be hidden. If it is not, # the playing will stop after the first subitem, since the # PLAY_END/USER_END event is not forwarded to the parent # videoitem. # And besides, we don't need the menu between two subitems. self.menuw.hide() self.last_error_msg = self.current_subitem.play( arg, self.menuw) if self.last_error_msg: self.error_in_subitem = 1 # Go to the next playable subitem, using the loop in # eventhandler() self.eventhandler(PLAY_END) elif not result: # No media at all was found: error ConfirmBox(text=(_( 'No media found for "%(name)s".\nPlease insert the media "%(media_id)s".' )) % ({ 'name': self.name, 'media_id': self.media_id }), handler=self.play).show() return # normal plackback of one file if self.url.startswith('file://'): file = self.filename if self.media_id: mountdir, file = util.resolve_media_mountdir( self.media_id, file) if mountdir: util.mount(mountdir) else: self.menuw.show() ConfirmBox(text=(_('No media found for "%(file)s".\nPlease insert the media "%(media_id)s".')) % \ ({'file': file, 'media_id': self.media_id}), handler=self.play).show() return elif self.media: util.mount(os.path.dirname(self.filename)) # dvd and vcd elif self.mode in ('dvd', 'vcd') and not self.filename and not self.media: media = util.check_media(self.media_id) if media: self.media = media else: self.menuw.show() ConfirmBox(text=(_( 'No media found for "%(media_id)s".\nPlease insert the media "%(url)s".' )) % ({ 'media_id': self.media_id, 'url': self.url }), handler=self.play).show() return mplayer_options = self.mplayer_options.split(' ') if not mplayer_options: mplayer_options = [] if arg: mplayer_options += arg.split(' ') if self.menuw.visible: self.menuw.hide() self.plugin_eventhandler(PLAY, menuw) self.menuw.delete_submenu() error = self.player.play(mplayer_options, self) # Clear any resume settings self['resume'] = '' if error: # If we are a subitem we don't show any error message before # having tried all the subitems if hasattr(self.parent, 'subitems') and self.parent.subitems: return error else: AlertBox(text=error, handler=self.error_handler).show()
class DirItem(Playlist): """ class for handling directories """ def __init__(self, directory, parent, name='', display_type=None, add_args=None, create_metainfo=True): self.autovars = [('num_dir_items', 0), ('show_all_items', False)] Playlist.__init__(self, parent=parent, display_type=display_type) self.type = 'dir' self.menu = None # store FileInformation for moving/copying self.files = FileInformation() if self.media: self.files.read_only = True self.files.append(directory) self.dir = os.path.abspath(directory) self.info = mediainfo.get_dir(directory) #FIXME This should be done in the cache create if not self.image: mminfo = mmpython.parse(directory) if mminfo: if mminfo['image']: self.image = mminfo['image'] if mminfo['title']: self.title = mminfo['title'] if mminfo['comment']: self.comment = mminfo['comment'] if name: self.name = Unicode(name) elif self.info['title:filename']: self.name = self.info['title:filename'] elif self.info['title']: self.name = self.info['title'] else: self.name = util.getname(directory, skip_ext=False) if add_args == None and hasattr(parent, 'add_args'): add_args = parent.add_args self.add_args = add_args if self.parent and hasattr(parent, 'skin_display_type'): self.skin_display_type = parent.skin_display_type elif parent: self.skin_display_type = parent.display_type else: self.skin_display_type = display_type if self['show_all_items']: self.display_type = None # set tv to video now if self.display_type == 'tv': display_type = 'video' # set directory variables to default global all_variables self.all_variables = copy.copy(all_variables) # Check mimetype plugins if they want to add something for p in plugin.mimetype(display_type): self.all_variables += p.dirconfig(self) # set the variables to the default values for var in self.all_variables: if hasattr(parent, var[0]): setattr(self, var[0], getattr(parent, var[0])) elif hasattr(config, var[0]): setattr(self, var[0], getattr(config, var[0])) else: setattr(self, var[0], False) self.modified_vars = [] # Check for a cover in current dir if self.info['image']: image = self.info['image'] else: image = util.getimage(os.path.join(directory, 'cover')) # if we have an image then use it if image: self.image = image self.files.image = image # Check for a folder.fxd in current dir self.folder_fxd = directory + '/folder.fxd' if vfs.isfile(self.folder_fxd): self.set_fxd_file(self.folder_fxd) # Check mimetype plugins if they want to add something for p in plugin.mimetype(display_type): p.dirinfo(self) if self.DIRECTORY_SORT_BY_DATE == 2 and self.display_type != 'tv': self.DIRECTORY_SORT_BY_DATE = 0 # create some extra info if create_metainfo: self.create_metainfo() def __str__(self): s = pformat(self, depth=2) return s def __repr__(self): if hasattr(self, 'name'): s = '<%s: %r>' % (self.name, self.__class__) else: s = '<%r>' % (self.__class__) return s def set_fxd_file(self, file): """ Set self.folder_fxd and parse it """ self.folder_fxd = file if self.folder_fxd and vfs.isfile(self.folder_fxd): if self.display_type == 'tv': display_type = 'video' try: parser = util.fxdparser.FXD(self.folder_fxd) parser.set_handler('folder', self.read_folder_fxd) parser.set_handler('skin', self.read_folder_fxd) parser.parse() except: print "fxd file %s corrupt" % self.folder_fxd traceback.print_exc() def read_folder_fxd(self, fxd, node): """ parse the xml file for directory settings:: <?xml version="1.0" ?> <freevo> <folder title="Incoming TV Shows" cover-img="foo.jpg"> <setvar name="directory_autoplay_single_item" val="0"/> <info> <content>Episodes for current tv shows not seen yet</content> </info> </folder> </freevo> """ if node.name == 'skin': self.skin_fxd = self.folder_fxd return # read attributes self.name = Unicode(fxd.getattr(node, 'title', self.name)) image = fxd.childcontent(node, 'cover-img') if image and vfs.isfile(os.path.join(self.dir, image)): self.image = os.path.join(self.dir, image) # parse <info> tag fxd.parse_info(fxd.get_children(node, 'info', 1), self, { 'description': 'content', 'content': 'content' }) for child in fxd.get_children(node, 'setvar', 1): # <setvar name="directory_smart_sort" val="1"/> for v, n, d, type_list in self.all_variables: if child.attrs[('', 'name')].upper() == v.upper(): if type_list: if int(child.attrs[('', 'val')]): setattr(self, v, [self.display_type]) else: setattr(self, v, []) else: try: setattr(self, v, int(child.attrs[('', 'val')])) except ValueError: setattr(self, v, child.attrs[('', 'val')]) self.modified_vars.append(v) def __is_type_list_var__(self, var): """ return if this variable to be saved is a type_list """ for v, n, d, type_list in self.all_variables: if v == var: return type_list return False def write_folder_fxd(self, fxd, node): """ callback to save the modified fxd file """ # remove old setvar for child in copy.copy(node.children): if child.name == 'setvar': node.children.remove(child) # add current vars as setvar for v in self.modified_vars: if self.__is_type_list_var__(v): if getattr(self, v): val = 1 else: val = 0 else: val = getattr(self, v) fxd.add(fxd.XMLnode('setvar', (('name', v.lower()), ('val', val))), node, 0) def __getitem__(self, key): """ return the specific attribute """ if key == 'type': if self.media and hasattr(self.media, 'label'): return _('Directory on disc [%s]') % self.media.label return _('Directory') if key == 'num_items': display_type = self.display_type or 'all' if self.display_type == 'tv': display_type = 'video' return self['num_%s_items' % display_type] + self['num_dir_items'] if key == 'num_play_items': display_type = self.display_type if self.display_type == 'tv': display_type = 'video' return self['num_%s_items' % display_type] if key in ('freespace', 'totalspace'): if self.media: return None space = getattr(util, key)(self.dir) / 1000000 if space > 1000: space = '%s,%s' % (space / 1000, space % 1000) return space return Item.__getitem__(self, key) # eventhandler for this item def eventhandler(self, event, menuw=None): if event == DIRECTORY_CHANGE_DISPLAY_TYPE and menuw.menustack[ -1] == self.menu: possible_display_types = [] for p in plugin.get('mimetype'): for t in p.display_type: if not t in possible_display_types: possible_display_types.append(t) try: pos = possible_display_types.index(self.display_type) type = possible_display_types[(pos + 1) % len(possible_display_types)] menuw.delete_menu(allow_reload=False) newdir = DirItem(self.dir, self.parent, self.name, type, self.add_args) newdir.DIRECTORY_AUTOPLAY_SINGLE_ITEM = False newdir.cwd(menuw=menuw) menuw.menustack[-2].selected = newdir pos = menuw.menustack[-2].choices.index(self) menuw.menustack[-2].choices[pos] = newdir rc.post_event(Event(OSD_MESSAGE, arg='%s view' % type)) return True except (IndexError, ValueError): pass return Playlist.eventhandler(self, event, menuw) # ====================================================================== # metainfo # ====================================================================== def create_metainfo(self): """ create some metainfo for the directory """ display_type = self.display_type if self.display_type == 'tv': display_type = 'video' name = display_type or 'all' # check autovars for var, val in self.autovars: if var == 'num_%s_timestamp' % name: break else: self.autovars += [('num_%s_timestamp' % name, 0), ('num_%s_items' % name, 0)] try: timestamp = os.stat(self.dir)[stat.ST_MTIME] except OSError: return num_timestamp = self.info['num_%s_timestamp' % name] if not num_timestamp or num_timestamp < timestamp: _debug_('create metainfo for %s', self.dir) need_umount = False if self.media: need_umount = not self.media.is_mounted() self.media.mount() num_dir_items = 0 num_play_items = 0 files = vfs.listdir(self.dir, include_overlay=True) # play items and playlists for p in plugin.mimetype(display_type): num_play_items += p.count(self, files) # normal DirItems for filename in files: if os.path.isdir(filename): num_dir_items += 1 # store info if num_play_items != self['num_%s_items' % name]: self['num_%s_items' % name] = num_play_items if self['num_dir_items'] != num_dir_items: self['num_dir_items'] = num_dir_items self['num_%s_timestamp' % name] = timestamp if need_umount: self.media.umount() # ====================================================================== # actions # ====================================================================== def actions(self): """ return a list of actions for this item """ if self.media: self.media.mount() display_type = self.display_type if self.display_type == 'tv': display_type = 'video' items = [(self.cwd, _('Browse directory'))] if self['num_%s_items' % display_type]: items.append((self.play, _('Play all files in directory'))) if display_type in self.DIRECTORY_AUTOPLAY_ITEMS and not self[ 'num_dir_items']: items.reverse() if self['num_%s_items' % display_type]: items.append((self.play_random, _('Random play all items'))) if self['num_dir_items']: items += [(self.play_random_recursive, _('Recursive random play all items')), (self.play_recursive, _('Recursive play all items'))] items.append((self.configure, _('Configure directory'), 'configure')) if self.folder_fxd: items += fxditem.mimetype.get(self, [self.folder_fxd]) if self.media: self.media.umount() return items def cwd(self, arg=None, menuw=None): """ browse directory """ self.check_password_and_build(arg=None, menuw=menuw) def play(self, arg=None, menuw=None): """ play directory """ if arg == 'next': Playlist.play(self, arg=arg, menuw=menuw) else: self.check_password_and_build(arg='play', menuw=menuw) def play_random(self, arg=None, menuw=None): """ play in random order """ self.check_password_and_build(arg='playlist:random', menuw=menuw) def play_recursive(self, arg=None, menuw=None): """ play recursive """ self.check_password_and_build(arg='playlist:recursive', menuw=menuw) def play_random_recursive(self, arg=None, menuw=None): """ play recursive in random order """ self.check_password_and_build(arg='playlist:random_recursive', menuw=menuw) def check_password_and_build(self, arg=None, menuw=None): """ password checker """ if not self.menuw: self.menuw = menuw # are we on a ROM_DRIVE and have to mount it first? for media in config.REMOVABLE_MEDIA: if self.dir.find(media.mountdir) == 0: util.mount(self.dir) self.media = media if vfs.isfile(self.dir + '/.password'): print 'password protected dir' self.arg = arg self.menuw = menuw pb = InputBox(text=_('Enter Password'), handler=self.pass_cmp_cb, type='password') pb.show() else: self.build(arg=arg, menuw=menuw) def pass_cmp_cb(self, word=None): """ read the contents of self.dir/.passwd and compare to word callback for check_password_and_build """ try: pwfile = vfs.open(self.dir + '/.password') line = pwfile.readline() except IOError, e: print 'error %d (%s) reading password file for %s' % \ (e.errno, e.strerror, self.dir) return pwfile.close() password = line.strip() if word == password: self.build(self.arg, self.menuw) else: pb = AlertBox(text=_('Password incorrect')) pb.show() return
def build(self, arg=None, menuw=None): """ build the items for the directory """ self.menuw = menuw self.playlist = [] self.play_items = [] self.dir_items = [] self.pl_items = [] if self.media: self.media.mount() if hasattr(self, '__dirwatcher_last_time__'): del self.__dirwatcher_last_time__ if arg == 'update': if not self.menu.choices: selected_pos = -1 else: # store the current selected item selected_id = self.menu.selected.id() selected_pos = self.menu.choices.index(self.menu.selected) if hasattr(self.menu, 'skin_default_has_description'): del self.menu.skin_default_has_description if hasattr(self.menu, 'skin_default_no_images'): del self.menu.skin_default_no_images if hasattr(self.menu, 'skin_force_text_view'): del self.menu.skin_force_text_view elif not os.path.exists(self.dir): AlertBox(text=_('Directory does not exist')).show() return display_type = self.display_type if self.display_type == 'tv': display_type = 'video' if arg and arg.startswith('playlist:'): if arg.endswith(':random'): Playlist(playlist=[(self.dir, 0)], parent=self, display_type=display_type, random=True).play(menuw=menuw) elif arg.endswith(':recursive'): Playlist(playlist=[(self.dir, 1)], parent=self, display_type=display_type, random=False).play(menuw=menuw) elif arg.endswith(':random_recursive'): Playlist(playlist=[(self.dir, 1)], parent=self, display_type=display_type, random=True).play(menuw=menuw) return if config.OSD_BUSYICON_TIMER: osd.get_singleton().busyicon.wait(config.OSD_BUSYICON_TIMER[0]) files = vfs.listdir(self.dir, include_overlay=True) num_changes = mediainfo.check_cache(self.dir) pop = None callback = None if skin.active(): if (num_changes > 10) or (num_changes and self.media): if self.media: pop = ProgressBox(text=_('Scanning disc, be patient...'), full=num_changes) else: pop = ProgressBox( text=_('Scanning directory, be patient...'), full=num_changes) pop.show() callback = pop.tick elif config.OSD_BUSYICON_TIMER and len( files) > config.OSD_BUSYICON_TIMER[1]: # many files, just show the busy icon now osd.get_singleton().busyicon.wait(0) if num_changes > 0: mediainfo.cache_dir(self.dir, callback=callback) # # build items # # build play_items, pl_items and dir_items for p in plugin.mimetype(display_type): for i in p.get(self, files): if i.type == 'playlist': self.pl_items.append(i) elif i.type == 'dir': self.dir_items.append(i) else: self.play_items.append(i) # normal DirItems for filename in files: if os.path.isdir(filename): d = DirItem(filename, self, display_type=self.display_type) self.dir_items.append(d) # remove same beginning from all play_items if self.DIRECTORY_SMART_NAMES: substr = '' if len(self.play_items) > 4 and len(self.play_items[0].name) > 5: substr = self.play_items[0].name[:-5].lower() for i in self.play_items[1:]: if len(i.name) > 5: substr = util.find_start_string(i.name.lower(), substr) if not substr or len(substr) < 10: break else: break else: for i in self.play_items: i.name = util.remove_start_string(i.name, substr) # # sort all items # # sort directories if self.DIRECTORY_SMART_SORT: self.dir_items.sort(lambda l, o: util.smartsort(l.dir, o.dir)) else: self.dir_items.sort(lambda l, o: cmp(l.dir.upper(), o.dir.upper())) # sort playlist self.pl_items.sort(lambda l, o: cmp(l.name.upper(), o.name.upper())) # sort normal items if self.DIRECTORY_SORT_BY_DATE: self.play_items.sort(lambda l, o: cmp( l.sort('date').upper(), o.sort('date').upper())) elif self['%s_advanced_sort' % display_type]: self.play_items.sort(lambda l, o: cmp( l.sort('advanced').upper(), o.sort('advanced').upper())) else: self.play_items.sort(lambda l, o: cmp(l.sort().upper(), o.sort().upper())) if self['num_dir_items'] != len(self.dir_items): self['num_dir_items'] = len(self.dir_items) if self['num_%s_items' % display_type] != len(self.play_items) + len(self.pl_items): self['num_%s_items' % display_type] = len(self.play_items) + len(self.pl_items) if self.DIRECTORY_REVERSE_SORT: self.dir_items.reverse() self.play_items.reverse() self.pl_items.reverse() # delete pl_items if they should not be displayed if self.display_type and not self.display_type in self.DIRECTORY_ADD_PLAYLIST_FILES: self.pl_items = [] # add all playable items to the playlist of the directory # to play one files after the other if not self.display_type or self.display_type in self.DIRECTORY_CREATE_PLAYLIST: self.playlist = self.play_items # build a list of all items items = self.dir_items + self.pl_items + self.play_items # random playlist (only active for audio) if self.display_type and self.display_type in self.DIRECTORY_ADD_RANDOM_PLAYLIST \ and len(self.play_items) > 1: pl = Playlist(_('Random playlist'), self.play_items, self, random=True) pl.autoplay = True items = [pl] + items if pop: pop.destroy() # closing the poup will rebuild the menu which may umount # the drive if self.media: self.media.mount() if config.OSD_BUSYICON_TIMER: # stop the timer. If the icons is drawn, it will stay there # until the osd is redrawn, if not, we don't need it to pop # up the next milliseconds osd.get_singleton().busyicon.stop() # # action # if arg == 'update': # update because of dirwatcher changes self.menu.choices = items if selected_pos != -1: for i in items: if Unicode(i.id()) == Unicode(selected_id): self.menu.selected = i break else: # item is gone now, try to the selection close # to the old item pos = max(0, min(selected_pos - 1, len(items) - 1)) if items: self.menu.selected = items[pos] else: self.menu.selected = None if self.menuw: if self.menu.selected and selected_pos != -1: self.menuw.rebuild_page() else: self.menuw.init_page() self.menuw.refresh() elif len(items) == 1 and items[0].actions() and \ self.DIRECTORY_AUTOPLAY_SINGLE_ITEM: # autoplay items[0].actions()[0][0](menuw=menuw) elif arg == 'play' and self.play_items: # called by play function self.playlist = self.play_items Playlist.play(self, menuw=menuw) else: # normal menu build item_menu = menu.Menu( self.name, items, reload_func=self.reload, item_types=self.skin_display_type, force_skin_layout=self.DIRECTORY_FORCE_SKIN_LAYOUT) if self.skin_fxd: item_menu.skin_settings = skin.load(self.skin_fxd) menuw.pushmenu(item_menu) dirwatcher.cwd(menuw, self, item_menu, self.dir) self.menu = item_menu self.menuw = menuw
def eventhandler(self, event): menu = self.menustack[-1] if self.cols == 1 and isinstance(menu, Menu): if config.MENU_ARROW_NAVIGATION: if event == MENU_LEFT: event = MENU_BACK_ONE_MENU elif event == MENU_RIGHT: event = MENU_SELECT else: if event == MENU_LEFT: event = MENU_PAGEUP elif event == MENU_RIGHT: event = MENU_PAGEDOWN if self.eventhandler_plugins == None: self.eventhandler_plugins = plugin.get('daemon_eventhandler') if event == MENU_GOTO_MAINMENU: self.goto_main_menu() return if event == MENU_GOTO_TV: self.goto_media_menu("tv") return if event == MENU_GOTO_TVGUIDE: self.goto_media_menu("tv.guide") return if event == MENU_GOTO_VIDEOS: self.goto_media_menu("video") return if event == MENU_GOTO_MUSIC: self.goto_media_menu("audio") return if event == MENU_GOTO_IMAGES: self.goto_media_menu("image") return if event == MENU_GOTO_GAMES: self.goto_media_menu("games") return if event == MENU_GOTO_RADIO: self.goto_media_menu("audio.radio") return if event == MENU_GOTO_SHUTDOWN: self.goto_media_menu("shutdown") return if event == MENU_BACK_ONE_MENU: self.back_one_menu() return if not isinstance(menu, Menu) and menu.eventhandler(event): return if event == 'MENU_REFRESH': self.refresh() return if event == 'MENU_REBUILD': self.init_page() self.refresh() return if not self.menu_items: if event in (MENU_SELECT, MENU_SUBMENU, MENU_PLAY_ITEM): self.back_one_menu() return menu = self.menustack[-2] if hasattr(menu.selected, 'eventhandler') and menu.selected.eventhandler: if menu.selected.eventhandler(event=event, menuw=self): return for p in self.eventhandler_plugins: if p.eventhandler(event=event, menuw=self): return return if not isinstance(menu, Menu): if self.eventhandler_plugins == None: self.eventhandler_plugins = plugin.get('daemon_eventhandler') for p in self.eventhandler_plugins: if p.eventhandler(event=event, menuw=self): return _debug_('no eventhandler for event %s' % event, 2) return if event == MENU_UP: curr_selected = self.all_items.index(menu.selected) if curr_selected-self.cols < 0 and \ menu.selected != menu.choices[0]: self.goto_prev_page(arg='no_refresh') try: if self.cols == 1: curr_selected = self.rows - 1 elif self.rows != 1: curr_selected = self.all_items.index(menu.selected) else: curr_selected += self.cols except ValueError: curr_selected += self.cols curr_selected = max(curr_selected - self.cols, 0) menu.selected = self.all_items[curr_selected] self.refresh() return elif event == MENU_DOWN: curr_selected = self.all_items.index(menu.selected) if curr_selected+self.cols > len(self.all_items)-1 and \ menu.page_start + len(self.all_items) < len(menu.choices): self.goto_next_page(arg='no_refresh') try: if self.cols == 1: curr_selected = 0 elif self.rows != 1: curr_selected = self.all_items.index(menu.selected) else: curr_selected -= self.cols except ValueError: curr_selected -= self.cols curr_selected = min(curr_selected + self.cols, len(self.all_items) - 1) menu.selected = self.all_items[curr_selected] self.refresh() return elif event == MENU_PAGEUP: # Do nothing for an empty file list if not len(self.menu_items): return curr_selected = self.all_items.index(menu.selected) # Move to the previous page if the current position is at the # top of the list, otherwise move to the top of the list. if curr_selected == 0: self.goto_prev_page() else: curr_selected = 0 menu.selected = self.all_items[curr_selected] self.refresh() return elif event == MENU_PAGEDOWN: # Do nothing for an empty file list if not len(self.menu_items): return if menu.selected == menu.choices[-1]: return curr_selected = self.all_items.index(menu.selected) bottom_index = self.menu_items.index(self.menu_items[-1]) # Move to the next page if the current position is at the # bottom of the list, otherwise move to the bottom of the list. if curr_selected >= bottom_index: self.goto_next_page() else: curr_selected = bottom_index menu.selected = self.all_items[curr_selected] self.refresh() return elif event == MENU_LEFT: # Do nothing for an empty file list if not len(self.menu_items): return curr_selected = self.all_items.index(menu.selected) if curr_selected == 0: self.goto_prev_page(arg='no_refresh') try: curr_selected = self.all_items.index(menu.selected) if self.rows == 1: curr_selected = len(self.all_items) except ValueError: curr_selected += self.cols curr_selected = max(curr_selected - 1, 0) menu.selected = self.all_items[curr_selected] self.refresh() return elif event == MENU_RIGHT: # Do nothing for an empty file list if not len(self.menu_items): return curr_selected = self.all_items.index(menu.selected) if curr_selected == len(self.all_items) - 1: self.goto_next_page(arg='no_refresh') try: curr_selected = self.all_items.index(menu.selected) if self.rows == 1: curr_selected -= 1 except ValueError: curr_selected -= self.cols curr_selected = min(curr_selected + 1, len(self.all_items) - 1) menu.selected = self.all_items[curr_selected] self.refresh() return elif event == MENU_PLAY_ITEM and hasattr(menu.selected, 'play'): menu.selected.play(menuw=self) elif event == MENU_SELECT or event == MENU_PLAY_ITEM: action = None arg = None try: action = menu.selected.action except AttributeError: action = menu.selected.actions() if action: action = action[0] if isinstance(action, MenuItem): action = action.function arg = action.arg else: action = action[0] if not action: print 'No action.. ' AlertBox(text=_('No action defined for this choice!')).show() else: action(arg=arg, menuw=self) return elif event == MENU_SUBMENU: if hasattr(menu, 'is_submenu'): return actions = menu.selected.actions() force = False if not actions: actions = [] force = True plugins = plugin.get('item') + plugin.get( 'item_%s' % menu.selected.type) if hasattr(menu.selected, 'display_type'): plugins += plugin.get('item_%s' % menu.selected.display_type) plugins.sort(lambda l, o: cmp(l._level, o._level)) for p in plugins: for a in p.actions(menu.selected): if isinstance(a, MenuItem): actions.append(a) else: actions.append(a[:2]) if len(a) == 3 and a[2] == 'MENU_SUBMENU': a[0](menuw=self) return if actions and (len(actions) > 1 or force): self.make_submenu(menu.selected.name, actions, menu.selected) return elif event == MENU_CALL_ITEM_ACTION: _debug_('calling action %s' % event.arg) for a in menu.selected.actions(): if not isinstance(a, Item) and len(a) > 2 and a[2] == event.arg: a[0](arg=None, menuw=self) return plugins = plugin.get('item') + plugin.get( 'item_%s' % menu.selected.type) if hasattr(menu.selected, 'display_type'): plugins += plugin.get('item_%s' % menu.selected.display_type) for p in plugins: for a in p.actions(menu.selected): if not isinstance( a, MenuItem) and len(a) > 2 and a[2] == event.arg: a[0](arg=None, menuw=self) return _debug_('action %s not found' % event.arg) elif event == MENU_CHANGE_STYLE and len(self.menustack) > 1: # did the menu change? if skin.toggle_display_style(menu): self.rebuild_page() self.refresh() return elif hasattr(menu.selected, 'eventhandler') and menu.selected.eventhandler: if menu.selected.eventhandler(event=event, menuw=self): return for p in self.eventhandler_plugins: if p.eventhandler(event=event, menuw=self): return _debug_('no eventhandler for event %s' % str(event), 2) return 0
def eventhandler(self, event, menuw=None): if self.get_selected_child() == self.name_input: if event == em.INPUT_LEFT: self.name_input.change_selected_box('left') self.draw() return True elif event == em.INPUT_RIGHT: self.name_input.change_selected_box('right') self.draw() return True elif event == em.INPUT_ENTER: self.name_input.get_selected_box().toggle_selected() self.chan_box.toggle_selected() self.draw() return True elif event == em.INPUT_UP: self.name_input.get_selected_box().charUp() self.draw() return True elif event == em.INPUT_DOWN: self.name_input.get_selected_box().charDown() self.draw() return True elif event in em.INPUT_ALL_NUMBERS: self.name_input.get_selected_box().cycle_phone_char(event) self.draw() return True elif event == em.INPUT_EXIT: self.destroy() return True elif self.get_selected_child() == self.chan_box: if event in (em.INPUT_UP, em.INPUT_DOWN): self.chan_box.change_item(event) self.draw() elif event == em.INPUT_ENTER: if self.chan_box.selected or self.chan_box.list.is_visible(): self.chan_box.toggle_box() self.draw() elif event in (em.INPUT_LEFT, em.MENU_PAGEUP): self.chan_box.toggle_selected() self.name_input.boxes[0].toggle_selected() self.draw() elif event in (em.INPUT_RIGHT, em.MENU_PAGEDOWN): self.chan_box.toggle_selected() self.dow_box.toggle_selected() self.draw() elif event == em.INPUT_EXIT: self.destroy() return True elif self.get_selected_child() == self.dow_box: if event in (em.INPUT_UP, em.INPUT_DOWN): self.dow_box.change_item(event) self.draw() elif event == em.INPUT_ENTER: if self.dow_box.selected or self.dow_box.list.is_visible(): self.dow_box.toggle_box() self.draw() elif event in (em.INPUT_LEFT, em.MENU_PAGEUP): self.dow_box.toggle_selected() self.chan_box.toggle_selected() self.draw() elif event in (em.INPUT_RIGHT, em.MENU_PAGEDOWN): self.dow_box.toggle_selected() self.tod_box.toggle_selected() self.draw() elif event == em.INPUT_EXIT: self.destroy() return True return True elif self.get_selected_child() == self.tod_box: if event in (em.INPUT_UP, em.INPUT_DOWN): self.tod_box.change_item(event) self.draw() elif event == em.INPUT_ENTER: if self.tod_box.selected or self.tod_box.list.is_visible(): self.tod_box.toggle_box() self.draw() elif event in (em.INPUT_LEFT, em.MENU_PAGEUP): self.tod_box.toggle_selected() self.dow_box.toggle_selected() self.draw() elif event in (em.INPUT_RIGHT, em.MENU_PAGEDOWN): self.tod_box.toggle_selected() self.save.toggle_selected() self.draw() elif event == em.INPUT_EXIT: self.destroy() return True return True elif self.get_selected_child() == self.save: if event == em.INPUT_ENTER: if self.oldname: record_client.removeFavorite(self.oldname) (result, msg) = record_client.addEditedFavorite( self.name_input.get_word(), self.fav.title, self.chan_box.list.get_selected_item().value, self.dow_box.list.get_selected_item().value, self.tod_box.list.get_selected_item().value, self.fav.priority, self.fav.allowDuplicates, self.fav.onlyNew) if result: #tv.view_favorites.ViewFavorites(parent=self.parent, text='Favorites').show() self.destroy() AlertBox(parent='osd', text=_('Favorite %s has been saved') % self.name_input.get_word()).show() else: AlertBox(parent=self, text=_('Failed: %s') % msg).show() return True elif event in (em.INPUT_LEFT, em.MENU_PAGEUP): self.save.toggle_selected() self.tod_box.toggle_selected() self.draw() elif event in (em.INPUT_RIGHT, em.MENU_PAGEDOWN): self.save.toggle_selected() if self.remove: self.remove.toggle_selected() else: self.cancel.toggle_selected() self.draw() elif event == em.INPUT_EXIT: self.destroy() return True return True elif self.get_selected_child() == self.remove: if event == em.INPUT_ENTER: ConfirmBox(text=_('Do you want to remove %s?') % self.name_input.get_word(), handler=self.removeFavorite).show() return True elif event in (em.INPUT_LEFT, em.MENU_PAGEUP): self.save.toggle_selected() self.remove.toggle_selected() self.draw() elif event in (em.INPUT_RIGHT, em.MENU_PAGEDOWN): self.remove.toggle_selected() self.cancel.toggle_selected() self.draw() elif event in (em.INPUT_ENTER, em.INPUT_EXIT): self.destroy() return True return True elif self.get_selected_child() == self.cancel: if event in (em.INPUT_LEFT, em.MENU_PAGEUP): if self.remove: self.remove.toggle_selected() else: self.save.toggle_selected() self.cancel.toggle_selected() self.draw() elif event in (em.INPUT_ENTER, em.INPUT_EXIT): self.destroy() return True return True if event == em.INPUT_EXIT: self.destroy() return True elif event in (em.MENU_PAGEDOWN, em.MENU_PAGEUP): return True else: return self.parent.eventhandler(event)
def _handle_play_item(self, menu, event): action = None arg = None sounds.play_sound(sounds.MENU_SELECT) try: action = menu.selected.action except AttributeError: actions = menu.selected.actions() or [] # Add the actions of the plugins to the list of actions. This is needed when a # Item class has no actions but plugins provides them. This case happens with an # empty disc. # # FIXME The event MENU_SELECT is called when selecting a submenu entry too. The # item passed to the plugin is then the submenu entry instead its parent item. So # if we are in a submenu we don't want to call the actions of the plugins. # because we'll break some (or all) plugins behavior. Does that sound correct? if config.OSD_SOUNDS: if hasattr(menu.selected, 'arg'): try: key = "menu." + menu.selected.arg[0] if config.OSD_SOUNDS[key]: sounds.play_sound(sounds.load_sound(key)) except: pass else: try: key = "menu." + menu.selected.__class__.__name__ if config.OSD_SOUNDS[key]: sounds.play_sound(sounds.load_sound(key)) except: pass if not hasattr(menu, 'is_submenu'): plugins = plugin.get('item') + plugin.get( 'item_%s' % menu.selected.type) if hasattr(menu.selected, 'display_type'): plugins += plugin.get('item_%s' % menu.selected.display_type) plugins.sort(lambda l, o: cmp(l._level, o._level)) for p in plugins: for a in p.actions(menu.selected): if isinstance(a, MenuItem): actions.append(a) else: actions.append(a[:2]) if actions: action = actions[0] if isinstance(action, MenuItem): action = action.function arg = action.arg else: action = action[0] if not action: AlertBox(text=_('No action defined for this choice!')).show() return action(arg=arg, menuw=self)