def cache_video_thumbs(defaults): import util.videothumb print checking('creating video thumbnails'), print sys.__stdout__.flush() files = [] for dirname in defaults['directory']: if defaults['dry_run']: print dirname if os.path.isdir(dirname): if defaults['recursive']: files += util.match_files_recursively(dirname, config.VIDEO_MPLAYER_SUFFIX) else: files += util.match_files(dirname, config.VIDEO_MPLAYER_SUFFIX) else: files += [ os.path.abspath(dirname) ] files = util.misc.unique(files) for filename in files[:]: print ' %4d/%-4d %s' % (files.index(filename)+1, len(files), Unicode(os.path.basename(filename))) if defaults['dry_run']: continue util.videothumb.snapshot(filename, update=False) print
def delete_old_files_1(): """ delete old files from previous versions of freevo which are not needed anymore """ #TODO Add WWW_LINK_CACHE and WWW_IMAGE_CACNE print checking('deleting old cache files from older freevo version'), sys.__stdout__.flush() del_list = [] #for name in ('image-viewer-thumb.jpg', 'thumbnails', 'audio', 'mmpython', 'disc', 'image_cache', 'link_cache'): for name in ('image-viewer-thumb.jpg', 'thumbnails', 'audio', 'mmpython', 'disc'): if os.path.exists(os.path.join(config.FREEVO_CACHEDIR, name)): del_list.append(os.path.join(config.FREEVO_CACHEDIR, name)) del_list += util.recursefolders(config.OVERLAY_DIR, 1, 'mmpython', 1) del_list += util.match_files(os.path.join(config.OVERLAY_DIR, 'disc'), ['mmpython', 'freevo']) for file in util.match_files_recursively(config.OVERLAY_DIR, ['png']): if file.endswith('.fvt.png'): del_list.append(file) for f in del_list: if os.path.isdir(f): util.rmrf(f) else: os.unlink(f) print 'deleted %s file%s' % (len(del_list), len(del_list) != 1 and 's' or '')
def cache_video_thumbs(defaults): import util.videothumb print checking('creating video thumbnails'), print sys.__stdout__.flush() files = [] for dirname in defaults['directory']: if defaults['dry_run']: print dirname if os.path.isdir(dirname): if defaults['recursive']: files += util.match_files_recursively( dirname, config.VIDEO_MPLAYER_SUFFIX) else: files += util.match_files(dirname, config.VIDEO_MPLAYER_SUFFIX) else: files += [os.path.abspath(dirname)] files = util.misc.unique(files) for filename in files[:]: print ' %4d/%-4d %s' % (files.index(filename) + 1, len(files), Unicode(os.path.basename(filename))) if defaults['dry_run']: continue util.videothumb.snapshot(filename, update=False) print
def load(self, file, prepare=True, clear=False): """ load and parse the skin file """ if file in self.fxd_files: return if clear: self._layout = {} self._font = {} self._color = {} self._images = {} self._menuset = {} self._menu = {} self._popup = '' self._sets = {} self._mainmenu = MainMenu() self.skindirs = [] self.fxd_files = [] # load plugin skin files: pdir = os.path.join(config.SHARE_DIR, 'skins/plugins') if os.path.isdir(pdir): for p in util.match_files(pdir, ['fxd']): self.load(p, prepare=False) self.prepared = False if not vfs.isfile(file): if vfs.isfile(file + '.fxd'): file += '.fxd' elif vfs.isfile( vfs.join(config.SKIN_DIR, '%s/%s.fxd' % (file, file))): file = vfs.join(config.SKIN_DIR, '%s/%s.fxd' % (file, file)) else: file = vfs.join(config.SKIN_DIR, 'xbmc/%s' % file) if vfs.isfile(file + '.fxd'): file += '.fxd' if not vfs.isfile(file): return 0 try: parser = util.fxdparser.FXD(file) parser.setattr(None, 'args', (clear, file, prepare)) parser.set_handler('include', self.include_callback) parser.set_handler('skin', self.fxd_callback) parser.parse() self.fxd_files.append(file) return 1 except: logger.error('XML file "%s" corrupt', file) traceback.print_exc() return 0
def cache_www_thumbnails(defaults): """ cache all image files for web server by creating thumbnails """ import cStringIO import stat print checking('checking web-server thumbnails'), print sys.__stdout__.flush() files = [] for dirname in defaults['directory']: if defaults['dry_run']: print dirname if os.path.isdir(dirname): if defaults['recursive']: files += util.match_files_recursively(dirname, config.IMAGE_SUFFIX) else: files += util.match_files(dirname, config.IMAGE_SUFFIX) else: files += [os.path.abspath(dirname)] files = util.misc.unique(files) for filename in files[:]: thumb = util.www_image_path(filename, '.thumbs') try: sinfo = os.stat(filename) if os.stat(thumb)[ST_MTIME] > sinfo[ST_MTIME]: files.remove(filename) except OSError: pass for bad_dir in ('.svn', '.xvpics', '.thumbnails', '.pics'): if filename.find(os.path.join(os.path.sep, bad_dir + '')) > 0: try: files.remove(filename) except: pass print '%s file%s' % (len(files), len(files) != 1 and 's' or '') for filename in files: fname = filename if len(fname) > 65: fname = fname[:20] + ' [...] ' + fname[-40:] print ' %4d/%-4d %s' % (files.index(filename) + 1, len(files), Unicode(fname)) if defaults['dry_run']: continue util.www_thumb_create(filename) if files: print
def load(self, file, prepare=True, clear=False): """ load and parse the skin file """ if file in self.fxd_files: return if clear: self._layout = {} self._font = {} self._color = {} self._images = {} self._menuset = {} self._menu = {} self._popup = '' self._sets = {} self._mainmenu = MainMenu() self.skindirs = [] self.fxd_files = [] # load plugin skin files: pdir = os.path.join(config.SHARE_DIR, 'skins/plugins') if os.path.isdir(pdir): for p in util.match_files(pdir, [ 'fxd' ]): self.load(p, prepare=False) self.prepared = False if not vfs.isfile(file): if vfs.isfile(file+'.fxd'): file += '.fxd' elif vfs.isfile(vfs.join(config.SKIN_DIR, '%s/%s.fxd' % (file, file))): file = vfs.join(config.SKIN_DIR, '%s/%s.fxd' % (file, file)) else: file = vfs.join(config.SKIN_DIR, 'main/%s' % file) if vfs.isfile(file+'.fxd'): file += '.fxd' if not vfs.isfile(file): return 0 try: parser = util.fxdparser.FXD(file) parser.setattr(None, 'args', (clear, file, prepare)) parser.set_handler('include', self.include_callback) parser.set_handler('skin', self.fxd_callback) parser.parse() self.fxd_files.append(file) return 1 except: logger.error('XML file "%s" corrupt', file) traceback.print_exc() return 0
def del_cache(): """ delete all cache files because kaa metadata got updated """ for f in util.recursefolders(config.OVERLAY_DIR,1,'mmpython.cache',1): os.unlink(f) for f in util.match_files(config.OVERLAY_DIR + '/disc/metadata', ['mmpython']): os.unlink(f) cachefile = os.path.join(config.FREEVO_CACHEDIR, 'mediainfo') util.save_pickle((mmpython.version.VERSION, 0, 0, 0), cachefile)
def cache_www_thumbnails(defaults): """ cache all image files for web server by creating thumbnails """ import cStringIO import stat print checking('checking web-server thumbnails'), print sys.__stdout__.flush() files = [] for dirname in defaults['directory']: if defaults['dry_run']: print dirname if os.path.isdir(dirname): if defaults['recursive']: files += util.match_files_recursively(dirname, config.IMAGE_SUFFIX) else: files += util.match_files(dirname, config.IMAGE_SUFFIX) else: files += [ os.path.abspath(dirname) ] files = util.misc.unique(files) for filename in files[:]: thumb = util.www_image_path(filename, '.thumbs') try: sinfo = os.stat(filename) if os.stat(thumb)[ST_MTIME] > sinfo[ST_MTIME]: files.remove(filename) except OSError: pass for bad_dir in ('.svn', '.xvpics', '.thumbnails', '.pics'): if filename.find(os.path.join(os.path.sep, bad_dir + '')) > 0: try: files.remove(filename) except: pass print '%s file%s' % (len(files), len(files) != 1 and 's' or '') for filename in files: fname = filename if len(fname) > 65: fname = fname[:20] + ' [...] ' + fname[-40:] print ' %4d/%-4d %s' % (files.index(filename)+1, len(files), Unicode(fname)) if defaults['dry_run']: continue util.www_thumb_create(filename) if files: print
def fxdhandler(self, fxd, node): """ parse image specific stuff from fxd files:: <?xml version="1.0" ?> <freevo> <slideshow title="foo" random="1|0" repeat="1|0"> <cover-img>foo.jpg</cover-img> <background-music random="1|0"> <directory recursive="1|0">path</directory> <file>filename</file> </background-music> <files> <directory recursive="1|0" duration="10">path</directory> <file duration="0">filename</file> </files> <info> <description>A nice description</description> </info> </slideshow> </freevo> """ items = [] dirname = os.path.dirname(fxd.getattr(None, 'filename', '')) children = fxd.get_children(node, 'files') if children: children = children[0].children for child in children: try: citems = [] fname = os.path.join(dirname, String(fxd.gettext(child))) if child.name == 'directory': if fxd.getattr(child, 'recursive', 0): f = util.match_files_recursively(fname, self.suffix(), skip_password=True) else: f = util.match_files(fname, self.suffix()) citems = self.get(None, f) elif child.name == 'file': citems = self.get(None, [fname]) duration = fxd.getattr(child, 'duration', 0) if duration: for i in citems: i.duration = duration items += citems except OSError, e: print 'slideshow error:', e
def fxdhandler(self, fxd, node): """ parse image specific stuff from fxd files:: <?xml version="1.0" ?> <freevo> <slideshow title="foo" random="1|0" repeat="1|0"> <cover-img>foo.jpg</cover-img> <background-music random="1|0"> <directory recursive="1|0">path</directory> <file>filename</file> </background-music> <files> <directory recursive="1|0" duration="10">path</directory> <file duration="0">filename</file> </files> <info> <description>A nice description</description> </info> </slideshow> </freevo> """ items = [] dirname = os.path.dirname(fxd.getattr(None, 'filename', '')) children = fxd.get_children(node, 'files') if children: children = children[0].children for child in children: try: citems = [] fname = os.path.join(dirname, String(fxd.gettext(child))) if child.name == 'directory': if fxd.getattr(child, 'recursive', 0): f = util.match_files_recursively(fname, self.suffix(), skip_password=True) else: f = util.match_files(fname, self.suffix()) citems = self.get(None, f) elif child.name == 'file': citems = self.get(None, [ fname ]) duration = fxd.getattr(child, 'duration', 0) if duration: for i in citems: i.duration = duration items += citems except OSError, e: print 'slideshow error:', e
def load_cache(self, filename): """ load a skin cache file """ if hasattr(self, '__last_load_cache__' ) and self.__last_load_cache__[0] == filename: return self.__last_load_cache__[1] if not os.path.isfile(filename): return None cache = self.cachename(filename) if not cache: return None if not os.path.isfile(cache): return None version, settings = util.read_pickle(cache) if not settings or version != xml_skin.FXD_FORMAT_VERSION: return None pdir = os.path.join(config.SHARE_DIR, 'skins/plugins') if os.path.isdir(pdir): ffiles = util.match_files(pdir, ['fxd']) else: ffiles = [] for f in settings.fxd_files: if not os.path.dirname(f).endswith(pdir): ffiles.append(f) # check if all files used by the skin are not newer than # the cache file ftime = os.stat(cache)[stat.ST_MTIME] for f in ffiles: if os.stat(f)[stat.ST_MTIME] > ftime: return None # restore the font objects for f in settings.font: settings.font[f].font = osd.getfont(settings.font[f].name, settings.font[f].size) self.__last_load_cache__ = filename, settings return settings
def load_cache(self, filename): """ load a skin cache file """ if hasattr(self, '__last_load_cache__') and self.__last_load_cache__[0] == filename: return self.__last_load_cache__[1] if not os.path.isfile(filename): return None cache = self.cachename(filename) if not cache: return None if not os.path.isfile(cache): return None version, settings = util.read_pickle(cache) if not settings or version != xml_skin.FXD_FORMAT_VERSION: return None pdir = os.path.join(config.SHARE_DIR, 'skins/plugins') if os.path.isdir(pdir): ffiles = util.match_files(pdir, [ 'fxd' ]) else: ffiles = [] for f in settings.fxd_files: if not os.path.dirname(f).endswith(pdir): ffiles.append(f) # check if all files used by the skin are not newer than # the cache file ftime = os.stat(cache)[stat.ST_MTIME] for f in ffiles: if os.stat(f)[stat.ST_MTIME] > ftime: return None # restore the font objects for f in settings.font: settings.font[f].font = osd.getfont(settings.font[f].name, settings.font[f].size) self.__last_load_cache__ = filename, settings return settings
def get_skins(self): """ return a list of all possible skins with name, image and filename """ ret = [] skin_files = util.match_files(os.path.join(config.SKIN_DIR, 'xbmc'), ['fxd']) # image is not usable stand alone skin_files.remove(os.path.join(config.SKIN_DIR, 'xbmc/image.fxd')) skin_files.remove(os.path.join(config.SKIN_DIR, 'xbmc/basic.fxd')) for skin in skin_files: name = os.path.splitext(os.path.basename(skin))[0] if os.path.isfile('%s.png' % os.path.splitext(skin)[0]): image = '%s.png' % os.path.splitext(skin)[0] elif os.path.isfile('%s.jpg' % os.path.splitext(skin)[0]): image = '%s.jpg' % os.path.splitext(skin)[0] else: image = None ret += [ (name, image, skin) ] return ret
def extract_image(self, path): for i in util.match_files(path, ['mp3']): try: self.tag.link(i) except eyeD3.InvalidAudioFormatException: print 'Cannot get tag for "%s"' % (String(i)) continue except: continue iname = os.path.splitext(os.path.basename(i))[0]+'.jpg' myname = vfs.getoverlay(os.path.join(path, iname)) images = self.tag.getImages(); for img in images: if vfs.isfile(myname) and (self.get_md5(vfs.open(myname, 'rb')) == self.get_md5(img.imageData)): # Image already there and has identical md5, skip pass else: f = vfs.open(myname, "wb") f.write(img.imageData) f.flush() f.close()
def match_files(self, files, separators=None): """ Matches the files to this path-spec. *files* (:class:`~collections.abc.Iterable` of :class:`str`) contains the file paths to be matched against :attr:`self.patterns <PathSpec.patterns>`. *separators* (:class:`~collections.abc.Collection` of :class:`str`; or :data:`None`) optionally contains the path separators to normalize. See :func:`~pathspec.util.normalize_file` for more information. Returns the matched files (:class:`~collections.abc.Iterable` of :class:`str`). """ if isinstance(files, (bytes, unicode)): raise TypeError("files:{!r} is not an iterable.".format(files)) file_map = util.normalize_files(files, separators=separators) matched_files = util.match_files(self.patterns, iterkeys(file_map)) for path in matched_files: yield file_map[path]
def __init__(self, dirname, force=False, rescan=False): self.artist = '' self.album = '' self.year = '' self.length = 0 self.changed = False self.force = force self.tag = eyeD3.Tag() cachefile = vfs.getoverlay(os.path.join(dirname, '..', 'freevo.cache')) subdirs = util.getdirnames(dirname, softlinks=False) filelist = None if not rescan: for subdir in subdirs: d = AudioParser(subdir, rescan) if d.changed: break else: # no changes in all subdirs, looks good if os.path.isfile(cachefile) and \ os.stat(dirname)[stat.ST_MTIME] <= os.stat(cachefile)[stat.ST_MTIME]: # and no changes in here. Do not parse everything again if force: # forces? We need to load our current values info = mediainfo.get(dirname) if info: for type in ('artist', 'album', 'year', 'length'): if info.has_key(type): setattr(self, type, info[type]) return if not filelist: filelist = util.match_files(dirname, config.AUDIO_SUFFIX) if not filelist and not subdirs: # no files in here? We are done return # ok, something changed here, too bad :-( self.changed = True self.force = False # scan all subdirs for subdir in subdirs: d = AudioParser(subdir, force=True, rescan=rescan) for type in ('artist', 'album', 'year'): setattr(self, type, self.strcmp(getattr(self, type), getattr(d, type))) self.length += d.length # cache dir first mediainfo.cache_dir(dirname) use_tracks = True for song in filelist: try: data = mediainfo.get(song) for type in ('artist', 'album'): setattr(self, type, self.strcmp(getattr(self, type), data[type])) self.year = self.strcmp(self.year, data['date']) if data['length']: self.length += int(data['length']) use_tracks = use_tracks and data['trackno'] except OSError: pass if use_tracks and (self.album or self.artist): mediainfo.set(dirname, 'audio_advanced_sort', True) if not self.length: return for type in ('artist', 'album', 'year', 'length'): if getattr(self, type): mediainfo.set(dirname, type, getattr(self, type)) data = mediainfo.get(dirname) modtime = os.stat(dirname)[stat.ST_MTIME] if not data['coverscan'] or data['coverscan'] != modtime: data.store('coverscan', modtime) self.extract_image(dirname)
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 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
for file in util.match_files_recursively('src/', ['py']): # doesn't work for everything :-( if file not in ( 'src/tv/record_server.py', ) and \ file.find('src/www') == -1 and \ file.find('src/helpers') == -1: file = re.sub('/', '.', file) try: pydoc.writedoc(file[4:-3]) except: pass try: os.mkdir('Docs/api') except: pass for file in util.match_files('.', [ 'html', ]): print 'moving %s' % file os.rename(file, 'Docs/api/%s' % file) print print 'wrote api doc to \'Docs/api\'' shutdown(exit=True) try: # signal handler signal.signal(signal.SIGTERM, unix_signal_handler) signal.signal(signal.SIGINT, unix_signal_handler) kaa.main.signals['shutdown'].connect(signal_handler) # load the fxditem to make sure it's the first in the # mimetypes list
sys.exit(0) if len(sys.argv) > 1 and sys.argv[1] == '--thumbnail': import util.videothumb if len(sys.argv) > 2: if sys.argv[2] == '--recursive': if len(sys.argv) > 3: dirname = os.path.abspath(sys.argv[3]) files = util.match_files_recursively( dirname, config.VIDEO_SUFFIX) else: print_error_and_exit() elif os.path.isdir(sys.argv[2]): dirname = os.path.abspath(sys.argv[2]) files = util.match_files(dirname, config.VIDEO_SUFFIX) else: files = [os.path.abspath(sys.argv[2])] print 'creating video thumbnails....' for filename in files: print ' %4d/%-4d %s' % (files.index(filename) + 1, len(files), os.path.basename(filename)) util.videothumb.snapshot(filename, update=False) print else: print_error_and_exit() sys.exit(0) print 'Freevo cache'
fxd.setattr(file, 'mplayer-options', '-vf crop=%s' % encjob.crop) plugin.register_callback('fxditem', ['video'], 'movie', fxdhandler.parse_movie) plugin.register_callback('fxditem', ['video'], 'disc-set', fxdhandler.parse_disc_set) print checking('checking cropdetect'), sys.__stdout__.flush() fxdfiles = [] for dirname in defaults['directory']: if os.path.isdir(dirname): if defaults['recursive']: fxdfiles += util.match_files_recursively(dirname, fxditem.mimetype.suffix()) else: fxdfiles += util.match_files(dirname, fxditem.mimetype.suffix()) else: fxdfiles += [ os.path.abspath(dirname) ] fxdfiles.sort(lambda l, o: cmp(l.lower(), o.lower())) fxdfiles = util.misc.unique(fxdfiles) files = [] for info in fxditem.mimetype.parse(None, fxdfiles, display_type='video'): if defaults['rebuild'] or (hasattr(info, 'mplayer_options') and not info.mplayer_options): files.append(info.files) for fileinfo in copy.copy(files): filename = fileinfo.fxd_file print print ' %4d/%-4d %s' % (files.index(fileinfo)+1, len(files), Unicode(os.path.basename(filename))), sys.__stdout__.flush()
def __init__(self, dirname, force=False, rescan=False): self.artist = '' self.album = '' self.year = '' self.length = 0 self.changed = False self.force = force self.tag = eyeD3.Tag() cachefile = vfs.getoverlay(os.path.join(dirname, '..', 'freevo.cache')) subdirs = util.getdirnames(dirname, softlinks=False) filelist = None if not rescan: for subdir in subdirs: d = AudioParser(subdir, rescan) if d.changed: break else: # no changes in all subdirs, looks good if os.path.isfile(cachefile) and os.stat(dirname)[stat.ST_MTIME] <= os.stat(cachefile)[stat.ST_MTIME]: # and no changes in here. Do not parse everything again if force: # forces? We need to load our current values info = mediainfo.get(dirname) if info: for type in ('artist', 'album', 'year', 'length'): if info.has_key(type): setattr(self, type, info[type]) return if not filelist: filelist = util.match_files(dirname, config.AUDIO_SUFFIX) if not filelist and not subdirs: # no files in here? We are done return # ok, something changed here, too bad :-( self.changed = True self.force = False # scan all subdirs for subdir in subdirs: d = AudioParser(subdir, force=True, rescan=rescan) for type in ('artist', 'album', 'year'): setattr(self, type, self.strcmp(getattr(self, type), getattr(d, type))) self.length += d.length # cache dir first mediainfo.cache_dir(dirname) use_tracks = True for song in filelist: try: data = mediainfo.get(song) for type in ('artist', 'album'): setattr(self, type, self.strcmp(getattr(self, type), data[type])) self.year = self.strcmp(self.year, data['userdate']) if data['length']: self.length += int(data['length']) use_tracks = use_tracks and data['trackno'] except OSError: pass if use_tracks and (self.album or self.artist): mediainfo.set(dirname, 'audio_advanced_sort', True) if not self.length: return for type in ('artist', 'album', 'year', 'length'): if getattr(self, type): mediainfo.set(dirname, type, getattr(self, type)) data = mediainfo.get(dirname) modtime = os.stat(dirname)[stat.ST_MTIME] if not data['coverscan'] or data['coverscan'] != modtime: data.store('coverscan', modtime) self.extract_image(dirname)
plugin.register_callback('fxditem', ['video'], 'movie', fxdhandler.parse_movie) plugin.register_callback('fxditem', ['video'], 'disc-set', fxdhandler.parse_disc_set) print checking('checking cropdetect'), sys.__stdout__.flush() fxdfiles = [] for dirname in defaults['directory']: if os.path.isdir(dirname): if defaults['recursive']: fxdfiles += util.match_files_recursively( dirname, fxditem.mimetype.suffix()) else: fxdfiles += util.match_files(dirname, fxditem.mimetype.suffix()) else: fxdfiles += [os.path.abspath(dirname)] fxdfiles.sort(lambda l, o: cmp(l.lower(), o.lower())) fxdfiles = util.misc.unique(fxdfiles) files = [] for info in fxditem.mimetype.parse(None, fxdfiles, display_type='video'): if defaults['rebuild'] or (hasattr(info, 'mplayer_options') and not info.mplayer_options): files.append(info.files) for fileinfo in copy.copy(files): filename = fileinfo.fxd_file print print ' %4d/%-4d %s' % (files.index(fileinfo) + 1, len(files),
class Playlist(Item): def __init__(self, name='', playlist=None, parent=None, display_type=None, random=False, build=False, autoplay=False, repeat=False): """ Init the playlist 1. a filename to a playlist file (e.g. m3u) 2. a list of items to play, this list can include - Items - filenames - a list (directoryname, recursive=0|1) @param build: create the playlist, this means unfold the directories """ Item.__init__(self, parent) self.type = 'playlist' self.menuw = None self.name = Unicode(name) if isstring(playlist) and not name: self.name = util.getname(playlist) # variables only for Playlist self.current_item = None self.playlist = playlist or [] self.autoplay = autoplay self.repeat = repeat self.display_type = display_type self.__build__ = False self.suffixlist = [] self.get_plugins = [] self.background_playlist = None if build: self.build() if self.name.find('Playlist') < 0: self.name = '%s Playlist' % self.name self.random = random def read_m3u(self, plsname): """ This is the (m3u) playlist reading function. @param plsname: The playlist filename @returns: The list of interesting lines in the playlist """ try: lines = util.readfile(plsname) except IOError: print 'Cannot open file "%s"' % plsname return 0 try: playlist_lines_dos = map(lambda l: l.strip(), lines) playlist_lines = filter(lambda l: len(l) > 0, playlist_lines_dos) except IndexError: print 'Bad m3u playlist file "%s"' % plsname return 0 (curdir, playlistname) = os.path.split(plsname) #XXX this may not work if the curdir is not accessible os.chdir(curdir) for i in range(0,len(playlist_lines)): if playlist_lines[i][0] == "#": continue line = playlist_lines[i] line = line.replace('\\', '/') # Fix MSDOS slashes try: if line.find('://') > 0: if playlist_lines[i-1].find('#EXTINF') > -1 and len(playlist_lines[i-1].split(","))>1: self.playlist.append((line,playlist_lines[i-1].split(",")[1])) else: self.playlist.append(line) elif os.path.isabs(line): if os.path.exists(line): self.playlist.append(line) else: if os.path.exists(os.path.abspath(os.path.join(curdir, line))): self.playlist.append(os.path.abspath(os.path.join(curdir, line))) except TypeError: print 'Bad m3u playlist line in "%s":%r' % (plsname, line) def read_pls(self, plsname): """ This is the (pls) playlist reading function. Arguments: plsname - the playlist filename Returns: The list of interesting lines in the playlist """ try: lines = util.readfile(plsname) except IOError: print String(_('Cannot open file "%s"')) % list return 0 playlist_lines_dos = map(lambda l: l.strip(), lines) playlist_lines = filter(lambda l: l[0:4] == 'File', playlist_lines_dos) for line in playlist_lines: numchars=line.find("=")+1 if numchars > 0: playlist_lines[playlist_lines.index(line)] = \ line[numchars:] (curdir, playlistname) = os.path.split(plsname) os.chdir(curdir) for line in playlist_lines: if line.endswith('\r\n'): line = line.replace('\\', '/') # Fix MSDOS slashes if line.find('://') > 0: self.playlist.append(line) elif os.path.isabs(line): if os.path.exists(line): self.playlist.append(line) else: if os.path.exists(os.path.abspath(os.path.join(curdir, line))): self.playlist.append(os.path.abspath(os.path.join(curdir, line))) def read_ssr(self, ssrname): """ This is the (ssr) slideshow reading function. File line format:: FileName: "image file name"; Caption: "caption text"; Delay: "sec" The caption and delay are optional. @param ssrname: the slideshow filename @returns: the list of interesting lines in the slideshow """ (curdir, playlistname) = os.path.split(ssrname) os.chdir(curdir) out_lines = [] try: lines = util.readfile(ssrname) except IOError: print String(_('Cannot open file "%s"')) % list return 0 playlist_lines_dos = map(lambda l: l.strip(), lines) playlist_lines = filter(lambda l: l[0] != '#', lines) # Here's where we parse the line. See the format above. for line in playlist_lines: tmp_list = [] ss_name = re.findall('FileName: \"(.*?)\"', line, re.I) ss_caption = re.findall('Caption: \"(.*?)\"', line, re.I) ss_delay = re.findall('Delay: \"(.*?)\"', line, re.I) if ss_name != []: if ss_caption == []: ss_caption += [""] if ss_delay == []: ss_delay += [5] for p in self.get_plugins: if os.path.isabs(ss_name[0]): curdir = ss_name[0] else: curdir = os.path.abspath(os.path.join(curdir, ss_name[0])) for i in p.get(self, [curdir]): if i.type == 'image': i.name = Unicode(ss_caption[0]) i.duration = int(ss_delay[0]) self.playlist.append(i) break self.autoplay = True def build(self): """ Build the playlist. Create a list of items and filenames. This function will load the playlist file or expand directories """ if self.suffixlist: # we called this function before return playlist = self.playlist self.playlist = [] for p in plugin.mimetype(self.display_type): #if self.display_type in p.display_type: # XXX self.display_type seems to be set to None # XXX Which prevents the str->Item from occuring # XXX This is a short-term fix I guess self.suffixlist += p.suffix() self.get_plugins.append(p) if isstring(playlist): # it's a filename with a playlist try: f=open(playlist, "r") line = f.readline() f.close if line.find("[playlist]") > -1: self.read_pls(playlist) elif line.find("[Slides]") > -1: self.read_ssr(playlist) else: self.read_m3u(playlist) except (OSError, IOError), e: print 'playlist error: %s' % e self.set_url(playlist) # self.playlist is a list of Items or strings (filenames) if not isstring(playlist): for i in playlist: if isinstance(i, Item): # Item object, correct parent i = copy.copy(i) i.parent = self self.playlist.append(i) elif isinstance(i, list) or isinstance(i, tuple) and len(i) == 2 and vfs.isdir(i[0]): # (directory, recursive=True|False) if i[1]: self.playlist += util.match_files_recursively(i[0], self.suffixlist, skip_password=True, follow_symlinks=config.SYS_FOLLOW_SYMLINKS) else: self.playlist += util.match_files(i[0], self.suffixlist) # set autoplay to True on such big lists self.autoplay = True else: # filename self.playlist.append(i) self.__build__ = True
import pydoc import re for file in util.match_files_recursively('src/', ['py' ]): # doesn't work for everything :-( if file not in ( 'src/tv/record_server.py', ) and \ file.find('src/www') == -1 and file.find('src/helpers') == -1: file = re.sub('/', '.', file) try: pydoc.writedoc(file[4:-3]) except: pass try: os.mkdir('Docs/api') except: pass for file in util.match_files('.', ['html', ]): print 'moving %s' % file os.rename(file, 'Docs/api/%s' % file) print print 'wrote api doc to \'Docs/api\'' shutdown(exit=True) try: # signal handler signal.signal(signal.SIGTERM, unix_signal_handler) signal.signal(signal.SIGINT, unix_signal_handler) kaa.main.signals['shutdown'].connect(signal_handler) kaa.main.signals['exception'].connect(exception_handler) # load the fxditem to make sure it's the first in the
class PluginInterface(plugin.MimetypePlugin): """ Plugin to handle all kinds of image items """ def __init__(self): plugin.MimetypePlugin.__init__(self) self.display_type = ['image'] # register the callbacks plugin.register_callback('fxditem', ['image'], 'slideshow', self.fxdhandler) # activate the mediamenu for image plugin.activate('mediamenu', level=plugin.is_active('image')[2], args='image') def suffix(self): """ return the list of suffixes this class handles """ return config.IMAGE_SUFFIX 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 dirinfo(self, diritem): """ set information for a diritem based on album.xml """ #dirinfo = bins.DirInfo(diritem.dir) #if dirinfo.has_key('desc'): # info = dirinfo['desc'] #if dirinfo.has_key('sampleimage') and dirinfo['sampleimage']: # image = vfs.join(diritem.dir, dirinfo['sampleimage']) # if vfs.isfile(image): # diritem.image = image #if dirinfo.has_key('title') and dirinfo['title']: # diritem.name = dirinfo['title'] def fxdhandler(self, fxd, node): """ parse image specific stuff from fxd files:: <?xml version="1.0" ?> <freevo> <slideshow title="foo" random="1|0" repeat="1|0"> <cover-img>foo.jpg</cover-img> <background-music random="1|0"> <directory recursive="1|0">path</directory> <file>filename</file> </background-music> <files> <directory recursive="1|0" duration="10">path</directory> <file duration="0">filename</file> </files> <info> <description>A nice description</description> </info> </slideshow> </freevo> """ items = [] dirname = os.path.dirname(fxd.getattr(None, 'filename', '')) children = fxd.get_children(node, 'files') if children: children = children[0].children for child in children: try: citems = [] fname = os.path.join(dirname, String(fxd.gettext(child))) if child.name == 'directory': if fxd.getattr(child, 'recursive', 0): f = util.match_files_recursively(fname, self.suffix(), skip_password=True) else: f = util.match_files(fname, self.suffix()) citems = self.get(None, f) elif child.name == 'file': citems = self.get(None, [fname]) duration = fxd.getattr(child, 'duration', 0) if duration: for i in citems: i.duration = duration items += citems except OSError, e: print 'slideshow error:', e pl = Playlist('', items, fxd.getattr(None, 'parent', None), random=fxd.getattr(node, 'random', 0), repeat=fxd.getattr(node, 'repeat', 0)) pl.autoplay = True pl.name = fxd.getattr(node, 'title') pl.image = fxd.childcontent(node, 'cover-img') if pl.image: pl.image = vfs.join(vfs.dirname(fxd.filename), pl.image) # background music children = fxd.get_children(node, 'background-music') if children: random = fxd.getattr(children[0], 'random', 0) children = children[0].children files = [] suffix = [] for p in plugin.mimetype('audio'): suffix += p.suffix() for child in children: try: fname = os.path.join(dirname, fxd.gettext(child)) if child.name == 'directory': if fxd.getattr(child, 'recursive', 0): files += util.match_files_recursively( fname, suffix, skip_password=True) else: files += util.match_files(fname, suffix) elif child.name == 'file': files.append(fname) except OSError, e: print 'playlist error:', e