Esempio n. 1
0
    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)
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
 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 []
Esempio n. 5
0
 def items(self, parent):
     return [
         DirItem(config.TV_RECORD_DIR,
                 None,
                 name=_('Recorded Shows'),
                 display_type='tv')
     ]
Esempio n. 6
0
    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)
Esempio n. 7
0
    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'))
Esempio n. 8
0
 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)
Esempio n. 9
0
    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()
Esempio n. 10
0
    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
Esempio n. 11
0
    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
Esempio n. 12
0
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
Esempio n. 13
0
    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()
Esempio n. 14
0
 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 []
Esempio n. 15
0
    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