def __init__(self, directory, parent, name='', display_type=None, add_args=None, create_metainfo=True, use_temp=False, cleanup=True): logger.log(9, '%s.__init__(directory=%r, parent=%r, name=%r, display_type=%r, add_args=%r, create_metainfo=%r, use_temp=%r, cleanup=%r)', self.__class__, directory, parent, name, display_type, add_args, create_metainfo, use_temp, cleanup) self.archive = os.path.abspath(directory) self.cleanup = cleanup self.valid = False fname = os.path.splitext(os.path.basename(self.archive))[0] # create the tmp directory that we will extract the content of the archive to if use_temp: dir = os.path.join(tempfile.gettempdir(), fname) else: dir = vfs.getoverlay(self.archive) try: if not os.path.exists(dir): os.makedirs(dir) except (OSError) as exc: logger.error('OS Error %s creating dir %s, skipping this archive...', exc, dir) return self.valid = True self.cover = self.set_cover_image(dir) # now we substitute the original dir/file name with the tmp dir location DirItem.__init__(self, dir, parent=parent, name=fname, display_type=display_type)
def cwd(self, arg=None, menuw=None): """ make a menu item for each file in the directory """ logger.log(9, 'cwd(arg=%r, menuw=%r)', arg, menuw) play_items = [] number = len(self.info['tracks']) if hasattr(self.info, 'mixed'): number -= 1 for i in range(0, number): title = self.info['tracks'][i]['title'] item = AudioItem('cdda://%d' % (i + 1), self, title, scan=False) # XXX FIXME: set also all the other info here if AudioInfo # XXX will be based on mmpython #item.set_info('', self.name, title, i+1, self.disc_id[1], '') item.info = self.info['tracks'][i] item.length = item.info['length'] if config.MPLAYER_ARGS.has_key('cd'): item.mplayer_options += (' ' + config.MPLAYER_ARGS['cd']) if self.devicename: item.mplayer_options += ' -cdrom-device %s' % self.devicename play_items.append(item) # add all playable items to the playlist of the directory # to play one files after the other self.playlist = play_items # all items together items = [] # random playlist (only active for audio) if 'audio' in config.DIRECTORY_ADD_RANDOM_PLAYLIST and len( play_items) > 1: pl = Playlist(_('Random Playlist'), play_items, self, random=True) pl.autoplay = True items += [pl] items += play_items if hasattr(self.info, 'mixed'): d = DirItem(self.media.mountdir, self) d.name = _('Data files on disc') items.append(d) self.play_items = play_items title = self.name if title[0] == '[' and title[-1] == ']': title = self.name[1:-1] item_menu = menu.Menu(title, items, item_types=self.display_type) if menuw: menuw.pushmenu(item_menu) return items
def cwd(self, arg=None, menuw=None): """ make a menu item for each file in the directory """ logger.log( 9, 'cwd(arg=%r, menuw=%r)', arg, menuw) play_items = [] number = len(self.info['tracks']) if hasattr(self.info, 'mixed'): number -= 1 for i in range(0, number): title=self.info['tracks'][i]['title'] item = AudioItem('cdda://%d' % (i+1), self, title, scan=False) # XXX FIXME: set also all the other info here if AudioInfo # XXX will be based on mmpython #item.set_info('', self.name, title, i+1, self.disc_id[1], '') item.info = self.info['tracks'][i] item.length = item.info['length'] if config.MPLAYER_ARGS.has_key('cd'): item.mplayer_options += (' ' + config.MPLAYER_ARGS['cd']) if self.devicename: item.mplayer_options += ' -cdrom-device %s' % self.devicename play_items.append(item) # add all playable items to the playlist of the directory # to play one files after the other self.playlist = play_items # all items together items = [] # random playlist (only active for audio) if 'audio' in config.DIRECTORY_ADD_RANDOM_PLAYLIST and len(play_items) > 1: pl = Playlist(_('Random Playlist'), play_items, self, random=True) pl.autoplay = True items += [ pl ] items += play_items if hasattr(self.info, 'mixed'): d = DirItem(self.media.mountdir, self) d.name = _('Data files on disc') items.append(d) self.play_items = play_items title = self.name if title[0] == '[' and title[-1] == ']': title = self.name[1:-1] item_menu = menu.Menu(title, items, item_types = self.display_type) if menuw: menuw.pushmenu(item_menu) return items
def items(self, parent): if util.is_usb_storage_device() != -1: d = DirItem(self.mountpoint, parent, self.name, display_type=parent.display_type) d.mountpoint = self.mountpoint return [d] return []
def items(self, parent): return [ DirItem(config.TV_RECORD_DIR, None, name=_('Recorded Shows'), display_type='tv') ]
def __init__(self, directory, parent, name='', display_type=None, add_args=None, create_metainfo=True, use_temp=False, cleanup=True): logger.log( 9, '%s.__init__(directory=%r, parent=%r, name=%r, display_type=%r, add_args=%r, create_metainfo=%r, use_temp=%r, cleanup=%r)', self.__class__, directory, parent, name, display_type, add_args, create_metainfo, use_temp, cleanup) self.archive = os.path.abspath(directory) self.cleanup = cleanup self.valid = False fname = os.path.splitext(os.path.basename(self.archive))[0] # create the tmp directory that we will extract the content of the archive to if use_temp: dir = os.path.join(tempfile.gettempdir(), fname) else: dir = vfs.getoverlay(self.archive) try: if not os.path.exists(dir): os.makedirs(dir) except (OSError) as exc: logger.error( 'OS Error %s creating dir %s, skipping this archive...', exc, dir) return self.valid = True self.cover = self.set_cover_image(dir) # now we substitute the original dir/file name with the tmp dir location DirItem.__init__(self, dir, parent=parent, name=fname, display_type=display_type)
def main_menu(self, arg, menuw): items = [] if config.TV_CHANNELS: items.append( menu.MenuItem(_('TV Guide'), action=self.start_tvguide)) items.append( DirItem(config.TV_RECORD_DIR, None, name=_('Recorded Shows'), display_type='tv')) # XXX: these are becomming plugins # items.append(menu.MenuItem(_('Search Guide'), action=self.show_search)) plugins_list = plugin.get('mainmenu_tv') for p in plugins_list: items += p.items(self) menuw.pushmenu( menu.Menu(_('TV Main Menu'), items, item_types='tv main menu'))
def __init__(self, required_space): plugin.DaemonPlugin.__init__(self) self.poll_interval = 1.0 # 1 second self.poll_menu_only = False self.required_space = required_space self.last_time = 0; self.menu = None self.menuw = None self.interested_series = None self.files = [] self.recordings_dir_item = DirItem(config.TV_RECORD_DIR, None) self.update_recordings() # If the recordings dir is on a network mount inotify won't work # so resort to using a timer. if util.fileops.is_net_mount(config.TV_RECORD_DIR): logger.debug('DiskManager using timer as recordings dir is on a network mount') self.check_timer = kaa.Timer(self.check_recordings) self.check_timer.start(0.5) else: logger.debug('DiskManager using inotify') util.inotify.watch(config.TV_RECORD_DIR).connect(self.check_recordings)
def create_metainfo(self): """ create some metainfo for the archive """ logger.log(9, 'create_metainfo()') display_type = self.display_type name = display_type or 'all' # check autovars for var, val in self.autovars: if var == 'num_%s_timestamp' % name: break else: self.autovars += [ ('num_%s_timestamp' % name, 0), ('num_%s_items' % name, 0), ('num_%s_total_items' % name, 0) ] try: timestamp = os.stat(self.dir)[stat.ST_MTIME] except OSError: return num_timestamp = self.info['num_%s_timestamp' % name] if not num_timestamp or num_timestamp < timestamp: logger.debug('Create metainfo for %s, display_type=%s', self.archive, self.display_type) if self.media: self.media.mount() num_dir_items = 0 num_play_items = 0 files = [] try: if zipfile.is_zipfile(self.archive): archive = zipfile.ZipFile(self.archive, 'r') files = archive.infolist() names = archive.namelist() elif tarfile.is_tarfile(self.archive): archive = tarfile.open(self.archive, 'r') files = archive.getmembers() names = archive.getnames() elif ARCHIVE_RAR_AVAILABLE and rarfile.is_rarfile(self.archive): archive = rarfile.RarFile(self.archive, 'r') files = archive.infolist() names = archive.namelist() except (ZipError, RarError, TarError) as exc: logger.warning('Archive %s error: %s', self.archive, exc) self.valid = False # play items and playlists for p in plugin.mimetype(display_type): num_play_items += p.count(self, names) # normal DirItems for file in files: if is_dir(file): num_dir_items += 1 # store info self['num_dir_items'] = num_dir_items self['num_%s_items' % name] = num_play_items self['num_%s_timestamp' % name] = timestamp total_play_items = DirItem.get_play_items_recursive(self, name) # some items such as archives are not walkable, hence no way to # calculate total number of playable items in the directory tree. logger.debug('self.name=%r, display_type=%r, total_play_items=%r, num_play_items=%r, num_dir_items=%r', self.name, name, total_play_items, num_play_items, num_dir_items) if total_play_items < num_play_items + num_dir_items: total_play_items = num_play_items + num_dir_items self['num_%s_total_items' % name] = total_play_items if self.media: self.media.umount()
def build(self, arg=None, menuw=None): """ build the items for the archive """ logger.log(9, 'build(arg=%r, menuw=%r)', arg, menuw) osd.get_singleton().busyicon.wait(config.OSD_BUSYICON_TIMER[0]) archive = None try: if zipfile.is_zipfile(self.archive): archive = zipfile.ZipFile(self.archive, 'r') files = archive.infolist() elif tarfile.is_tarfile(self.archive): archive = tarfile.open(self.archive, 'r') files = archive.getmembers() elif ARCHIVE_RAR_AVAILABLE and rarfile.is_rarfile(self.archive): archive = rarfile.RarFile(self.archive, 'r') files = archive.infolist() else: # fallback, nothing to do, not an archive super(DirItem, self).build(arg, menuw) return except (ZipError, RarError, TarError) as exc: logger.warning('Archive %s error: %s', self.archive, exc) self.valid = False osd.get_singleton().busyicon.stop() DirItem.build(self, arg, menuw) return # display the msg box pop = None to_extract = 0 xfiles = [] for f in files: logger.debug('testing for %s', os.path.join(self.dir, get_filename(f))) if not os.path.exists(os.path.join(self.dir, get_filename(f))): logger.debug('%s not found, will extract', os.path.join(self.dir, get_filename(f))) xfiles.append(f) if len(xfiles) > 8 and skin.active(): pop = CacheProgressDialog(_('Extracting from archive, be patient...'), len(xfiles)) pop.show() elif len(xfiles) > config.OSD_BUSYICON_TIMER[1]: # many files, just show the busy icon now osd.get_singleton().busyicon.wait(0) # extract one file at the time, bump the progress bar for each file extracted for f in xfiles: archive.extract(f, self.dir) if pop: pop.processed_file() # get rid of the msg box if pop: pop.hide() # stop the timer. If the icons is drawn, it will stay there # until the osd is redrawn, if not, we don't need it to pop # up the next milliseconds osd.get_singleton().busyicon.stop() exclude = '' if self.cover: # we do not want to include the cover img we just created # we store original config.IMAGE_EXCLUDE first, then set it to cover exclude = config.IMAGE_EXCLUDE config.IMAGE_EXCLUDE = ['cover'] # now we let the base class handle the tmp directory DirItem.build(self, arg, menuw) if self.cover: # and now we restore original cover.IMAGE_RESTORE config.IMAGE_EXCLUDE = exclude
def build(self, arg=None, menuw=None): """ build the items for the archive """ logger.log(9, 'build(arg=%r, menuw=%r)', arg, menuw) osd.get_singleton().busyicon.wait(config.OSD_BUSYICON_TIMER[0]) archive = None try: if zipfile.is_zipfile(self.archive): archive = zipfile.ZipFile(self.archive, 'r') files = archive.infolist() elif tarfile.is_tarfile(self.archive): archive = tarfile.open(self.archive, 'r') files = archive.getmembers() elif ARCHIVE_RAR_AVAILABLE and rarfile.is_rarfile(self.archive): archive = rarfile.RarFile(self.archive, 'r') files = archive.infolist() else: # fallback, nothing to do, not an archive super(DirItem, self).build(arg, menuw) return except (ZipError, RarError, TarError) as exc: _debug_('Archive %s error: %s' % (self.archive, exc), 1) self.valid = False osd.get_singleton().busyicon.stop() DirItem.build(self, arg, menuw) return # display the msg box pop = None to_extract = 0 xfiles = [] for f in files: logger.debug('testing for %s', os.path.join(self.dir, get_filename(f))) if not os.path.exists(os.path.join(self.dir, get_filename(f))): logger.debug('%s not found, will extract', os.path.join(self.dir, get_filename(f))) xfiles.append(f) if len(xfiles) > 8 and skin.active(): pop = CacheProgressDialog( _('Extracting from archive, be patient...'), len(xfiles)) pop.show() elif len(xfiles) > config.OSD_BUSYICON_TIMER[1]: # many files, just show the busy icon now osd.get_singleton().busyicon.wait(0) # extract one file at the time, bump the progress bar for each file extracted for f in xfiles: archive.extract(f, self.dir) if pop: pop.processed_file() # get rid of the msg box if pop: pop.hide() # stop the timer. If the icons is drawn, it will stay there # until the osd is redrawn, if not, we don't need it to pop # up the next milliseconds osd.get_singleton().busyicon.stop() exclude = '' if self.cover: # we do not want to include the cover img we just created # we store original config.IMAGE_EXCLUDE first, then set it to cover exclude = config.IMAGE_EXCLUDE config.IMAGE_EXCLUDE = ['cover'] # now we let the base class handle the tmp directory DirItem.build(self, arg, menuw) if self.cover: # and now we restore original cover.IMAGE_RESTORE config.IMAGE_EXCLUDE = exclude
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 create_metainfo(self): """ create some metainfo for the archive """ logger.log(9, 'create_metainfo()') display_type = self.display_type name = display_type or 'all' # check autovars for var, val in self.autovars: if var == 'num_%s_timestamp' % name: break else: self.autovars += [('num_%s_timestamp' % name, 0), ('num_%s_items' % name, 0), ('num_%s_total_items' % name, 0)] try: timestamp = os.stat(self.dir)[stat.ST_MTIME] except OSError: return num_timestamp = self.info['num_%s_timestamp' % name] if not num_timestamp or num_timestamp < timestamp: logger.debug('Create metainfo for %s, display_type=%s', self.archive, self.display_type) if self.media: self.media.mount() num_dir_items = 0 num_play_items = 0 files = [] try: if zipfile.is_zipfile(self.archive): archive = zipfile.ZipFile(self.archive, 'r') files = archive.infolist() names = archive.namelist() elif tarfile.is_tarfile(self.archive): archive = tarfile.open(self.archive, 'r') files = archive.getmembers() names = archive.getnames() elif ARCHIVE_RAR_AVAILABLE and rarfile.is_rarfile( self.archive): archive = rarfile.RarFile(self.archive, 'r') files = archive.infolist() names = archive.namelist() except (ZipError, RarError, TarError) as exc: logger.warning('Archive %s error: %s', self.archive, exc) self.valid = False # play items and playlists for p in plugin.mimetype(display_type): num_play_items += p.count(self, names) # normal DirItems for file in files: if is_dir(file): num_dir_items += 1 # store info self['num_dir_items'] = num_dir_items self['num_%s_items' % name] = num_play_items self['num_%s_timestamp' % name] = timestamp total_play_items = DirItem.get_play_items_recursive(self, name) # some items such as archives are not walkable, hence no way to # calculate total number of playable items in the directory tree. logger.debug( 'self.name=%r, display_type=%r, total_play_items=%r, num_play_items=%r, num_dir_items=%r', self.name, name, total_play_items, num_play_items, num_dir_items) if total_play_items < num_play_items + num_dir_items: total_play_items = num_play_items + num_dir_items self['num_%s_total_items' % name] = total_play_items if self.media: self.media.umount()
def items(self, parent): if util.is_usb_storage_device() != -1: d = DirItem(self.mountpoint, parent, self.name, display_type=parent.display_type) d.mountpoint = self.mountpoint return [ d ] return []
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