def set_url(self, url, info=True): """ Sets a new url to the item. Always use this function and not set 'url' directly because this functions also changes other attributes, like filename, mode and network_play. WARNING: This is called whenever self.url is set, therefor it is strictly forbidden to set self.url directly in this function (infinit recursion!). Use self.__dict__['url'] instead! """ Item.set_url(self, url, info) # Look for audio cover image by ID3 tags if info: filename_array = { 'album': self.info['album'], 'artist': self.info['artist'] } for format_string in config.AUDIO_COVER_FORMAT_STRINGS: filemask = format_string % filename_array if format_string.startswith('/'): audiocover = util.getimage(filemask) else: audiocover = os.path.dirname(self.filename) audiocover = os.path.join(audiocover, String(filemask)) audiocover = util.getimage(audiocover) if audiocover: self.image = audiocover self.files.image = audiocover break # additional url types if url and url.startswith('cdda://'): self.network_play = False self.mode = 'cdda' self.mimetype = 'cdda'
def set_url(self, url, info=True): """ Sets a new url to the item. Always use this function and not set 'url' directly because this functions also changes other attributes, like filename, mode and network_play. WARNING: This is called whenever self.url is set, therefor it is strictly forbidden to set self.url directly in this function (infinit recursion!). Use self.__dict__['url'] instead! """ Item.set_url(self, url, info) # Look for audio cover image by ID3 tags if info: filename_array = { 'album' : self.info['album'], 'artist' : self.info['artist'] } for format_string in config.AUDIO_COVER_FORMAT_STRINGS: filemask = format_string % filename_array if format_string.startswith('/'): audiocover = util.getimage(filemask) else: audiocover = os.path.dirname(self.filename) audiocover = os.path.join(audiocover, String(filemask)) audiocover = util.getimage(audiocover) if audiocover: self.image = audiocover self.files.image = audiocover break; # additional url types if url and url.startswith('cdda://'): self.network_play = False self.mode = 'cdda' self.mimetype = 'cdda'
def get_icon(self, name): """ Get the icon object 'name'. Return the icon in the theme dir if it exists, else try the normal image dir. If not found, return '' """ icon = util.getimage(os.path.join(self.settings.icon_dir, name)) if icon: return icon return util.getimage(os.path.join(config.ICON_DIR, name), '')
def saveimagedictionary(self): logging.info("Starting saving") newimagecount = updatedimagecount = 0 imagestosave = [] for imagename in self.imagedictionary.keys(): dbimage = util.getimage(imagename) wikiimage = self.imagedictionary[imagename] if (dbimage is not None): dbimage.pageid=int(wikiimage[0]) dbimage.neighborhood=wikiimage[1] imagetosave = dbimage updatedimagecount = updatedimagecount + 1 else: imagetosave = ImageModel( pageid=int(wikiimage[0]), imageurl=imagename, neighborhood=wikiimage[1], usernameupdated='WikiUser') savedimagecount = savedimagecount + 1 imagestosave.append(imagetosave) try: db.put(imagestosave) except Exception, err: logging.error(str(err))
def saveimagedictionary(self): logging.info("Starting saving") newimagecount = updatedimagecount = 0 imagestosave = [] for imagename in self.imagedictionary.keys(): dbimage = util.getimage(imagename) wikiimage = self.imagedictionary[imagename] if (dbimage is not None): dbimage.pageid = int(wikiimage[0]) dbimage.neighborhood = wikiimage[1] imagetosave = dbimage updatedimagecount = updatedimagecount + 1 else: imagetosave = ImageModel(pageid=int(wikiimage[0]), imageurl=imagename, neighborhood=wikiimage[1], usernameupdated='WikiUser') savedimagecount = savedimagecount + 1 imagestosave.append(imagetosave) try: db.put(imagestosave) except Exception, err: logging.error(str(err))
def __init__(self, parent=None, info=None, skin_type=None): """ Init the item. Sets all needed variables, if parent is given also inherit some settings from there. Set self.info to info if given. """ if not hasattr(self, 'type'): self.type = None # e.g. video, audio, dir, playlist self.name = u'' # name in menu self.parent = parent # parent item to pass unmapped event self.icon = None if info and isinstance(info, mediainfo.Info): self.info = copy.copy(info) else: self.info = mediainfo.Info(None, None, info) self.menuw = None self.description = '' self.eventhandler_plugins = [] if not hasattr(self, 'autovars'): self.autovars = [] if info and parent and hasattr(parent, 'DIRECTORY_USE_MEDIAID_TAG_NAMES') and \ parent.DIRECTORY_USE_MEDIAID_TAG_NAMES and self.info.has_key('title'): self.name = self.info['title'] if parent: self.image = parent.image if hasattr(parent, 'is_mainmenu_item'): self.image = None self.skin_fxd = parent.skin_fxd self.media = parent.media if hasattr(parent, '_'): self._ = parent._ else: self.image = None # imagefile self.skin_fxd = None # skin informationes etc. self.media = None self.fxd_file = None if skin_type: import skin settings = skin.get_settings() skin_info = settings.mainmenu.items imagedir = settings.mainmenu.imagedir if skin_info.has_key(skin_type): skin_info = skin_info[skin_type] self.name = _(skin_info.name) self.image = skin_info.image if skin_info.icon: self.icon = os.path.join(settings.icon_dir, skin_info.icon) if skin_info.outicon: self.outicon = os.path.join(settings.icon_dir, skin_info.outicon) if not self.image and imagedir: self.image = util.getimage(os.path.join(imagedir, skin_type))
def parse_name(self, name): # find image for tv show and build new name if config.VIDEO_SHOW_REGEXP_MATCH(name) and not self.network_play: show_name = config.VIDEO_SHOW_REGEXP_SPLIT(name) if show_name[0] and show_name[1] and show_name[2]: ep = config.IMDB_SEASON_EPISODE_FORMAT % (int( show_name[1]), int(show_name[2])) name = '%s %s %s' % (show_name[0], ep, show_name[3]) if config.VIDEO_SHOW_DATA_DIR: image = util.getimage( (config.VIDEO_SHOW_DATA_DIR + show_name[0].lower())) if self.filename and not image: image = util.getimage( os.path.join(os.path.dirname(self.filename), show_name[0].lower())) if image: self.image = image from video import tv_show_information if tv_show_information.has_key(show_name[0].lower()): tvinfo = tv_show_information[show_name[0].lower()] self.info.set_variables(tvinfo[1]) if not self.image: self.image = tvinfo[0] self.skin_fxd = tvinfo[3] self.mplayer_options = tvinfo[2] self.tv_show = True self.show_name = show_name self.subtitle = '%s - Season %s' % (show_name[0], show_name[1]) self.tv_show_name = show_name[0] self.tv_show_season = show_name[1] self.tv_show_episode = show_name[2] self.tv_show_title = show_name[3] if not hasattr(self, 'subtitle') or not self.subtitle: self.subtitle = self.parent['title'] self.title = name return self.format_name(name)
def __init__(self, command=None, directory=None): Item.__init__(self, skin_type='commands') self.display_type = 'commands' self.stoposd = False self.use_wm = False self.spawnwm = config.COMMAND_SPAWN_WM self.killwm = config.COMMAND_KILL_WM self.stdout = True if command and directory: self.name = command self.cmd = os.path.join(directory, command) self.image = util.getimage(self.cmd)
def parse_name(self, name): # find image for tv show and build new name if config.VIDEO_SHOW_REGEXP_MATCH(name) and not self.network_play: show_name = config.VIDEO_SHOW_REGEXP_SPLIT(name) if show_name[0] and show_name[1] and show_name[2]: ep = config.IMDB_SEASON_EPISODE_FORMAT % (int(show_name[1]), int(show_name[2])) name = '%s %s %s' % (show_name[0], ep, show_name[3]) if config.VIDEO_SHOW_DATA_DIR: image = util.getimage((config.VIDEO_SHOW_DATA_DIR + show_name[0].lower())) if self.filename and not image: image = util.getimage(os.path.join(os.path.dirname(self.filename), show_name[0].lower())) if image: self.image = image from video import tv_show_information if tv_show_information.has_key(show_name[0].lower()): tvinfo = tv_show_information[show_name[0].lower()] self.info.set_variables(tvinfo[1]) if not self.image: self.image = tvinfo[0] self.skin_fxd = tvinfo[3] self.mplayer_options = tvinfo[2] self.tv_show = True self.show_name = show_name self.subtitle = '%s - Season %s' % (show_name[0], show_name[1]) self.tv_show_name = show_name[0] self.tv_show_season = show_name[1] self.tv_show_episode = show_name[2] self.tv_show_title = show_name[3] if not hasattr(self, 'subtitle') or not self.subtitle: self.subtitle = self.parent['title'] self.title = name return self.format_name(name)
def __init__(self, command=None, directory=None): Item.__init__(self, skin_type='commands') self.display_type = 'commands' self.stoposd = False self.use_wm = False self.spawnwm = config.COMMAND_SPAWN_WM self.killwm = config.COMMAND_KILL_WM self.stdout = True self.rc = rc.get_singleton() if command and directory: self.name = command self.cmd = os.path.join(directory, command) self.image = util.getimage(self.cmd)
def dirinfo(self, diritem): """ set information for a diritem based on the content, etc. """ global tv_show_information if not diritem.image and config.VIDEO_SHOW_DATA_DIR: diritem.image = util.getimage(vfs.join(config.VIDEO_SHOW_DATA_DIR, vfs.basename(diritem.dir).lower())) if tv_show_information.has_key(vfs.basename(diritem.dir).lower()): tvinfo = tv_show_information[vfs.basename(diritem.dir).lower()] diritem.info.set_variables(tvinfo[1]) if not diritem.image: diritem.image = tvinfo[0] if not diritem.skin_fxd: diritem.skin_fxd = tvinfo[3]
def dirinfo(self, diritem): """ set informations for a diritem based on the content, etc. """ global tv_show_informations if not diritem.image and config.VIDEO_SHOW_DATA_DIR: diritem.image = util.getimage(vfs.join(config.VIDEO_SHOW_DATA_DIR, vfs.basename(diritem.dir).lower())) if tv_show_informations.has_key(vfs.basename(diritem.dir).lower()): tvinfo = tv_show_informations[vfs.basename(diritem.dir).lower()] diritem.info.set_variables(tvinfo[1]) if not diritem.image: diritem.image = tvinfo[0] if not diritem.skin_fxd: diritem.skin_fxd = tvinfo[3]
def fxdparser(fxd, node): """ parse commands out of a fxd file """ item = CommandItem() item.name = fxd.getattr(node, 'title') item.cmd = fxd.childcontent(node, 'cmd') item.image = util.getimage(item.cmd) if fxd.get_children(node, 'stoposd'): item.stoposd = True if fxd.get_children(node, 'spawnwm'): item.use_wm = True if fxd.get_children(node, 'nostdout'): item.stdout = False # parse <info> tag fxd.parse_info(fxd.get_children(node, 'info', 1), item) fxd.getattr(None, 'items', []).append(item)
def set_url(self, url, info=True, search_image=True): """ Set a new url to the item and adjust all attributes depending on the url. """ self.url = url # the url itself if not url: self.network_play = True # network url, like http self.filename = '' # filename if it's a file:// url self.mode = '' # the type of the url (file, http, dvd...) self.files = None # FileInformation self.mimetype = '' # extention or mode return if url.find('://') == -1: self.url = 'file://' + url self.files = FileInformation() if self.media: self.files.read_only = True self.mode = self.url[:self.url.find('://')] if self.mode == 'file': self.network_play = False self.filename = self.url[7:] self.files.append(self.filename) if search_image: image = util.getimage(self.filename[:self.filename.rfind('.')]) if image: self.image = image self.files.image = image elif self.parent and self.parent.type != 'dir': self.image = util.getimage(os.path.dirname(self.filename)+\ '/cover', self.image) if config.REMOVE_COMMERCIALS: edlBase=self.filename[:self.filename.rfind('.')] edlFile=edlBase+".edl" self.edl_file=edlFile if os.path.exists(edlFile): self.files.edl_file=edlFile else: self.files.edl_file=None self.mimetype = self.filename[self.filename.rfind('.')+1:].lower() if info: self.info = mediainfo.get(self.filename) try: if self.parent.DIRECTORY_USE_MEDIAID_TAG_NAMES: self.name = self.info['title'] or self.name except: pass if not self.name: self.name = self.info['title:filename'] if self.type == 'audio' and info: # Look for audio cover image by ID3 tags filename_array = { 'album' : self.info['album'], 'artist' : self.info['artist'] } for format_string in config.AUDIO_COVER_FORMAT_STRINGS: filemask = format_string % filename_array if format_string.startswith('/'): audiocover = util.getimage(filemask) else: audiocover = util.getimage(os.path.dirname(self.filename)+'/'+filemask) if audiocover: self.image = audiocover self.files.image = audiocover break; if not self.name: self.name = util.getname(self.filename) else: self.network_play = True self.filename = '' self.mimetype = self.type if not self.name: self.name = Unicode(self.url)
def parse_movie(fxd, node): """ Callback for VideoItem <movie>:: <movie title> <cover-img>file</cover-img> <video mplayer-options> <dvd|vcd|file id name media_id mplayer-options>file</>+ <variants> <variant> <part ref mplayer-options> <subtitle media_id>file</subtitle> <audio media_id>file</audio> </part>+ </variant>+ </variants> <info/> </movie> """ files = [] def parse_video_child(fxd, node, dirname): """ parse a subitem from <video> """ filename = String(fxd.gettext(node)) media_id = fxd.getattr(node, 'media-id') mode = node.name id = fxd.getattr(node, 'id') options = fxd.getattr(node, 'mplayer-options') player = fxd.childcontent(node, 'player') playlist = fxd.get_children(node, 'playlist') and True or False if mode == 'file': if not media_id: filename = os.path.join(dirname, filename) if vfs.isoverlay(filename): filename = vfs.normalize(filename) if filename and not filename in files: files.append(filename) if mode == 'url': return id, filename, media_id, options, player, playlist return id, String('%s://%s' % (String(mode), String(filename))), \ media_id, options, player, playlist item = VideoItem('', fxd.getattr(None, 'parent', None), parse=False) title = name=fxd.getattr(node, 'title') item.name = title dirname = os.path.dirname(fxd.filename) image = fxd.childcontent(node, 'cover-img') if image: try: image = vfs.abspath(os.path.join(dirname, str(image))) except UnicodeEncodeError: logger.debug('os.path.join(dirname=%r, item.image=%r)', dirname, item.image) raise item.image = image item.files.image = image else: # no image for this item, see if we have a cover img image = util.getimage(os.path.join(dirname, 'cover')) if image: item.image = image fxd.parse_info(node, item, {'runtime': 'length'}) video = fxd.get_children(node, 'video') if video: mplayer_options = fxd.getattr(video[0], 'mplayer-options') video = fxd.get_children(video[0], 'file') + \ fxd.get_children(video[0], 'vcd') + \ fxd.get_children(video[0], 'dvd') + \ fxd.get_children(video[0], 'url') variants = fxd.get_children(node, 'variants') if variants: variants = fxd.get_children(variants[0], 'variant') if variants: # a list of variants id = {} for v in video: video_child = parse_video_child(fxd, v, dirname) id[video_child[0]] = video_child for variant in variants: mplayer_options += " " + fxd.getattr(variant, 'mplayer-options'); parts = fxd.get_children(variant, 'part') if len(parts) == 1: # a variant with one file ref = fxd.getattr(parts[0] ,'ref') v = VideoItem(id[ref][1], parent=item, info=item.info, parse=False) v.files = None v.media_id, v.mplayer_options, player, is_playlist = id[ref][2:] if player: v.force_player = player if is_playlist: v.is_playlist = True audio = fxd.get_children(parts[0], 'audio') if audio: audio = { 'media_id': fxd.getattr(audio[0], 'media-id'), 'file' : fxd.gettext(audio[0]) } if not audio['media_id']: audio['file'] = os.path.join(dirname, audio['file']) else: audio = {} v.audio_file = audio subtitle = fxd.get_children(parts[0], 'subtitle') if subtitle: subtitle = { 'media_id': fxd.getattr(subtitle[0], 'media-id'), 'file' : fxd.gettext(subtitle[0]) } if not subtitle['media_id']: subtitle['file'] = os.path.join(dirname, subtitle['file']) else: subtitle = {} v.subtitle_file = subtitle # global <video> mplayer_options if mplayer_options: v.mplayer_options += mplayer_options else: # a variant with a list of files v = VideoItem('', parent=item, info=item.info, parse=False) for p in parts: ref = fxd.getattr(p ,'ref') audio = fxd.get_children(p, 'audio') subtitle = fxd.get_children(p, 'subtitle') if audio: audio = { 'media_id': fxd.getattr(audio[0], 'media-id'), 'file' : fxd.gettext(audio[0]) } if not audio['media_id']: audio['file'] = os.path.join(dirname, audio['file']) else: audio = {} if subtitle: subtitle = { 'media_id': fxd.getattr(subtitle[0], 'media-id'), 'file' : fxd.gettext(subtitle[0]) } if not subtitle['media_id']: subtitle['file'] = os.path.join(dirname, subtitle['file']) else: subtitle = {} sub = VideoItem(id[ref][1], parent=v, info=item.info, parse=False) sub.files = None sub.media_id, sub.mplayer_options, player, is_playlist = id[ref][2:] sub.subtitle_file = subtitle sub.audio_file = audio # global <video> mplayer_options if mplayer_options: sub.mplayer_options += mplayer_options v.subitems.append(sub) v.name = fxd.getattr(variant, 'name') item.variants.append(v) else: # one or more files, this is directly for the item try: id, url, item.media_id, item.mplayer_options, player, is_playlist = parse_video_child( fxd, video[0], dirname) except (IndexError, TypeError), why: logger.warning('%r is corrupt', fxd.filename) raise if url.startswith('file://') and os.path.isfile(url[7:]): variables = item.info.get_variables() item.set_url(url, info=True) item.info.set_variables(variables) elif url.startswith('file://') and os.path.isdir(url[7:]): # dvd dir variables = item.info.get_variables() item.set_url(url.replace('file://', 'dvd:/')+ '/VIDEO_TS/', info=True) item.info.set_variables(variables) else: item.set_url(url, info=False) # if title: # item.name = title if player: item.force_player = player if is_playlist: item.is_playlist = True if len(video) == 1: # global <video> mplayer_options if mplayer_options: item.mplayer_options += mplayer_options # if there is more than one item add them to subitems if len(video) > 1: # a list of files subitem_matched = False for s in video: #id, url, item.media_id, mplayer_options, player, is_playlist = parse_video_child(fxd, s, dirname) video_child = parse_video_child(fxd, s, dirname) url = video_child[1] v = VideoItem(url, parent=item, info=item.info, parse=False) if url.startswith('file://'): v.files = FileInformation() v.files.append(url[7:]) if url == item.url and not subitem_matched: subitem_matched = True v.files.fxd_file = fxd.filename if item.image: v.files.image = item.image else: v.files = None v.media_id, v.mplayer_options, player, is_playlist = video_child[2:] if player: v.force_player = player if is_playlist: item.is_playlist = True # global <movie> mplayer_options if mplayer_options: v.mplayer_options += ' ' + mplayer_options item.subitems.append(v)
def __init__(self, url, parent, info=None, parse=True): """ Create an instance of a VideoItem @param url: the pysudo URL for the VideoItem @param parent: the parent of the VideoItem @param info: controls if additional information is found @type info: boolean @param parse: controls if the url is parsed @type parse: boolean """ self.autovars = [] Item.__init__(self, parent) self.type = 'video' self.variants = [] self.subitems = [] self.current_subitem = None self.media_id = '' self.subtitle_file = {} self.audio_file = {} self.mplayer_options = '' self.tv_show = False self.video_width = 0 self.video_height = 0 self.selected_subtitle = None self.selected_audio = None self.elapsed = 0 self.possible_players = [] self.player = None self.player_rating = 0 # set the url (this influences the list of possible players!) self.set_url(url, info=parse) if info: self.info.set_variables(info) # deinterlacing and related things video_deinterlace = config.VIDEO_DEINTERLACE != None and config.VIDEO_DEINTERLACE or False self['deinterlace'] = video_deinterlace video_use_xvmc = config.VIDEO_USE_XVMC != None and config.VIDEO_USE_XVMC or False self['xvmc'] = video_use_xvmc video_field_dominance = config.VIDEO_FIELD_DOMINANCE != None and config.VIDEO_FIELD_DOMINANCE or False self['field-dominance'] = video_field_dominance # find image for tv show and build new title if config.VIDEO_SHOW_REGEXP_MATCH(self.name) and not self.network_play and config.VIDEO_SHOW_DATA_DIR: show_name = config.VIDEO_SHOW_REGEXP_SPLIT(self.name) if show_name[0] and show_name[1] and show_name[2] and show_name[3]: self.name = show_name[0] + u' ' + show_name[1] + u'x' + show_name[2] + u' - ' + show_name[3] image = util.getimage((config.VIDEO_SHOW_DATA_DIR + show_name[0].lower())) if self.filename and not image: image = util.getimage(os.path.join(os.path.dirname(self.filename), show_name[0].lower())) if image: self.image = image from video import tv_show_information if tv_show_information.has_key(show_name[0].lower()): tvinfo = tv_show_information[show_name[0].lower()] self.info.set_variables(tvinfo[1]) if not self.image: self.image = tvinfo[0] self.skin_fxd = tvinfo[3] self.mplayer_options = tvinfo[2] self.tv_show = True self.show_name = show_name self.tv_show_name = show_name[0] self.tv_show_ep = show_name[3] # extra info in discset_information if parent and parent.media: fid = String(parent.media.id) + self.filename[len(os.path.join(parent.media.mountdir,'')):] from video import discset_information if discset_information.has_key(fid): self.mplayer_options = discset_information[fid] if config.VIDEO_DEINTERLACE and self.info['interlaced']: # force deinterlacing self['deinterlace'] = True else: self['deinterlace'] = False
def set_cover_image(self, dir): """ we search for images within the archive, sort the result and get the first that matches and extract it to the tmp directory """ logger.log(9, 'set_cover_image(dir=%r)', dir) cover = util.getimage(os.path.join(dir, 'cover')) if cover: # nothing to do, image already exist logger.debug( 'Nothing to do, archive cover already exist, skipping...') return cover files = [] images = [] try: if zipfile.is_zipfile(self.archive): archive = zipfile.ZipFile(self.archive, 'r') files = archive.namelist() elif tarfile.is_tarfile(self.archive): archive = tarfile.open(self.archive, 'r') files = archive.getnames() elif ARCHIVE_RAR_AVAILABLE and rarfile.is_rarfile(self.archive): archive = rarfile.RarFile(self.archive, 'r') files = archive.namelist() except (ZipError, RarError, TarError) as exc: logger.warning('Archive %s error: %s', self.archive, exc) self.valid = False return None if len(files): # get the image plugin matches on image files stored in the archive logger.debug('Found %d items in the archive %s', len(files), self.archive) for p in plugin.mimetype('image'): logger.debug( 'Found mime plugin for type \'image\', querying now...') images.extend(util.find_matches(files, p.suffix())) logger.debug( 'Plugin reports %d images matches the suffix rule', len(images)) if len(images): logger.debug('Found %d images in the archive %s', len(images), self.archive) excl = re.compile('cover') for image in images: if re.search(excl, image): # there is a cover image in the archive already logger.debug('Found cover image %s in the archive', images[0]) try: archive.extract(image, dir) logger.debug('Cover image %s extracted to %s', image, dir) return os.path.join(dir, image) except (ZipError, RarError, TarError) as exc: # we tried to extract the cover but there is an error, # we will try another approach later on logger.warning('Archive extract %s error: %s', self.archive, exc) # no cover image in the archive, let's try to guess which one we could use as such # extract first image on the list, most likely it'll represet # a useful cover. This is definitely the case with cbz/cbr comics covers # first, we need sort all files to make sure that we have them in sequence images.sort(lambda l, o: cmp(l.upper(), o.upper())) # just for cleaner code image = images[0] logger.debug('Found suitable cover image %s in the archive', image) try: archive.extract(image, dir) ext = os.path.splitext(image)[1].lower().replace( 'jpeg', 'jpg') except (ZipError, RarError, TarError) as exc: # we tried to extract the image but there was an error, we give up logger.warning('Archive %s extract error: %s', self.archive, exc) return None try: os.symlink(os.path.join(dir, normalize(image)), os.path.join(dir, ('cover' + ext))) #shutil.copy(os.path.join(dir, normalize(image)), os.path.join(dir, ('cover' + ext))) logger.debug('Cover image %s, copied to %s', normalize(image), dir) except (OSError, ShutilError) as exc: logger.warning( 'Error while getting cover image for archive %s, %s', self.archive, exc) return None return os.path.join(dir, ('cover.' + ext)) logger.debug('Unable to find a suitable cover image for archive %s', self.archive) return None
class Identify_Thread(threading.Thread): """ Thread to watch the rom drives for changes """ def identify(self, media, force_rebuild=False): """ Try to find out as much as possible about the disc in the rom drive: title, image, play options, ... """ cds = media.get_drive_status() #media.log_drive_status(cds) # Same as last time? If so we're done if media.drive_status == cds: #_debug_('status not changed for drive %r' % (media.devicename)) return logger.debug('drive_status changed %s -> %s', media.drive_status, cds) media.drive_status = cds media.id = '' media.label = '' media.type = 'empty_cdrom' media.item = None media.videoitem = None media.cached = False # Is there a disc information? if media.drive_status == CDS_NO_INFO: logger.debug('cannot get the drive status for drive %r', media.devicename) return # Is there a disc present? if media.drive_status != CDS_DISC_OK: logger.debug('disc not ready for drive %r', media.devicename) return # try to set the speed try: fd = os.open(media.devicename, os.O_RDONLY | os.O_NONBLOCK) try: if media.can_select_speed and config.ROM_SPEED: try: ioctl(fd, CDROM_SELECT_SPEED, config.ROM_SPEED) except Exception, e: logger.debug('setting rom speed for %r failed: %s', media.devicename, e) finally: #_debug_('closing %r drive %r' % (fd, media.devicename)) try: os.close(fd) except Exception, e: logger.debug('closing %r failed: %s', media.devicename, e) except Exception, e: logger.debug('opening %r failed: %s', media.devicename, e) return # if there is a disc, the tray can't be open media.tray_open = False disc_info = util.mediainfo.disc_info(media, force_rebuild) if not disc_info: logger.debug('no disc information for drive %r', media.devicename) return info = disc_info.discinfo if not info: logger.debug('no info for drive %r', media.devicename) return if info['mime'] == 'audio/cd': media.id = disc_id = info['id'] media.item = AudioDiskItem(disc_id, parent=None, devicename=media.devicename, display_type='audio') media.type = 'audio' media.item.media = media if info['title']: media.item.name = info['title'] media.item.info = disc_info logger.debug('playing audio in drive %r', media.devicename) return image = title = movie_info = more_info = fxd_file = None media.id = info['id'] media.label = info['label'] media.type = 'cdrom' label = info['label'] # is the id in the database? if media.id in video.fxd_database['id']: movie_info = video.fxd_database['id'][media.id] if movie_info: title = movie_info.name else: # no? Maybe we can find a label regexp match for (re_label, movie_info_t) in video.fxd_database['label']: if re_label.match(media.label): movie_info = movie_info_t if movie_info_t.name: title = movie_info.name m = re_label.match(media.label).groups() re_count = 1 # found, now change the title with the regexp. E.g.: # label is "bla_2", the label regexp "bla_[0-9]" and the title # is "Something \1", the \1 will be replaced with the first item # in the regexp group, here 2. The title is now "Something 2" for g in m: title = string.replace(title, '\\%s' % re_count, g) re_count += 1 break if movie_info: image = movie_info.image # DVD/VCD/SVCD: if info['mime'] in ('video/vcd', 'video/dvd'): if not title: title = media.label.replace('_', ' ').lstrip().rstrip() title = '%s [%s]' % (info['mime'][6:].upper(), title) if movie_info: media.item = copy.copy(movie_info) else: media.item = VideoItem('', None) media.item.image = util.getimage( os.path.join(config.OVERLAY_DIR, 'disc-set', media.id)) variables = media.item.info.variables media.item.info = disc_info media.item.info.set_variables(variables) media.item.name = title media.item.url = info['mime'][6:] + '://' media.item.media = media media.type = info['mime'][6:] media.item.info.mmdata = info logger.debug('playing video in drive %r', media.devicename) return # Disc is data of some sort. Mount it to get the file info util.mount(media.mountdir, force=True) try: if os.path.isdir(os.path.join(media.mountdir, 'VIDEO_TS')) or \ os.path.isdir(os.path.join(media.mountdir, 'video_ts')): if force_rebuild: logger.debug('Double check without success') else: logger.debug('Undetected DVD, checking again') media.drive_status = CDS_NO_DISC return self.identify(media, True) # Check for movies/audio/images on the disc num_video = disc_info['disc_num_video'] num_audio = disc_info['disc_num_audio'] num_image = disc_info['disc_num_image'] video_files = util.match_files(media.mountdir, config.VIDEO_SUFFIX) logger.debug('video_files=%r', video_files) media.item = DirItem(media.mountdir, None, create_metainfo=False) media.item.info = disc_info finally: util.umount(media.mountdir) # if there is a video file on the root dir of the disc, we guess # it's a video disc. There may also be audio files and images, but # they only belong to the movie if video_files: media.type = 'video' # try to find out if it is a series cd if not title: show_name = "" the_same = 1 volumes = '' start_ep = 0 end_ep = 0 video_files.sort(lambda l, o: cmp(l.upper(), o.upper())) for movie in video_files: if config.VIDEO_SHOW_REGEXP_MATCH(movie): show = config.VIDEO_SHOW_REGEXP_SPLIT( os.path.basename(movie)) if show_name and show_name != show[0]: the_same = 0 if not show_name: show_name = show[0] if volumes: volumes += ', ' current_ep = int(show[1]) * 100 + int(show[2]) if end_ep and current_ep == end_ep + 1: end_ep = current_ep elif not end_ep: end_ep = current_ep else: end_ep = -1 if not start_ep: start_ep = end_ep volumes += show[1] + "x" + show[2] if show_name and the_same and config.VIDEO_SHOW_DATA_DIR: if end_ep > 0: volumes = '%dx%02d - %dx%02d' % ( start_ep / 100, start_ep % 100, end_ep / 100, end_ep % 100) k = config.VIDEO_SHOW_DATA_DIR + show_name if os.path.isfile((k + ".png").lower()): image = (k + ".png").lower() elif os.path.isfile((k + ".jpg").lower()): image = (k + ".jpg").lower() title = show_name + ' (' + volumes + ')' if video.tv_show_information.has_key(show_name.lower()): tvinfo = video.tv_show_information[show_name.lower()] more_info = tvinfo[1] if not image: image = tvinfo[0] if not fxd_file: fxd_file = tvinfo[3] elif (not show_name) and len(video_files) == 1: movie = video_files[0] title = os.path.splitext(os.path.basename(movie))[0] # nothing found, give up: return the label if not title: title = label # If there are no videos and only audio files (and maybe images) # it is an audio disc (autostart will auto play everything) elif not num_video and num_audio: media.type = 'audio' title = '%s [%s]' % (media.drivename, label) # Only images? OK than, make it an image disc elif not num_video and not num_audio and num_image: media.type = 'image' title = '%s [%s]' % (media.drivename, label) # Mixed media? elif num_video or num_audio or num_image: media.type = None title = '%s [%s]' % (media.drivename, label) # Strange, no useable files else: media.type = None title = '%s [%s]' % (media.drivename, label) # set the info we have now if title: media.item.name = title if image: media.item.image = image if more_info: media.item.info.set_variables(more_info) if fxd_file and not media.item.fxd_file: media.item.set_fxd_file(fxd_file) # One video in the root dir. This sounds like a disc with one # movie on it. Save the information about it and autostart will # play this. if len(video_files) == 1 and media.item['num_dir_items'] == 0: util.mount(media.mountdir) try: if movie_info: media.videoitem = copy.deepcopy(movie_info) else: media.videoitem = VideoItem(video_files[0], None) finally: util.umount(media.mountdir) media.videoitem.media = media media.videoitem.media_id = media.id # set the info we have if title: media.videoitem.name = title if image: media.videoitem.image = image if more_info: media.videoitem.set_variables(more_info) if fxd_file: media.videoitem.fxd_file = fxd_file media.item.media = media
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 __init__(self, parent=None, info=None, skin_type=None): """ Create an instance of an Item. @param parent: parent of the Item. @param info: info item of the Item. @param skin_type: skin type of the Item. """ if not hasattr(self, 'type'): self.type = None # e.g. video, audio, dir, playlist self.name = u'' # name in menu self.parent = parent # parent item to pass unmapped event self.icon = None if info and isinstance(info, mediainfo.Info): self.info = copy.copy(info) else: self.info = mediainfo.Info(None, None, info) self.menuw = None self.description = '' self.rect = pygame.Rect(0,0,0,0) self.image = None # imagefile self.skin_fxd = None # skin information etc. self.media = None self.fxd_file = None self.network_play = True # network url, like http self.filename = '' # filename if it's a file:// url self.mode = '' # the type of the url (file, http, dvd...) self.files = None # FileInformation self.mimetype = '' # extention or mode self.eventhandler_plugins = [] if not hasattr(self, 'autovars'): self.autovars = [] if info and parent and hasattr(parent, 'DIRECTORY_USE_MEDIAID_TAG_NAMES') and \ parent.DIRECTORY_USE_MEDIAID_TAG_NAMES and self.info.has_key('title'): self.name = self.info['title'] if parent: self.image = parent.image if hasattr(parent, 'is_mainmenu_item'): self.image = None self.skin_fxd = parent.skin_fxd self.media = parent.media if hasattr(parent, '_'): self._ = parent._ if skin_type: import skin settings = skin.get_settings() skin_info = settings.mainmenu.items imagedir = settings.mainmenu.imagedir if skin_info.has_key(skin_type): skin_info = skin_info[skin_type] self.name = _(skin_info.name) self.image = skin_info.image if skin_info.icon: self.icon = os.path.join(settings.icon_dir, skin_info.icon) if skin_info.outicon: self.outicon = os.path.join(settings.icon_dir, skin_info.outicon) if not self.image and imagedir: self.image = util.getimage(os.path.join(imagedir, skin_type))
def set_url(self, url, info=True, search_image=True): """ Set a new url to the item and adjust all attributes depending on the url. WARNING: This is called whenever self.url is set, therefor it is strictly forbidden to set self.url directly in this function, (infinit recursion!). Use self.__dict__['url'] instead! """ # set the url itself if url and url.find('://') == -1: # local url self.__dict__['url'] = 'file://' + url else: # some other kind of url self.__dict__['url'] = url if self.url==None: # reset everything to default values self.network_play = True self.filename = '' self.mode = '' self.files = None self.mimetype = '' return # add additional info files self.files = FileInformation() if self.media: self.files.read_only = True # determine the mode of this item self.mode = self.url[:self.url.find('://')] if self.mode == 'file': self.network_play = False self.filename = self.url[7:] self.files.append(self.filename) self.mimetype = os.path.splitext(self.filename)[1][1:].lower() if search_image: image = util.getimage(self.filename[:self.filename.rfind('.')]) if image: self.image = image self.files.image = image elif self.parent and self.parent.type != 'dir': imagepath= os.path.dirname(self.filename) imagepath= os.path.join(imagepath, 'cover') self.image = util.getimage(imagepath, self.image) # TODO: is this the right place for this? if config.TV_RECORD_REMOVE_COMMERCIALS: edlBase=self.filename[:self.filename.rfind('.')] edlFile=edlBase+".edl" self.edl_file=edlFile if os.path.exists(edlFile): self.files.edl_file=edlFile else: self.files.edl_file=None if info: self.info = mediainfo.get(self.filename) try: if self.parent.DIRECTORY_USE_MEDIAID_TAG_NAMES: self.name = self.info['title'] or self.name except: pass if not self.name: self.name = self.info['title:filename'] if not self.name: self.name = util.getname(self.filename) else: # some defaults for other url types self.network_play = True self.filename = '' self.mimetype = self.type if not self.name: self.name = Unicode(self.url)
def identify(self, media, force_rebuild=False): """ magic! Try to find out as much as possible about the disc in the rom drive: title, image, play options, ... """ # Check drive status (tray pos, disc ready) try: CDSL_CURRENT = ((int)(~0 >> 1)) fd = os.open(media.devicename, os.O_RDONLY | os.O_NONBLOCK) if os.uname()[0] == 'FreeBSD': try: data = array.array('c', '\000' * 4096) (address, length) = data.buffer_info() buf = pack('BBHP', CD_MSF_FORMAT, 0, length, address) s = ioctl(fd, CDIOREADTOCENTRYS, buf) s = CDS_DISC_OK except: s = CDS_NO_DISC else: s = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) except: # maybe we need to close the fd if ioctl fails, maybe # open fails and there is no fd try: os.close(fd) except: pass media.drive_status = None return # Same as last time? If so we're done if s == media.drive_status: os.close(fd) return media.drive_status = s media.id = '' media.label = '' media.type = 'empty_cdrom' media.item = None media.videoitem = None media.cached = False # Is there a disc present? if s != CDS_DISC_OK: os.close(fd) return # if there is a disc, the tray can't be open media.tray_open = False disc_info = util.mediainfo.disc_info(media, force_rebuild) if not disc_info: # bad disc, e.g. blank disc. os.close(fd) return data = disc_info.mmdata # try to set the speed if config.ROM_SPEED and data and not data['mime'] == 'video/dvd': try: ioctl(fd, CDROM_SELECT_SPEED, config.ROM_SPEED) except: pass if data and data['mime'] == 'audio/cd': os.close(fd) disc_id = data['id'] media.item = AudioDiskItem(disc_id, parent=None, devicename=media.devicename, display_type='audio') media.type = media.item.type media.item.media = media if data['title']: media.item.name = data['title'] media.item.info = disc_info return os.close(fd) image = title = movie_info = more_info = fxd_file = None media.id = data['id'] media.label = data['label'] media.type = 'cdrom' label = data['label'] # is the id in the database? if media.id in video.fxd_database['id']: movie_info = video.fxd_database['id'][media.id] if movie_info: title = movie_info.name # no? Maybe we can find a label regexp match else: for (re_label, movie_info_t) in video.fxd_database['label']: if re_label.match(media.label): movie_info = movie_info_t if movie_info_t.name: title = movie_info.name m = re_label.match(media.label).groups() re_count = 1 # found, now change the title with the regexp. E.g.: # label is "bla_2", the label regexp "bla_[0-9]" and the title # is "Something \1", the \1 will be replaced with the first item # in the regexp group, here 2. The title is now "Something 2" for g in m: title = string.replace(title, '\\%s' % re_count, g) re_count += 1 break if movie_info: image = movie_info.image # DVD/VCD/SVCD: # There is data from mmpython for these three types if data['mime'] in ('video/vcd', 'video/dvd'): if not title: title = media.label.replace('_', ' ').lstrip().rstrip() title = '%s [%s]' % (data['mime'][6:].upper(), title) if movie_info: media.item = copy.copy(movie_info) else: media.item = VideoItem('', None) media.item.image = util.getimage( os.path.join(config.OVERLAY_DIR, 'disc-set', media.id)) variables = media.item.info.variables media.item.info = disc_info media.item.info.set_variables(variables) media.item.name = title media.item.set_url(data['mime'][6:] + '://') media.item.media = media media.type = data['mime'][6:] media.item.info.mmdata = data return # Disc is data of some sort. Mount it to get the file info util.mount(media.mountdir, force=True) if os.path.isdir(os.path.join(media.mountdir, 'VIDEO_TS')) or \ os.path.isdir(os.path.join(media.mountdir, 'video_ts')): if force_rebuild: _debug_('Double check without success') else: _debug_('Undetected DVD, checking again') media.drive_status = CDS_NO_DISC util.umount(media.mountdir) return self.identify(media, True) # Check for movies/audio/images on the disc num_video = disc_info['disc_num_video'] num_audio = disc_info['disc_num_audio'] num_image = disc_info['disc_num_image'] video_files = util.match_files(media.mountdir, config.VIDEO_SUFFIX) _debug_('identifymedia: mplayer = "%s"' % video_files, level=2) media.item = DirItem(media.mountdir, None, create_metainfo=False) media.item.info = disc_info util.umount(media.mountdir) # if there is a video file on the root dir of the disc, we guess # it's a video disc. There may also be audio files and images, but # they only belong to the movie if video_files: media.type = 'video' # try to find out if it is a series cd if not title: show_name = "" the_same = 1 volumes = '' start_ep = 0 end_ep = 0 video_files.sort(lambda l, o: cmp(l.upper(), o.upper())) for movie in video_files: if config.VIDEO_SHOW_REGEXP_MATCH(movie): show = config.VIDEO_SHOW_REGEXP_SPLIT( os.path.basename(movie)) if show_name and show_name != show[0]: the_same = 0 if not show_name: show_name = show[0] if volumes: volumes += ', ' current_ep = int(show[1]) * 100 + int(show[2]) if end_ep and current_ep == end_ep + 1: end_ep = current_ep elif not end_ep: end_ep = current_ep else: end_ep = -1 if not start_ep: start_ep = end_ep volumes += show[1] + "x" + show[2] if show_name and the_same and config.VIDEO_SHOW_DATA_DIR: if end_ep > 0: volumes = '%dx%02d - %dx%02d' % ( start_ep / 100, start_ep % 100, end_ep / 100, end_ep % 100) k = config.VIDEO_SHOW_DATA_DIR + show_name if os.path.isfile((k + ".png").lower()): image = (k + ".png").lower() elif os.path.isfile((k + ".jpg").lower()): image = (k + ".jpg").lower() title = show_name + ' (' + volumes + ')' if video.tv_show_informations.has_key(show_name.lower()): tvinfo = video.tv_show_informations[show_name.lower()] more_info = tvinfo[1] if not image: image = tvinfo[0] if not fxd_file: fxd_file = tvinfo[3] elif (not show_name) and len(video_files) == 1: movie = video_files[0] title = os.path.splitext(os.path.basename(movie))[0] # nothing found, give up: return the label if not title: title = label # If there are no videos and only audio files (and maybe images) # it is an audio disc (autostart will auto play everything) elif not num_video and num_audio: media.type = 'audio' title = '%s [%s]' % (media.drivename, label) # Only images? OK than, make it an image disc elif not num_video and not num_audio and num_image: media.type = 'image' title = '%s [%s]' % (media.drivename, label) # Mixed media? elif num_video or num_audio or num_image: media.type = None title = '%s [%s]' % (media.drivename, label) # Strange, no useable files else: media.type = None title = '%s [%s]' % (media.drivename, label) # set the infos we have now if title: media.item.name = title if image: media.item.image = image if more_info: media.item.info.set_variables(more_info) if fxd_file and not media.item.fxd_file: media.item.set_fxd_file(fxd_file) # One video in the root dir. This sounds like a disc with one # movie on it. Save the information about it and autostart will # play this. if len(video_files) == 1 and media.item['num_dir_items'] == 0: util.mount(media.mountdir) if movie_info: media.videoitem = copy.deepcopy(movie_info) else: media.videoitem = VideoItem(video_files[0], None) util.umount(media.mountdir) media.videoitem.media = media media.videoitem.media_id = media.id # set the infos we have if title: media.videoitem.name = title if image: media.videoitem.image = image if more_info: media.videoitem.set_variables(more_info) if fxd_file: media.videoitem.fxd_file = fxd_file media.item.media = media return
def __init__(self, url, parent, info=None, parse=True): """ Create an instance of a VideoItem @param url: the pysudo URL for the VideoItem @param parent: the parent of the VideoItem @param info: controls if additional information is found @type info: boolean @param parse: controls if the url is parsed @type parse: boolean """ self.autovars = [] Item.__init__(self, parent) self.type = 'video' self.variants = [] self.subitems = [] self.current_subitem = None self.media_id = '' self.subtitle_file = {} self.audio_file = {} self.mplayer_options = '' self.tv_show = False self.video_width = 0 self.video_height = 0 self.selected_subtitle = None self.selected_audio = None self.elapsed = 0 self.possible_players = [] self.player = None self.player_rating = 0 # set the url (this influences the list of possible players!) self.set_url(url, info=parse) if info: self.info.set_variables(info) # deinterlacing and related things video_deinterlace = config.VIDEO_DEINTERLACE != None and config.VIDEO_DEINTERLACE or False self['deinterlace'] = video_deinterlace video_use_xvmc = config.VIDEO_USE_XVMC != None and config.VIDEO_USE_XVMC or False self['xvmc'] = video_use_xvmc video_field_dominance = config.VIDEO_FIELD_DOMINANCE != None and config.VIDEO_FIELD_DOMINANCE or False self['field-dominance'] = video_field_dominance # find image for tv show and build new title if config.VIDEO_SHOW_REGEXP_MATCH( self.name ) and not self.network_play and config.VIDEO_SHOW_DATA_DIR: show_name = config.VIDEO_SHOW_REGEXP_SPLIT(self.name) if show_name[0] and show_name[1] and show_name[2] and show_name[3]: self.name = show_name[0] + u' ' + show_name[ 1] + u'x' + show_name[2] + u' - ' + show_name[3] image = util.getimage( (config.VIDEO_SHOW_DATA_DIR + show_name[0].lower())) if self.filename and not image: image = util.getimage( os.path.join(os.path.dirname(self.filename), show_name[0].lower())) if image: self.image = image from video import tv_show_information if tv_show_information.has_key(show_name[0].lower()): tvinfo = tv_show_information[show_name[0].lower()] self.info.set_variables(tvinfo[1]) if not self.image: self.image = tvinfo[0] self.skin_fxd = tvinfo[3] self.mplayer_options = tvinfo[2] self.tv_show = True self.show_name = show_name self.tv_show_name = show_name[0] self.tv_show_ep = show_name[3] # extra info in discset_information if parent and parent.media: fid = String( parent.media.id ) + self.filename[len(os.path.join(parent.media.mountdir, '')):] from video import discset_information if discset_information.has_key(fid): self.mplayer_options = discset_information[fid] if config.VIDEO_DEINTERLACE and self.info['interlaced']: # force deinterlacing self['deinterlace'] = True else: self['deinterlace'] = False
def __init__(self, parent=None, info=None, skin_type=None): """ Create an instance of an Item. @param parent: parent of the Item. @param info: info item of the Item. @param skin_type: skin type of the Item. """ if not hasattr(self, 'type'): self.type = None # e.g. video, audio, dir, playlist self.name = u'' # name in menu self.parent = parent # parent item to pass unmapped event self.icon = None if info and isinstance(info, mediainfo.Info): self.info = copy.copy(info) else: self.info = mediainfo.Info(None, None, info) self.menuw = None self.description = '' self.rect = pygame.Rect(0, 0, 0, 0) self.image = None # imagefile self.skin_fxd = None # skin information etc. self.media = None self.fxd_file = None self.network_play = True # network url, like http self.filename = '' # filename if it's a file:// url self.mode = '' # the type of the url (file, http, dvd...) self.files = None # FileInformation self.mimetype = '' # extention or mode self.eventhandler_plugins = [] if not hasattr(self, 'autovars'): self.autovars = [] if info and parent and hasattr(parent, 'DIRECTORY_USE_MEDIAID_TAG_NAMES') and \ parent.DIRECTORY_USE_MEDIAID_TAG_NAMES and self.info.has_key('title'): self.name = self.info['title'] if parent: self.image = parent.image if hasattr(parent, 'is_mainmenu_item'): self.image = None self.skin_fxd = parent.skin_fxd self.media = parent.media if hasattr(parent, '_'): self._ = parent._ if skin_type: import skin settings = skin.get_settings() skin_info = settings.mainmenu.items imagedir = settings.mainmenu.imagedir if skin_info.has_key(skin_type): skin_info = skin_info[skin_type] self.name = _(skin_info.name) self.image = skin_info.image if skin_info.icon: self.icon = os.path.join(settings.icon_dir, skin_info.icon) if skin_info.outicon: self.outicon = os.path.join(settings.icon_dir, skin_info.outicon) if not self.image and imagedir: self.image = util.getimage(os.path.join(imagedir, skin_type))
def __init__(self, url, parent, info=None, parse=True): self.autovars = [('deinterlace', 0)] Item.__init__(self, parent) self.type = 'video' self.set_url(url, info=parse) if info: self.info.set_variables(info) self.variants = [] # if this item has variants self.subitems = [] # more than one file/track to play self.current_subitem = None self.media_id = '' self.subtitle_file = {} # text subtitles self.audio_file = {} # audio dubbing self.mplayer_options = '' self.tv_show = False self.video_width = 0 self.video_height = 0 self.selected_subtitle = None self.selected_audio = None self.elapsed = 0 self.possible_player = [] self.player = None self.player_rating = 0 # find image for tv show and build new title if config.VIDEO_SHOW_REGEXP_MATCH(self.name) and not self.network_play and \ config.VIDEO_SHOW_DATA_DIR: show_name = config.VIDEO_SHOW_REGEXP_SPLIT(self.name) if show_name[0] and show_name[1] and show_name[2] and show_name[3]: self.name = show_name[0] + u' ' + show_name[1] + u'x' + show_name[2] +\ u' - ' + show_name[3] image = util.getimage((config.VIDEO_SHOW_DATA_DIR + \ show_name[0].lower())) if self.filename and not image: image = util.getimage(os.path.dirname(self.filename) + '/' + \ show_name[0].lower()) if image: self.image = image from video import tv_show_informations if tv_show_informations.has_key(show_name[0].lower()): tvinfo = tv_show_informations[show_name[0].lower()] self.info.set_variables(tvinfo[1]) if not self.image: self.image = tvinfo[0] self.skin_fxd = tvinfo[3] self.mplayer_options = tvinfo[2] self.tv_show = True self.show_name = show_name self.tv_show_name = show_name[0] self.tv_show_ep = show_name[3] # extra infos in discset_informations if parent and parent.media: fid = parent.media.id + \ self.filename[len(os.path.join(parent.media.mountdir,'')):] from video import discset_informations if discset_informations.has_key(fid): self.mplayer_options = discset_informations[fid]
def set_url(self, url, info=True, search_image=True): """ Set a new url to the item and adjust all attributes depending on the url. WARNING: This is called whenever self.url is set, therefor it is strictly forbidden to set self.url directly in this function, (infinit recursion!). Use self.__dict__['url'] instead! """ # set the url itself if url and url.find('://') == -1: # local url self.__dict__['url'] = 'file://' + url else: # some other kind of url self.__dict__['url'] = url if self.url == None: # reset everything to default values self.network_play = True self.filename = '' self.mode = '' self.files = None self.mimetype = '' return # add additional info files self.files = FileInformation() if self.media: self.files.read_only = True # determine the mode of this item self.mode = self.url[:self.url.find('://')] if self.mode == 'file': self.network_play = False self.filename = self.url[7:] self.files.append(self.filename) self.mimetype = os.path.splitext(self.filename)[1][1:].lower() if search_image: image = util.getimage(self.filename[:self.filename.rfind('.')]) if image: self.image = image self.files.image = image elif self.parent and self.parent.type != 'dir': imagepath = os.path.dirname(self.filename) imagepath = os.path.join(imagepath, 'cover') self.image = util.getimage(imagepath, self.image) # TODO: is this the right place for this? if config.TV_RECORD_REMOVE_COMMERCIALS: edlBase = self.filename[:self.filename.rfind('.')] edlFile = edlBase + ".edl" self.edl_file = edlFile if os.path.exists(edlFile): self.files.edl_file = edlFile else: self.files.edl_file = None if info: self.info = mediainfo.get(self.filename) try: if self.parent.DIRECTORY_USE_MEDIAID_TAG_NAMES: self.name = self.info['title'] or self.name except: pass if not self.name: self.name = self.info['title:filename'] if not self.name: self.name = util.getname(self.filename) else: # some defaults for other url types self.network_play = True self.filename = '' self.mimetype = self.type if not self.name: self.name = Unicode(self.url)
def set_cover_image(self, dir): """ we search for images within the archive, sort the result and get the first that matches and extract it to the tmp directory """ logger.log(9, 'set_cover_image(dir=%r)', dir) cover = util.getimage(os.path.join(dir, 'cover')) if cover: # nothing to do, image already exist logger.debug('Nothing to do, archive cover already exist, skipping...') return cover files = [] images = [] try: if zipfile.is_zipfile(self.archive): archive = zipfile.ZipFile(self.archive, 'r') files = archive.namelist() elif tarfile.is_tarfile(self.archive): archive = tarfile.open(self.archive, 'r') files = archive.getnames() elif ARCHIVE_RAR_AVAILABLE and rarfile.is_rarfile(self.archive): archive = rarfile.RarFile(self.archive, 'r') files = archive.namelist() except (ZipError, RarError, TarError) as exc: logger.warning('Archive %s error: %s', self.archive, exc) self.valid = False return None if len(files): # get the image plugin matches on image files stored in the archive logger.debug('Found %d items in the archive %s', len(files), self.archive) for p in plugin.mimetype('image'): logger.debug('Found mime plugin for type \'image\', querying now...') images.extend(util.find_matches(files, p.suffix())) logger.debug('Plugin reports %d images matches the suffix rule', len(images)) if len(images): logger.debug('Found %d images in the archive %s', len(images), self.archive) excl = re.compile('cover') for image in images: if re.search(excl, image): # there is a cover image in the archive already logger.debug('Found cover image %s in the archive', images[0]) try: archive.extract(image, dir) logger.debug('Cover image %s extracted to %s', image, dir) return os.path.join(dir, image) except (ZipError, RarError, TarError) as exc: # we tried to extract the cover but there is an error, # we will try another approach later on logger.warning('Archive extract %s error: %s', self.archive, exc) # no cover image in the archive, let's try to guess which one we could use as such # extract first image on the list, most likely it'll represet # a useful cover. This is definitely the case with cbz/cbr comics covers # first, we need sort all files to make sure that we have them in sequence images.sort(lambda l, o: cmp(l.upper(), o.upper())) # just for cleaner code image = images[0] logger.debug('Found suitable cover image %s in the archive', image) try: archive.extract(image, dir) ext = os.path.splitext(image)[1].lower().replace('jpeg', 'jpg') except (ZipError, RarError, TarError) as exc: # we tried to extract the image but there was an error, we give up logger.warning('Archive %s extract error: %s', self.archive, exc) return None try: os.symlink(os.path.join(dir, normalize(image)), os.path.join(dir, ('cover' + ext))) #shutil.copy(os.path.join(dir, normalize(image)), os.path.join(dir, ('cover' + ext))) logger.debug('Cover image %s, copied to %s', normalize(image), dir) except (OSError, ShutilError) as exc: logger.warning('Error while getting cover image for archive %s, %s', self.archive, exc) return None return os.path.join(dir, ('cover.' + ext)) logger.debug('Unable to find a suitable cover image for archive %s', self.archive) return None
def parse_movie(fxd, node): """ Callback for VideoItem <movie>:: <movie title> <cover-img>file</cover-img> <video mplayer-options> <dvd|vcd|file id name media_id mplayer-options>file</>+ <variants> <variant> <part ref mplayer-options> <subtitle media_id>file</subtitle> <audio media_id>file</audio> </part>+ </variant>+ </variants> <info/> </movie> """ files = [] def parse_video_child(fxd, node, dirname): """ parse a subitem from <video> """ filename = String(fxd.gettext(node)) media_id = fxd.getattr(node, 'media-id') mode = node.name id = fxd.getattr(node, 'id') options = fxd.getattr(node, 'mplayer-options') player = fxd.childcontent(node, 'player') playlist = fxd.get_children(node, 'playlist') and True or False if mode == 'file': if not media_id: filename = os.path.join(dirname, filename) if vfs.isoverlay(filename): filename = vfs.normalize(filename) if filename and not filename in files: files.append(filename) if mode == 'url': return id, filename, media_id, options, player, playlist return id, String('%s://%s' % (String(mode), String(filename))), \ media_id, options, player, playlist item = VideoItem('', fxd.getattr(None, 'parent', None), parse=False) title = name = fxd.getattr(node, 'title') item.name = title dirname = os.path.dirname(fxd.filename) image = fxd.childcontent(node, 'cover-img') if image: try: image = vfs.abspath(os.path.join(dirname, str(image))) except UnicodeEncodeError: logger.debug('os.path.join(dirname=%r, item.image=%r)', dirname, item.image) raise item.image = image item.files.image = image else: # no image for this item, see if we have a cover img image = util.getimage(os.path.join(dirname, 'cover')) if image: item.image = image fxd.parse_info(node, item, {'runtime': 'length'}) video = fxd.get_children(node, 'video') if video: mplayer_options = fxd.getattr(video[0], 'mplayer-options') video = fxd.get_children(video[0], 'file') + \ fxd.get_children(video[0], 'vcd') + \ fxd.get_children(video[0], 'dvd') + \ fxd.get_children(video[0], 'url') variants = fxd.get_children(node, 'variants') if variants: variants = fxd.get_children(variants[0], 'variant') if variants: # a list of variants id = {} for v in video: video_child = parse_video_child(fxd, v, dirname) id[video_child[0]] = video_child for variant in variants: mplayer_options += " " + fxd.getattr(variant, 'mplayer-options') parts = fxd.get_children(variant, 'part') if len(parts) == 1: # a variant with one file ref = fxd.getattr(parts[0], 'ref') v = VideoItem(id[ref][1], parent=item, info=item.info, parse=False) v.files = None v.media_id, v.mplayer_options, player, is_playlist = id[ref][ 2:] if player: v.force_player = player if is_playlist: v.is_playlist = True audio = fxd.get_children(parts[0], 'audio') if audio: audio = { 'media_id': fxd.getattr(audio[0], 'media-id'), 'file': fxd.gettext(audio[0]) } if not audio['media_id']: audio['file'] = os.path.join(dirname, audio['file']) else: audio = {} v.audio_file = audio subtitle = fxd.get_children(parts[0], 'subtitle') if subtitle: subtitle = { 'media_id': fxd.getattr(subtitle[0], 'media-id'), 'file': fxd.gettext(subtitle[0]) } if not subtitle['media_id']: subtitle['file'] = os.path.join( dirname, subtitle['file']) else: subtitle = {} v.subtitle_file = subtitle # global <video> mplayer_options if mplayer_options: v.mplayer_options += mplayer_options else: # a variant with a list of files v = VideoItem('', parent=item, info=item.info, parse=False) for p in parts: ref = fxd.getattr(p, 'ref') audio = fxd.get_children(p, 'audio') subtitle = fxd.get_children(p, 'subtitle') if audio: audio = { 'media_id': fxd.getattr(audio[0], 'media-id'), 'file': fxd.gettext(audio[0]) } if not audio['media_id']: audio['file'] = os.path.join( dirname, audio['file']) else: audio = {} if subtitle: subtitle = { 'media_id': fxd.getattr(subtitle[0], 'media-id'), 'file': fxd.gettext(subtitle[0]) } if not subtitle['media_id']: subtitle['file'] = os.path.join( dirname, subtitle['file']) else: subtitle = {} sub = VideoItem(id[ref][1], parent=v, info=item.info, parse=False) sub.files = None sub.media_id, sub.mplayer_options, player, is_playlist = id[ ref][2:] sub.subtitle_file = subtitle sub.audio_file = audio # global <video> mplayer_options if mplayer_options: sub.mplayer_options += mplayer_options v.subitems.append(sub) v.name = fxd.getattr(variant, 'name') item.variants.append(v) else: # one or more files, this is directly for the item try: id, url, item.media_id, item.mplayer_options, player, is_playlist = parse_video_child( fxd, video[0], dirname) except (IndexError, TypeError), why: logger.warning('%r is corrupt', fxd.filename) raise if url.startswith('file://') and os.path.isfile(url[7:]): variables = item.info.get_variables() item.set_url(url, info=True) item.info.set_variables(variables) elif url.startswith('file://') and os.path.isdir(url[7:]): # dvd dir variables = item.info.get_variables() item.set_url(url.replace('file://', 'dvd:/') + '/VIDEO_TS/', info=True) item.info.set_variables(variables) else: item.set_url(url, info=False) # if title: # item.name = title if player: item.force_player = player if is_playlist: item.is_playlist = True if len(video) == 1: # global <video> mplayer_options if mplayer_options: item.mplayer_options += mplayer_options # if there is more than one item add them to subitems if len(video) > 1: # a list of files subitem_matched = False for s in video: #id, url, item.media_id, mplayer_options, player, is_playlist = parse_video_child(fxd, s, dirname) video_child = parse_video_child(fxd, s, dirname) url = video_child[1] v = VideoItem(url, parent=item, info=item.info, parse=False) if url.startswith('file://'): v.files = FileInformation() v.files.append(url[7:]) if url == item.url and not subitem_matched: subitem_matched = True v.files.fxd_file = fxd.filename if item.image: v.files.image = item.image else: v.files = None v.media_id, v.mplayer_options, player, is_playlist = video_child[ 2:] if player: v.force_player = player if is_playlist: item.is_playlist = True # global <movie> mplayer_options if mplayer_options: v.mplayer_options += ' ' + mplayer_options item.subitems.append(v)