def get(self, parent, files): """ return a list of items based on the files """ logger.log(9, 'get(parent=%r, files=%r)', parent, files) items = [] if not hasattr(parent, 'add_args') or type( parent.add_args) is not types.TupleType: pop = PopupBox( text=_('please update GAMES_ITEMS in local_conf.py')) pop.show() time.sleep(2) pop.destroy() return [] file = '' (gtype, cmd, args, imgpath, suffixlist) = parent.add_args[0] try: if gtype == 'MAME': mame_files = util.find_matches(files, ['zip']) # This will only add real mame roms to the cache. (rm_files, mame_list) = mame_cache.getMameItemInfoList(mame_files, cmd) for rm_file in rm_files: files.remove(rm_file) for ml in mame_list: items += [ MameItem(ml[0], ml[1], ml[2], cmd, args, imgpath, parent, ml[3]) ] elif gtype == 'SNES': for file in util.find_matches(files, snesromExtensions + ['zip']): items += [SnesItem(file, cmd, args, imgpath, parent)] files.remove(file) elif gtype == 'GENESIS': for file in util.find_matches(files, genesisromExtensions + ['zip']): items += [GenesisItem(file, cmd, args, imgpath, parent)] files.remove(file) elif gtype == 'GENERIC': logger.log(9, 'find_matches=%r files=%r suffixlist=%r', util.find_matches(files, suffixlist), files, suffixlist) for file in util.find_matches(files, suffixlist): items += [GenericItem(file, cmd, args, imgpath, parent)] files.remove(file) except UnboundLocalError: logger.warning('Zip file \"%s\" may be corrupt', file) return items
def get(self, parent, files): """ return a list of items based on the files """ logger.log(9, '%s.get(parent=%r, files=%r)' % (self.__class__, parent, files)) temp = False cleanup = True items = [] # get the list of fxd files archives = util.find_matches(files, config.ARCHIVE_SUFFIX) # sort all files to make sure that we have them in sequence archives.sort(lambda l, o: cmp(l.upper(), o.upper())) for file in archives: if is_archive(file): # check if the extracted files should be deleted upon the exit/shutdown # This will always be done for System's temp directory though, regardless of # the ARCHIVE_DELETE_ON_SHUTDOWN setting. if parent and parent.type == 'dir': if hasattr(parent, 'ARCHIVE_DELETE_ON_SHUTDOWN') and not parent.ARCHIVE_DELETE_ON_SHUTDOWN: cleanup = False if hasattr(parent, 'ARCHIVE_USE_SYSTEM_TEMP_DIR') and parent.ARCHIVE_USE_SYSTEM_TEMP_DIR: cleanup = temp = True a = ArchiveItem(file, parent, display_type=parent.display_type, use_temp=temp, cleanup=cleanup) items.append(a) logger.debug('Found %d archive files', len(items)) self.archives.extend(items) return items
def get(self, parent, files): """ return a list of items based on the files """ # get the list of fxd files fxd_files = util.find_matches(files, ["fxd"]) # removed covered files from the list for f in fxd_files: try: files.remove(f) except: pass # check of directories with a fxd covering it for d in copy.copy(files): if os.path.isdir(d): f = os.path.join(d, os.path.basename(d) + ".fxd") if vfs.isfile(f): fxd_files.append(f) files.remove(d) # return items if fxd_files: return self.parse(parent, fxd_files, files) else: return []
def get(self, parent, files): """ return a list of items based on the files """ # get the list of fxd files fxd_files = util.find_matches(files, ['fxd']) # removed covered files from the list for f in fxd_files: try: files.remove(f) except: pass # check of directories with a fxd covering it for d in copy.copy(files): if os.path.isdir(d): f = os.path.join(d, os.path.basename(d) + '.fxd') if vfs.isfile(f): fxd_files.append(f) files.remove(d) # return items if fxd_files: return self.parse(parent, fxd_files, files) else: return []
def get(self, parent, files): """ return a list of items based on the files """ items = [] for file in util.find_matches(files, config.IMAGE_SUFFIX): items.append(ImageItem(file, parent)) files.remove(file) return items
def get(self, parent, files): """ return a list of items based on the files """ logger.log( 9, 'get(parent=%r, files=%r)', parent, files) items = [] if not hasattr(parent, 'add_args') or type(parent.add_args) is not types.TupleType: pop = PopupBox(text=_('please update GAMES_ITEMS in local_conf.py')) pop.show() time.sleep(2) pop.destroy() return [] file = '' (gtype, cmd, args, imgpath, suffixlist) = parent.add_args[0] try: if gtype == 'MAME': mame_files = util.find_matches(files, [ 'zip' ] ) # This will only add real mame roms to the cache. (rm_files, mame_list) = mame_cache.getMameItemInfoList(mame_files, cmd) for rm_file in rm_files: files.remove(rm_file) for ml in mame_list: items += [ MameItem(ml[0], ml[1], ml[2], cmd, args, imgpath, parent, ml[3]) ] elif gtype == 'SNES': for file in util.find_matches(files, snesromExtensions + [ 'zip' ]): items += [ SnesItem(file, cmd, args, imgpath, parent) ] files.remove(file) elif gtype == 'GENESIS': for file in util.find_matches(files, genesisromExtensions + ['zip']): items += [ GenesisItem(file, cmd, args, imgpath, parent) ] files.remove(file) elif gtype == 'GENERIC': logger.log( 9, 'find_matches=%r files=%r suffixlist=%r', util.find_matches(files, suffixlist), files, suffixlist) for file in util.find_matches(files, suffixlist): items += [ GenericItem(file, cmd, args, imgpath, parent) ] files.remove(file) except UnboundLocalError: logger.warning('Zip file \"%s\" may be corrupt', file) return items
def get(self, parent, files): """ return a list of items based on the files """ items = [] for file in util.find_matches(files, config.AUDIO_SUFFIX): a = AudioItem(file, parent) items.append(a) files.remove(file) return items
def get(self, parent, files): """ return a list of items based on the files """ items = [] if config.IMAGE_EXCLUDE: exclude_string = re.compile('|'.join(config.IMAGE_EXCLUDE)) for file in util.find_matches(files, config.IMAGE_SUFFIX): if config.IMAGE_EXCLUDE: if not re.search(exclude_string, file): items.append(ImageItem(file, parent)) files.remove(file) else: items.append(ImageItem(file, parent)) files.remove(file) return items
def get(self, parent, files): """ return a list of items based on the files """ items = [] if parent and hasattr(parent, 'display_type'): display_type = parent.display_type else: display_type = None for filename in util.find_matches(files, self.suffix()): items.append(Playlist(playlist=filename, parent=parent, display_type=display_type, build=True)) files.remove(filename) return items
def dirinfo(self, diritem): """ set information for a diritem based on the content, etc. """ logger.log(9, 'diritem.dir = "%s"', diritem.dir) if os.path.exists(diritem.dir): timestamp = os.stat(diritem.dir)[stat.ST_MTIME] if not diritem['coversearch_timestamp'] or \ timestamp > diritem['coversearch_timestamp']: # Pick an image if it is the only image in this dir, or it matches # the configurable regexp files = util.find_matches( vfs.listdir(diritem.dir, include_overlay=True), ('jpg', 'gif', 'png')) if len(files) == 1: diritem.image = os.path.join(diritem.dir, files[0]) elif len(files) > 1: covers = filter(cover_filter, files) if covers: diritem.image = os.path.join(diritem.dir, covers[0]) diritem.store_info('coversearch_timestamp', timestamp) diritem.store_info('coversearch_result', diritem.image) elif diritem['coversearch_result']: diritem.image = diritem['coversearch_result'] if not diritem.info.has_key('title') and diritem.parent: # ok, try some good name creation p_album = diritem.parent['album'] p_artist = diritem.parent['artist'] album = diritem['album'] artist = diritem['artist'] if artist and p_artist == artist and album and not p_album: # parent has same artist, but no album, but item has: diritem.name = album # XXX FIXME #elif not p_artist and artist: # # item has artist, parent not # diritem.name = artist elif not p_artist and not p_album and not artist and album: # parent has no info, item no artist but album (== collection) diritem.name = album
def get(self, parent, files): """ return a list of items based on the files """ items = [] if parent and hasattr(parent, 'display_type'): display_type = parent.display_type else: display_type = None for filename in util.find_matches(files, self.suffix()): items.append( Playlist(playlist=filename, parent=parent, display_type=display_type, build=True)) files.remove(filename) return items
def dirinfo(self, diritem): """ set information for a diritem based on the content, etc. """ logger.log( 9, 'diritem.dir = "%s"', diritem.dir) if os.path.exists(diritem.dir): timestamp = os.stat(diritem.dir)[stat.ST_MTIME] if not diritem['coversearch_timestamp'] or \ timestamp > diritem['coversearch_timestamp']: # Pick an image if it is the only image in this dir, or it matches # the configurable regexp files = util.find_matches(vfs.listdir(diritem.dir, include_overlay=True), ('jpg', 'gif', 'png')) if len(files) == 1: diritem.image = os.path.join(diritem.dir, files[0]) elif len(files) > 1: covers = filter(cover_filter, files) if covers: diritem.image = os.path.join(diritem.dir, covers[0]) diritem.store_info('coversearch_timestamp', timestamp) diritem.store_info('coversearch_result', diritem.image) elif diritem['coversearch_result']: diritem.image = diritem['coversearch_result'] if not diritem.info.has_key('title') and diritem.parent: # ok, try some good name creation p_album = diritem.parent['album'] p_artist = diritem.parent['artist'] album = diritem['album'] artist = diritem['artist'] if artist and p_artist == artist and album and not p_album: # parent has same artist, but no album, but item has: diritem.name = album # XXX FIXME #elif not p_artist and artist: # # item has artist, parent not # diritem.name = artist elif not p_artist and not p_album and not artist and album: # parent has no info, item no artist but album (== collection) diritem.name = album
def get(self, parent, files): """ return a list of items based on the files """ items = [] if parent and hasattr(parent, 'display_type'): display_type = parent.display_type else: display_type = None if display_type and display_type in config.DIRECTORY_AUTOPLAY_PLAYLISTS: autoplay = True for filename in util.find_matches(files, self.suffix()): items.append(Playlist(playlist=filename, parent=parent, display_type=display_type, build=True, autoplay=autoplay)) files.remove(filename) return items
def get(self, parent, files): """ return a list of items based on the files """ logger.log( 9, '%s.get(parent=%r, files=%r)' % (self.__class__, parent, files)) temp = False cleanup = True items = [] # get the list of fxd files archives = util.find_matches(files, config.ARCHIVE_SUFFIX) # sort all files to make sure that we have them in sequence archives.sort(lambda l, o: cmp(l.upper(), o.upper())) for file in archives: if is_archive(file): # check if the extracted files should be deleted upon the exit/shutdown # This will always be done for System's temp directory though, regardless of # the ARCHIVE_DELETE_ON_SHUTDOWN setting. if parent and parent.type == 'dir': if hasattr(parent, 'ARCHIVE_DELETE_ON_SHUTDOWN' ) and not parent.ARCHIVE_DELETE_ON_SHUTDOWN: cleanup = False if hasattr(parent, 'ARCHIVE_USE_SYSTEM_TEMP_DIR' ) and parent.ARCHIVE_USE_SYSTEM_TEMP_DIR: cleanup = temp = True a = ArchiveItem(file, parent, display_type=parent.display_type, use_temp=temp, cleanup=cleanup) items.append(a) logger.debug('Found %d archive files', len(items)) self.archives.extend(items) return items
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 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 get(self, parent, files): """ return a list of items based on the files """ items = [] all_files = util.find_matches(files, config.VIDEO_SUFFIX) # sort all files to make sure 1 is before 2 for auto-join all_files.sort(lambda l, o: cmp(l.upper(), o.upper())) hidden_files = [] pat = re.compile(config.VIDEO_AUTOJOIN_REGEX) for file in all_files: if parent and parent.type == 'dir' and \ hasattr(parent, 'VIDEO_DIRECTORY_AUTOBUILD_THUMBNAILS') and \ parent.VIDEO_DIRECTORY_AUTOBUILD_THUMBNAILS: util.videothumb.snapshot(file, update=False, popup=True) if file in hidden_files: files.remove(file) continue x = VideoItem(file, parent) # join video files if config.VIDEO_AUTOJOIN: mat = pat.search(file) if mat is not None: add_file = [] start = file.find(mat.group(1), mat.start()) end = start + len(mat.group(1)) stem = file[:start] tail = file[end:] next = 2 for f in all_files: next_str = '%0*d' % (end - start, next) filename = stem + next_str + tail if filename in all_files: add_file.append(filename) else: break next += 1 if len(add_file) > 0: name = stem + tail x = VideoItem(name, parent) x.files = FileInformation() x.subitems.append(VideoItem(file, x)) x.set_url(file, True) for filename in add_file: x.files.append(filename) x.subitems.append(VideoItem(filename, x)) hidden_files.append(filename) if parent and parent.media: file_id = String( parent.media.id ) + file[len(os.path.join(parent.media.mountdir, '')):] try: x.mplayer_options = discset_information[file_id] logger.debug('x.mplayer_options=%r', x.mplayer_options) except KeyError: pass items.append(x) files.remove(file) for i in copy.copy(files): if os.path.isdir(i + '/VIDEO_TS'): # DVD Image, trailing slash is important for Xine items.append(VideoItem('dvd://' + i[1:] + '/VIDEO_TS/', parent)) files.remove(i) return items
def get(self, parent, files): """ return a list of items based on the files """ items = [] all_files = util.find_matches(files, config.VIDEO_SUFFIX) # sort all files to make sure 1 is before 2 for auto-join all_files.sort(lambda l, o: cmp(l.upper(), o.upper())) hidden_files = [] for file in all_files: if parent and parent.type == 'dir' and \ hasattr(parent, 'VIDEO_DIRECTORY_AUTOBUILD_THUMBNAILS') and \ parent.VIDEO_DIRECTORY_AUTOBUILD_THUMBNAILS: util.videothumb.snapshot(file, update=False, popup=True) if file in hidden_files: files.remove(file) continue x = VideoItem(file, parent) # join video files if config.VIDEO_AUTOJOIN and file.find('1') > 0: pos = 0 for count in range(file.count('1')): # only count single digests if file[pos+file[pos:].find('1')-1] in string.digits or \ file[pos+file[pos:].find('1')+1] in string.digits: pos += file[pos:].find('1') + 1 continue add_file = [] missing = 0 for i in range(2, 6): current = file[:pos] + file[pos:].replace( '1', str(i), 1) if current in all_files: add_file.append(current) end = i elif not missing: # one file missing, stop searching missing = i if add_file and missing > end: if len(add_file) > 3: # more than 4 files, I don't belive it break # create new name name = file[:pos] + file[pos:].replace( '1', '1-%s' % end, 1) x = VideoItem(name, parent) x.files = FileInformation() x.set_url(file, True) for f in [file] + add_file: x.files.append(f) x.subitems.append(VideoItem(f, x)) hidden_files.append(f) break else: pos += file[pos:].find('1') + 1 if parent.media: file_id = String(parent.media.id) + \ file[len(os.path.join(parent.media.mountdir, "")):] try: x.mplayer_options = discset_information[file_id] _debug_('x.mplayer_options=%r' % x.mplayer_options) except KeyError: pass items.append(x) files.remove(file) for i in copy.copy(files): if os.path.isdir(i + '/VIDEO_TS'): # DVD Image, trailing slash is important for Xine items.append(VideoItem('dvd://' + i[1:] + '/VIDEO_TS/', parent)) files.remove(i) return items
def get(self, parent, files): """ return a list of items based on the files """ items = [] all_files = util.find_matches(files, config.VIDEO_SUFFIX) # sort all files to make sure 1 is before 2 for auto-join all_files.sort(lambda l, o: cmp(l.upper(), o.upper())) hidden_files = [] pat = re.compile(config.VIDEO_AUTOJOIN_REGEX) for file in all_files: if parent and parent.type == 'dir' and \ hasattr(parent, 'VIDEO_DIRECTORY_AUTOBUILD_THUMBNAILS') and \ parent.VIDEO_DIRECTORY_AUTOBUILD_THUMBNAILS: util.videothumb.snapshot(file, update=False, popup=True) if file in hidden_files: files.remove(file) continue x = VideoItem(file, parent) # join video files if config.VIDEO_AUTOJOIN: mat = pat.search(file) if mat is not None: add_file = [] start = file.find(mat.group(1), mat.start()) end = start + len(mat.group(1)) stem = file[:start] tail = file[end:] next = 2 for f in all_files: next_str = '%0*d' % (end-start, next) filename = stem+next_str+tail if filename in all_files: add_file.append(filename) else: break next += 1 if len(add_file) > 0: name = stem+tail x = VideoItem(name, parent) x.files = FileInformation() x.subitems.append(VideoItem(file, x)) x.set_url(file, True) for filename in add_file: x.files.append(filename) x.subitems.append(VideoItem(filename, x)) hidden_files.append(filename) if parent and parent.media: file_id = String(parent.media.id) + file[len(os.path.join(parent.media.mountdir, '')):] try: x.mplayer_options = discset_information[file_id] logger.debug('x.mplayer_options=%r', x.mplayer_options) except KeyError: pass items.append(x) files.remove(file) for i in copy.copy(files): if os.path.isdir(i+'/VIDEO_TS'): # DVD Image, trailing slash is important for Xine items.append(VideoItem('dvd://' + i[1:] + '/VIDEO_TS/', parent)) files.remove(i) return items