Пример #1
0
 def get(self, fileUrl):
     """
     @return: local path if file resolution was successful, None otherwise
     """
     filepath = self._mapToPath(fileUrl) 
     if not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
         log.debug('Cache MISS %s' % safe_str(fileUrl))
         
         self.lockResource(fileUrl)
         try:
             if not self.contains(fileUrl): 
                 self.resolver.store(fileUrl, filepath)
         finally:
             self.unlockResource(fileUrl)
         
         # Don't cache zero byte files
         if not os.path.exists(filepath):
             log.warn('File could not be resolved: %s and not at path: %s' % (safe_str(fileUrl), filepath) )
             return None
         
         if os.path.getsize(filepath) == 0:
             log.warn('file %s resulted in zero byte file...removing...' % safe_str(fileUrl))
             self.remove(fileUrl)
             return None
     else:
         if log.isEnabledFor(logging.DEBUG):
             if hasattr(fileUrl, 'title'):
                 s = fileUrl.title()
             elif hasattr(fileUrl, 'getChannelName'):
                 s = fileUrl.getChannelName()
             else:
                 s = fileUrl
             #log.debug('Cache HIT %s ' % safe_str(s))
     return filepath
Пример #2
0
 def renderProgramInfo(self, program):
     if program:
         log.debug('Show info for ' + safe_str(program.title()))
         self.setWindowProperty('title', program.fullTitle())
         self.setWindowProperty('category', program.category())
         self.setWindowProperty('description', program.description())
         self.setWindowProperty('subtitle', program.subtitle())
         self.setWindowProperty('airtime', program.formattedAirTime())
         self.setWindowProperty('duration', program.formattedDuration())
         self.setWindowProperty('originalAirDate', program.formattedOriginalAirDate())
         
         season, episode = self.fanArt.getSeasonAndEpisode(program)
         if not season is None and not episode is None:
             self.setWindowProperty('seasonAndEpisode', '%sx%s' % (season, episode))
         else:
             self.setWindowProperty('seasonAndEpisode', '-')
             
         self.setWindowProperty('banner', u'')
         if self.fanArt.hasBanners(program):
             bannerPath = self.fanArt.pickBanner(program)
             self.setWindowProperty('banner', [u'',bannerPath][bannerPath is not None])
         else:
             log.debug('Added to bannerqueue: %s' % safe_str(program.title()))
             self.bannerQueue.put(program)
     else:
         self.setWindowProperty('title', u'')
         self.setWindowProperty('category', u'')
         self.setWindowProperty('description', u'')
         self.setWindowProperty('subtitle', u'')
         self.setWindowProperty('airtime', u'')
         self.setWindowProperty('duration', u'')
         self.setWindowProperty('originalAirDate', u'')
         self.setWindowProperty('banner', u'')
         self.setWindowProperty('seasonAndEpisode', u'')
Пример #3
0
    def addJob(self, job):
        '''Add a new job to the job queue'''        
        sql = """INSERT INTO jobqueue (
                    chanid,
                    starttime,
                    type,
                    inserttime,
                    hostname, 
                    status,
                    comment, 
                    schedruntime)
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"""
        
        log.debug("sql = %s" % safe_str(sql))
        args = (job.channelId, job.startTime, job.jobType, job.insertTime, job.hostname, job.jobStatus, job.comment, datetime.datetime.now(),)

        if log.isEnabledFor(logging.DEBUG):
            for i,arg in enumerate(args):
                log.debug('Positional arg %d: %s' % (i,safe_str(arg)))

        c = self.conn.cursor(*cursorArgs)       
        try:
            c.execute(sql, args)
        finally:
            c.close()

        if job.id is None:
            c2 = self.conn.cursor(*cursorArgs)
            try:
                c2.execute("select max(id) from jobqueue")
                job.id = c2.fetchall()[0][0]
                log.debug('New job id = %s' % job.id)
            finally:
                c2.close()
Пример #4
0
    def getPosters(self, program):
        posters = []
        if program.isMovie():
            try:
                results = self.mdb.search(program.title())
                if results and len(results) > 0:
                    filmId = results[0]['id']
                    film = self.mdb.getMovieInfo(filmId)
                    
                    for id in film['images']['poster']:
                        if 'mid' in film['images']['poster'][id]:
                        #for size in film['images']['poster'][id]:
                            size = 'mid'
                            url = film['images']['poster'][id][size]
                            #log.debug('TMDB: %s size = %s  url = %s' % (id, size, url))
                            posters.append(url)

                    #for i, result in enumerate(results):    
                        # Poster keys: 
                        #    'cover'      -- little small - 185px by 247px 
                        #    'mid'        -- just right   - 500px by 760px
                        #    'original'   -- can be huge  - 2690px by 3587px
                        #    'thumb'      -- tiny         - 92px by 136px
                        
                        #for key, value in result['poster'].items():
                        #    log.debug('TMDB: %d key = %s  value = %s' % (i, key, value))

                        #if  'mid' in result['poster']:
                        #    posters.append(result['poster']['mid'])
                else:
                    log.debug('TMDB: Found nothing for: %s' % safe_str(program.title()))
            except Exception, e:
                log.exception('TMDB: Fanart search error: %s %s' % (safe_str(program.title()), safe_str(e)))
Пример #5
0
    def getUpcomingRecordings(self, filter=Upcoming.SCHEDULED):
        """
        @type filter: UPCOMING_*
        @rtype: RecordedProgram[]
        """
        upcoming = []
        reply = self._sendRequest(self.cmdSock, ['QUERY_GETALLPENDING', '2'])

        log.debug('getUpcomingRecordings reply begin= %s' %
                  safe_str(reply[:80]))
        log.debug('getUpcomingRecordings reply end  = %s' %
                  safe_str(reply[-80:]))

        numRows = int(reply[1])
        offset = 2

        from mythbox.mythtv.domain import RecordedProgram
        for i in xrange(numRows):
            program = RecordedProgram(
                reply[offset:offset + self.protocol.recordSize()],
                self.settings, self.translator, self.platform, self.protocol,
                [self, None][self._db is None])
            if program.getRecordingStatus() in filter:
                upcoming.append(program)
            offset += self.protocol.recordSize()
        return upcoming
Пример #6
0
    def addJob(self, job):
        '''Add a new job to the job queue'''        
        sql = """INSERT INTO jobqueue (
                    chanid,
                    starttime,
                    type,
                    inserttime,
                    hostname, 
                    status,
                    comment, 
                    schedruntime)
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"""
        
        log.debug("sql = %s" % safe_str(sql))
        args = (job.channelId, job.startTime, job.jobType, job.insertTime, job.hostname, job.jobStatus, job.comment, datetime.datetime.now(),)

        if log.isEnabledFor(logging.DEBUG):
            for i,arg in enumerate(args):
                log.debug('Positional arg %d: %s' % (i,safe_str(arg)))

        c = self.conn.cursor(*cursorArgs)       
        try:
            c.execute(sql, args)
        finally:
            c.close()

        if job.id is None:
            c2 = self.conn.cursor(*cursorArgs)
            try:
                c2.execute("select max(id) from jobqueue")
                job.id = c2.fetchall()[0][0]
                log.debug('New job id = %s' % job.id)
            finally:
                c2.close()
Пример #7
0
 def renderProgramInfo(self, program):
     if program:
         log.debug('Show info for ' + safe_str(program.title()))
         self.setWindowProperty('title', program.fullTitle())
         self.setWindowProperty('category', program.category())
         self.setWindowProperty('description', program.description())
         self.setWindowProperty('subtitle', program.subtitle())
         self.setWindowProperty('airtime', program.formattedAirTime())
         self.setWindowProperty('duration', program.formattedDuration())
         self.setWindowProperty('originalAirDate', program.formattedOriginalAirDate())
         self.setWindowProperty('banner', u'')
         if self.fanArt.hasBanners(program):
             bannerPath = self.fanArt.pickBanner(program)
             self.setWindowProperty('banner', [u'',bannerPath][bannerPath is not None])
         else:
             log.debug('Added to bannerqueue: %s' % safe_str(program.title()))
             self.bannerQueue.put(program)
     else:
         self.setWindowProperty('title', u'')
         self.setWindowProperty('category', u'')
         self.setWindowProperty('description', u'')
         self.setWindowProperty('subtitle', u'')
         self.setWindowProperty('airtime', u'')
         self.setWindowProperty('duration', u'')
         self.setWindowProperty('originalAirDate', u'')
         self.setWindowProperty('banner', u'')
Пример #8
0
 def work(p):
     posters = provider.getPosters(p)
     if len(posters) == 0:
         log.exception('Failed on %s' % safe_str(p.title()))
         self.fail = True
     for poster in posters:
         log.debug('%s - %s' % (safe_str(p.title()), poster))
Пример #9
0
class ImdbFanartProvider(NoOpFanartProvider):
    def __init__(self):
        NoOpFanartProvider.__init__(self)
        self.imdb = imdb.IMDb(
            accessSystem=None
        )  # loggingConfig='~/git/mythbox/mythbox_log.ini')

    @max_threads(1)
    @timed
    def getPosters(self, program):
        if not program.isMovie():
            return []

        posters = []
        try:
            movies = self.imdb.search_movie(title=u'' + program.title(),
                                            results=1)
            for movie in movies:
                m = self.imdb.get_movie(movie.getID())
                #for key,value in m.items():
                #    log.warn('movie[%d] id[%s] key[%s] -> %s' % (1, m.getID(), key, safe_str(value)))
                posters.append(m['full-size cover url'])
        except imdb.IMDbError, e:
            log.error('IMDB: Error looking up movie: %s %s' %
                      (safe_str(program.title()), safe_str(str(e))))
        except Exception, e:
            log.error('IMDB: Error looking up %s: %s' %
                      (safe_str(program.title()), safe_str(str(e))))
Пример #10
0
 def work(p):
     posters = provider.getPosters(p)
     if len(posters) == 0:
         log.exception('Failed on %s' % safe_str(p.title()))
         self.fail = True
     for poster in posters:
         log.debug('%s - %s' % (safe_str(p.title()), poster))
Пример #11
0
    def getUpcomingRecordings(self, filter=Upcoming.SCHEDULED):
        """
        @type filter: UPCOMING_*
        @rtype: RecordedProgram[]
        """
        upcoming = []
        reply = self._sendRequest(self.cmdSock, ['QUERY_GETALLPENDING', '2'])
        
        log.debug('getUpcomingRecordings reply begin= %s' % safe_str(reply[:80]))
        log.debug('getUpcomingRecordings reply end  = %s' % safe_str(reply[-80:]))
        
        numRows = int(reply[1])
        offset = 2

        from mythbox.mythtv.domain import RecordedProgram
        for i in xrange(numRows):
            program = RecordedProgram(
                    reply[offset:offset+self.protocol.recordSize()],
                    self.settings, 
                    self.translator,
                    self.platform,
                    self.protocol,
                    [self, None][self._db is None])
            if program.getRecordingStatus() in filter:
                upcoming.append(program)
            offset += self.protocol.recordSize()
        return upcoming
Пример #12
0
 def createEpisodeKey(self, methodName, program):
     return '-'.join(
         str(k) for k in [
             methodName,
             safe_str(program.title()),
             safe_str(program.subtitle()),
             program.originalAirDate()
         ])
Пример #13
0
 def queryTvRage(self, program):
     try:
         show = self.indexEpisodes(tvrage.api.Show(program.title()))
         self.save(program, show)
         return self.searchForEpisode(program, show)
     except tvrage.api.ShowNotFound:
         log.debug('TVRage: Show not found - %s' % safe_str(program.title()))
         return None, None
     except KeyError, ke:
         # TVRage throws KeyError on last line of constructor for incomplete
         # datasets
         log.warn('TVRage: KeyError %s - %s' % (safe_str(ke), safe_str(program.title())))
         return None, None
Пример #14
0
 def getBackgrounds(self, program):
     backgrounds = []
     if not program.isMovie():
         t = self.transform(program.title())
         try:
             backgroundsByDimension = self._queryTvDb(t, qtype='fanart')
             for knownDim in ['1280x720', '1920x1080']:
                 if knownDim in backgroundsByDimension:
                     backgroundsById = backgroundsByDimension[knownDim]
                     for id in backgroundsById.keys():
                         backgrounds.append(backgroundsById[id]['_bannerpath'])
         except Exception, e:
             log.debug('TVDB: No backgrounds for %s - %s' % (safe_str(t), safe_str(e)))
Пример #15
0
 def renderBanners(self, myRenderToken):
     log.debug('---- RENDER BANNER BEGIN ----')
     for channel, li in self.listItemsByChannel.items():
         if self.closed or xbmc.abortRequested or myRenderToken != self.activeRenderToken:
             return
         if channel.currentProgram and channel.needsBanner:
             channel.needsBanner = False
             bannerPath = self.fanArt.pickBanner(channel.currentProgram)
             if bannerPath:
                 log.debug('setting banner for %s to %s' % (safe_str(channel.currentProgram.title()), bannerPath))
                 self.updateListItemProperty(li, 'banner', bannerPath)
             else:
                 log.debug('no banner for %s' % safe_str(channel.currentProgram.title()))
     log.debug('---- RENDER BANNER END ----')
Пример #16
0
 def getPosters(self, program):
     posters = []
     if program.isMovie():
         try:
             movies = self.imdb.search_movie(title=u'' + program.title(), results=1)
             for movie in movies:
                 m = self.imdb.get_movie(movie.getID())
                 #for key,value in m.items():
                 #    log.warn('movie[%d] id[%s] key[%s] -> %s' % (1, m.getID(), key, safe_str(value)))
                 posters.append(m['full-size cover url'])  
         except imdb.IMDbError, e:
             log.error('IMDB error looking up movie: %s %s' % (safe_str(program.title()), safe_str(str(e))))
         except Exception, e:
             log.error('IMDB error looking up %s: %s' % (safe_str(program.title()), safe_str(str(e))))
Пример #17
0
 def renderBanners(self, myRenderToken):
     log.debug('---- RENDER BANNER BEGIN ----')
     for channel, li in self.listItemsByChannel.items():
         if self.closed or xbmc.abortRequested or myRenderToken != self.activeRenderToken:
             return
         if channel.currentProgram and channel.needsBanner:
             channel.needsBanner = False
             bannerPath = self.fanArt.pickBanner(channel.currentProgram)
             if bannerPath:
                 log.debug('setting banner for %s to %s' % (safe_str(channel.currentProgram.title()), bannerPath))
                 self.updateListItemProperty(li, 'banner', bannerPath)
             else:
                 log.debug('no banner for %s' % safe_str(channel.currentProgram.title()))
     log.debug('---- RENDER BANNER END ----')
Пример #18
0
 def queryTvRage(self, program):
     try:
         show = self.indexEpisodes(tvrage.api.Show(program.title()))
         self.save(program, show)
         return self.searchForEpisode(program, show)
     except tvrage.api.ShowNotFound:
         log.debug('TVRage: Show not found - %s' % safe_str(program.title()))
         return None, None
     except TypeError, te:
         #  File "tvrage/api.py", line 145, in __init__
         #    for season in eplist:
         #TypeError: iteration over non-sequence
         log.exception('TVRage: TypeError %s - %s' % (safe_str(te), safe_str(program.title())))
         return None, None
Пример #19
0
 def getBanners(self, program):
     if program.isMovie(): 
         return []
     
     banners = []
     t = self.transform(program.title())
     try:
         bannersByType = self._queryTvDb(t, qtype='series')
         for subType in ['graphical', 'text', 'blank']:
             if subType in bannersByType:
                 bannersById = bannersByType[subType]
                 for id in bannersById.keys():
                     banners.append(bannersById[id]['_bannerpath'])
     except Exception, e:
         log.warn('TVDB: No banners for %s - %s' % (safe_str(t), safe_str(e)))
Пример #20
0
 def getBackgrounds(self, program):
     backgrounds = []
     if not program.isMovie():
         t = self.transform(program.title())
         try:
             backgroundsByDimension = self._queryTvDb(t, qtype='fanart')
             for knownDim in ['1280x720', '1920x1080']:
                 if knownDim in backgroundsByDimension:
                     backgroundsById = backgroundsByDimension[knownDim]
                     for id in backgroundsById.keys():
                         backgrounds.append(
                             backgroundsById[id]['_bannerpath'])
         except Exception, e:
             log.debug('TVDB: No backgrounds for %s - %s' %
                       (safe_str(t), safe_str(e)))
Пример #21
0
 def test_getFramerate(self):
     from mythbox.mythtv.conn import Connection
     from mythbox.util import safe_str
     from mythbox.mythtv.enums import RecordingStatus
     
     conn = Connection(settings=self.settings, translator=Mock(), platform=Mock(), bus=Mock(), db=self.db)
     try:
         recordings = conn.getAllRecordings()[-10:]
         for r in recordings:
             if r.isCommFlagged() and r.getRecordingStatus() == RecordingStatus.RECORDED:
                 fps  = self.db.getFramerate(r)
                 log.debug('%s - %s - %s %d' % (safe_str(r.title()), safe_str(r.subtitle()), fps, r.getRecordingStatus()))
                 self.assertGreaterEqual(fps, 0.0, fps)
     finally:
         conn.close()
         
Пример #22
0
    def getPosters(self, program):
        if not program.isMovie():
            return []

        posters = []
        try:
            movies = self.imdb.search_movie(title=u'' + program.title(),
                                            results=1)
            for movie in movies:
                m = self.imdb.get_movie(movie.getID())
                #for key,value in m.items():
                #    log.warn('movie[%d] id[%s] key[%s] -> %s' % (1, m.getID(), key, safe_str(value)))
                posters.append(m['full-size cover url'])
        except imdb.IMDbError, e:
            log.error('IMDB: Error looking up movie: %s %s' %
                      (safe_str(program.title()), safe_str(str(e))))
Пример #23
0
    def renderProgramInfo(self, program):
        self.program = program
        if program:
            log.debug('Show info for ' + safe_str(program.title()))
            self.setWindowProperty('title', program.fullTitle())
            self.setWindowProperty('category', program.category())
            self.setWindowProperty('description', program.description())
            self.setWindowProperty('subtitle', program.subtitle())
            self.setWindowProperty('airtime', program.formattedAirTime())
            self.setWindowProperty('duration', program.formattedDuration())
            self.setWindowProperty('originalAirDate', program.formattedOriginalAirDate())

            self.renderEpisode(program)
                
            self.setWindowProperty('banner', u'')
            self.bannerQueue.put(program)
        else:
            self.setWindowProperty('title', u'')
            self.setWindowProperty('category', u'')
            self.setWindowProperty('description', u'')
            self.setWindowProperty('subtitle', u'')
            self.setWindowProperty('airtime', u'')
            self.setWindowProperty('duration', u'')
            self.setWindowProperty('originalAirDate', u'')
            self.setWindowProperty('banner', u'')
            self.setWindowProperty('seasonAndEpisode', u'')
Пример #24
0
    def renderCoverFlow(self, exclude=None):
        log.debug('>>> renderCoverFlow begin')
        self.recordings = self.conn().getAllRecordings()
        
        if exclude:
            try:
                self.recordings.remove(exclude)
            except:
                pass
        
        self.coverItems = []
            
        for i, r in enumerate(self.recordings[:MAX_COVERFLOW]):
            log.debug('Coverflow %d/%d: %s' % (i+1, MAX_COVERFLOW, safe_str(r.title())))
            listItem = xbmcgui.ListItem() 
            self.setListItemProperty(listItem, 'title', r.title())
            self.setListItemProperty(listItem, 'description', r.description())
            
            cover = self.fanArt.pickPoster(r)
            if not cover:
                cover = self.mythThumbnailCache.get(r)
                if not cover:
                    cover = 'mythbox-logo.png'
            self.updateListItemProperty(listItem, 'thumb', cover)
            self.coverItems.append(listItem)

        # NOTE: apparently, updating listitem properties broke in eden creating dupes.
        #       reset as a workaround for the time being.
        self.coverFlow.reset()
        self.coverFlow.addItems(self.coverItems)
        log.debug('<<< renderCoverFlow end')
Пример #25
0
    def renderGroups(self):
        lastSelectedIndex = 0
        self.groupsListItems = []
        
        sortedGroups = self.groupsByTitle.values()[:]
        sortedGroups.sort(key=self.GROUP_SORT_BY[self.groupSortBy]['sorter'], reverse=self.GROUP_SORT_BY[self.groupSortBy]['reverse'])
                    
        for i, group in enumerate(sortedGroups):
            title = group.title
  
            #log.debug('YYY %s %s' % (type(title), safe_str(title)))
            #log.debug('ZZZ %s %s' % (type(group.title), safe_str(group.title)))
            
            group.listItem = xbmcgui.ListItem()
            group.index = i
            self.groupsListItems.append(group.listItem)
            self.setListItemProperty(group.listItem, 'index', str(i))
            self.setListItemProperty(group.listItem, 'title', title)
            self.setListItemProperty(group.listItem, 'num_episodes', str(len(group.programs)))

            #vtitle = group.listItem.getProperty('title')
            #log.debug('\n\nAAA %s %s\n' % (type(vtitle), safe_str(vtitle)))

            if self.lastSelectedGroup == title:
                lastSelectedIndex = i
                log.debug('Last selected group index = %s %s' % (safe_str(title), lastSelectedIndex))

        self.groupsListbox.reset()
        self.groupsListbox.addItems(self.groupsListItems)
        self.selectListItemAtIndex(self.groupsListbox, lastSelectedIndex)
        
        log.debug('index check = %s' % self.groupsListbox.getSelectedPosition())
        self.onGroupSelect()
Пример #26
0
    def renderProgramInfo(self, program):
        self.program = program
        if program:
            log.debug('Show info for ' + safe_str(program.title()))
            self.setWindowProperty('title', program.fullTitle())
            self.setWindowProperty('category', program.category())
            self.setWindowProperty('description', program.description())
            self.setWindowProperty('subtitle', program.subtitle())
            self.setWindowProperty('airtime', program.formattedAirTime())
            self.setWindowProperty('duration', program.formattedDuration())
            self.setWindowProperty('originalAirDate',
                                   program.formattedOriginalAirDate())

            self.renderEpisode(program)

            self.setWindowProperty('banner', u'')
            self.bannerQueue.put(program)
        else:
            self.setWindowProperty('title', u'')
            self.setWindowProperty('category', u'')
            self.setWindowProperty('description', u'')
            self.setWindowProperty('subtitle', u'')
            self.setWindowProperty('airtime', u'')
            self.setWindowProperty('duration', u'')
            self.setWindowProperty('originalAirDate', u'')
            self.setWindowProperty('banner', u'')
            self.setWindowProperty('seasonAndEpisode', u'')
Пример #27
0
    def renderCoverFlow(self, exclude=None):
        log.debug('>>> renderCoverFlow begin')
        self.recordings = self.conn().getAllRecordings()

        if exclude:
            try:
                self.recordings.remove(exclude)
            except:
                pass

        self.coverItems = []

        for i, r in enumerate(self.recordings[:MAX_COVERFLOW]):
            log.debug('Coverflow %d/%d: %s' %
                      (i + 1, MAX_COVERFLOW, safe_str(r.title())))
            listItem = xbmcgui.ListItem()
            self.setListItemProperty(listItem, 'title', r.title())
            self.setListItemProperty(listItem, 'description', r.description())

            cover = self.fanArt.pickPoster(r)
            if not cover:
                cover = self.mythThumbnailCache.get(r)
                if not cover:
                    cover = 'mythbox-logo.png'
            self.updateListItemProperty(listItem, 'thumb', cover)
            self.coverItems.append(listItem)

        # NOTE: apparently, updating listitem properties broke in eden creating dupes.
        #       reset as a workaround for the time being.
        self.coverFlow.reset()
        self.coverFlow.addItems(self.coverItems)
        log.debug('<<< renderCoverFlow end')
Пример #28
0
    def setBookmark(self, program, frameNumber):
        """
        Sets the bookmark for the given program to frameNumber. 
        Raises ServerException on failure.
        """
        tokens = [
            'SET_BOOKMARK',
            '%s' % program.getChannelId(),
            '%s' % program.recstarttimets()
        ]
        self.protocol.writeLong(frameNumber, tokens)

        # pad with 'dont_care' if frameNumber not split into high/low bytes
        if len(tokens) == 4:
            tokens.append('dont_care')

        reply = self._sendRequest(self.cmdSock, [' '.join(tokens)])

        if reply[0] == 'OK':
            log.debug("Bookmark frameNumber set to %s" % frameNumber)
        elif reply[0] == 'FAILED':
            raise ServerException(
                "Failed to save position in program '%s' to frame %s. Server response: %s"
                % (safe_str(program.title()), frameNumber, reply[0]))
        else:
            raise ProtocolException('Unexpected return value: %s' % reply[0])
Пример #29
0
 def startup(self):
     """
     @return: True if startup successful, False otherwise
     """
     self.settingsOK = False
     try:
         self.settings.verify()
         self.settingsOK = True
     except SettingsException, se:
         showPopup(self.t(m.ERROR), safe_str(se), 7000)
         if se.wakeup and self.settings.get("wakeup_command"):
             showPopup(self.t(m.INFO), "Waking the backend up", 7000)
             subprocess.call(self.settings.get("wakeup_command"),
                             shell=True)
             time.sleep(int(self.settings.get("wakeup_wait")))
             try:
                 self.settings.verify()
                 self.settingsOK = True
             except SettingsException:
                 pass
         if not self.settingsOK:
             self.goSettings()
             try:
                 self.settings.verify() # TODO: optimize unnecessary re-verify
                 self.settingsOK = True
             except SettingsException:
                 self.shutdown()
                 self.close()
                 return False
Пример #30
0
 def createKey(self, method, program):
     if method != 'getSeasonAndEpisode':
         return '%s-%s' % (method, md5(safe_str(
             program.title())).hexdigest())
     else:
         return ('getSeasonAndEpisode', program.title(), program.subtitle(),
                 program.originalAirDate())
Пример #31
0
def showPopup(title, text, millis=10000):
    # filter all commas out of text since they delimit args
    title = title.replace(',', ';')
    text = text.replace(',', ';')
    s = u'XBMC.Notification(%s,%s,%s)'  % (title, text, millis)
    log.debug('showPopup: %s' % safe_str(s))
    xbmc.executebuiltin(s)
Пример #32
0
 def __str__(self):
     s = """
     group         = %s
     num programs  = %d 
     num listitems = %d
     num li map    = %d """ % (safe_str(self.title), len(self.programs), len(self.listItems), len(self.programsByListItem))
     return s
Пример #33
0
 def getBanners(self, program):
     if program.isMovie(): 
         return []
     
     banners = []
     t = self.overrides.get(program.title(), program.title())
     try:
         with self.lock:
             bannersByType = self._queryTvDb(t, qtype='series')
             for subType in ['graphical', 'text', 'blank']:
                 if subType in bannersByType:
                     bannersById = bannersByType[subType]
                     for id in bannersById.keys():
                         banners.append(bannersById[id]['_bannerpath'])
     except Exception, e:
         log.warn('TVDB: No banners for %s - %s' % (safe_str(t), safe_str(e)))
Пример #34
0
 def _saveLastPositionAsBookmark(self):
     lastPos = self.player.tracker.getLastPosition()
     log.debug('Setting bookmark on %s to %s' %(safe_str(self.program.title()), formatSeconds(lastPos)))
     try:
         self.program.setBookmark(lastPos)
     except:
         log.exception('_saveLastPositionAsBookmark catchall')
Пример #35
0
    def renderGroups(self):
        lastSelectedIndex = 0
        self.groupsListItems = []
        
        sortedGroups = self.groupsByTitle.values()[:]
        sortedGroups.sort(key=self.GROUP_SORT_BY[self.groupSortBy]['sorter'], reverse=self.GROUP_SORT_BY[self.groupSortBy]['reverse'])
                    
        for i, group in enumerate(sortedGroups):
            title = group.title
  
            #log.debug('YYY %s %s' % (type(title), safe_str(title)))
            #log.debug('ZZZ %s %s' % (type(group.title), safe_str(group.title)))
            
            group.listItem = xbmcgui.ListItem()
            group.index = i
            self.groupsListItems.append(group.listItem)
            self.setListItemProperty(group.listItem, 'index', str(i))
            self.setListItemProperty(group.listItem, 'title', title)
            self.setListItemProperty(group.listItem, 'num_episodes', str(len(group.programs)))

            #vtitle = group.listItem.getProperty('title')
            #log.debug('\n\nAAA %s %s\n' % (type(vtitle), safe_str(vtitle)))

            if self.lastSelectedGroup == title:
                lastSelectedIndex = i
                log.debug('Last selected group index = %s %s' % (safe_str(title), lastSelectedIndex))

        self.groupsListbox.reset()
        self.groupsListbox.addItems(self.groupsListItems)
        self.selectListItemAtIndex(self.groupsListbox, lastSelectedIndex)
        
        log.debug('index check = %s' % self.groupsListbox.getSelectedPosition())
        self.onGroupSelect()
Пример #36
0
 def _trackCommercials(self):
     """Method run in a separate thread to skip over commercials"""
     try:
         if len(self._breaks) == 0:
             log.debug('Recording %s has no comm breaks, exiting comm tracker' % safe_str(self.program.title()))
             return
         
         while self.player.isPlaying():
             pos = self.player.getTime()
             if self._isInBreak(pos) and not self._currentBreak.skipped:
                 log.debug('entered comm break = %s' % self._currentBreak)
                 if self._isCloseToStartOfCommercial(pos) and not self._wasUserSkippingAround(pos): 
                     log.debug('Comm skip activated!')
                     showPopup(self.program.title(), self.translator.get(m.SKIPPING_COMMERCIAL) % formatSeconds(self._currentBreak.duration()), 3000)
                     self.player.seekTime(self._currentBreak.end)
                     self._waitForPlayerToPassCommercialBreak()
                     self._currentBreak.skipped = True
                     
                 if self._landedInCommercial(pos):
                     log.debug("Landed in comm break and want to skip forward")  
                     showPopup(self.program.title(), self.translator.get(m.FORWARDING_THROUGH) % formatSeconds(self._currentBreak.duration()), 3000)
                     self.player.seekTime(self._currentBreak.end)
                     self._waitForPlayerToPassCommercialBreak()
                     self._currentBreak.skipped = True
             xbmc.sleep(SLEEP_MILLIS)
         log.debug('Commercial tracker thread exiting')
     except:
         log.exception('_trackCommercials catchall')
Пример #37
0
 def __str__(self):
     s = """
     group         = %s
     num programs  = %d 
     num listitems = %d
     num li map    = %d """ % (safe_str(self.title), len(self.programs), len(self.listItems), len(self.programsByListItem))
     return s
Пример #38
0
def showPopup(title, text, millis=10000):
    # filter all commas out of text since they delimit args
    title = title.replace(',', ';')
    text = text.replace(',', ';')
    s = u'XBMC.Notification(%s,%s,%s)'  % (title, text, millis)
    log.debug('showPopup: %s' % safe_str(s))
    xbmc.executebuiltin(s)
Пример #39
0
    def onAction(self, action):
        id = action.getId()

        if id in Action.GO_BACK:
            self.closed = True
            self.settings.put('livetv_last_selected',
                              str(self.channelsListBox.getSelectedPosition()))
            self.close()

        elif id in (
                Action.UP,
                Action.DOWN,
                Action.PAGE_DOWN,
                Action.PAGE_UP,
        ):
            self.lastSelected = self.channelsListBox.getSelectedPosition()
            channel = self.listItem2Channel(
                self.channelsListBox.getSelectedItem())
            if channel.currentProgram and channel.needsPoster:
                log.debug('Adding %s:%s to poster lookup q' %
                          (channel.getChannelNumber(),
                           safe_str(channel.currentProgram.title())))
                [self.tvQueue, self.movieQueue
                 ][channel.currentProgram.isMovie()].append(channel)

        elif id in (
                Action.ACTION_NEXT_ITEM,
                Action.ACTION_PREV_ITEM,
        ):  # bottom, top
            if self.lastFocusId == ID_CHANNELS_LISTBOX:
                self.selectListItemAtIndex(self.channelsListBox, [
                    0, self.channelsListBox.size() - 1
                ][id == Action.ACTION_NEXT_ITEM])
Пример #40
0
    def render(self):
        for setting in self.settingsMap.values():
            log.debug("Rendering %s" % safe_str(setting.key))
            setting.render()

        self.renderStreaming()

        import default

        about = (
            "[B]%s[/B]\n\n%s\n\n%s\n\n%s\n\n\n\nMythBox would not be possible without the\nfollowing opensource software and services"
            % (default.__scriptname__, default.__author__, default.__url__, self.platform.addonVersion())
        )
        opensource = """
        [B]Software[/B]
        
        BiDict
        BeautifulSoup
        Decorator
        Eclipse
        ElementTree
        FeedParser
        GNU/Linux
        HTMLTestRunner
        IMDBPy
        Mockito
        MythTV
        MySQL-Connector-Python
        ODict
        PyDev for Eclipse
        Python
        Python-Twitter 
        SimpleJSON
        TheMovieDb Python API
        TVDB Python API
        TVRage Python API
        Twisted
        XBMC
        
        [B]Services[/B]
        
        Google Image Search
        Google Code Project Hosting
        Internet Movie Database
        The Movie Database
        TVDB
        TVRage
        Twitter
        """
        self.setWindowProperty("AboutText", about)
        self.setWindowProperty("OpensourceText", opensource)
        self.setWindowProperty(
            "ReadmeText",
            "%s\n%s"
            % (
                open(os.path.join(self.platform.getScriptDir(), "README"), "r").read(),
                open(os.path.join(self.platform.getScriptDir(), "FAQ"), "r").read(),
            ),
        )
Пример #41
0
 def watchSelectedChannel(self):
     if not self.conn().protocol.supportsStreaming(self.platform):
         xbmcgui.Dialog().ok(self.translator.get(m.ERROR), 
             'Watching Live TV is currently not supported', 
             'with your configuration of MythTV %s and' % self.conn().protocol.mythVersion(), 
             'XBMC %s. Should be working in XBMC 11.0+' % self.platform.xbmcVersion())
         return
     
     self.lastSelected = self.channelsListBox.getSelectedPosition()
     channel = self.listItem2Channel(self.channelsListBox.getSelectedItem())
     brain = self.conn().protocol.getLiveTvBrain(self.settings, self.translator)
     
     try:
         brain.watchLiveTV(channel)
     except Exception, e:
         log.error(safe_str(e))
         xbmcgui.Dialog().ok(self.translator.get(m.ERROR), '', safe_str(e))
Пример #42
0
 def save(self, program, show):
     '''Save tvrage.api.Show to memory/disk cache'''
     f = open(os.path.join(self.cacheDir, safe_str(program.title().replace('/','_'))), 'wb')
     try:
         self.memcache[program.title()] = show
         pickle.dump(show, f)
     finally:
         f.close()
Пример #43
0
 def searchBySubtitle(self, program, show):
     subtitle = program.subtitle()
     if subtitle is None or len(subtitle) == 0:
         return None, None
     
     for sn in xrange(1, show.seasons+1):
         try:
             season = show.season(sn)
             for en, episode in season.items():
                 if episode.title and episode.title.lower() == subtitle.lower():
                     return str(sn), str(episode.number)
         except KeyError:
             # For cases where an entire season is missing, keep going...
             log.debug('TVRage: Season %d of %s is missing' % (sn, safe_str(program.title())))
 
     log.debug('TVRage: No episode of %s found matching subtitle %s' % (safe_str(program.title()), safe_str(subtitle)))        
     return None, None
Пример #44
0
 def renderThumbnail(self):
     thumbFile = self.mythThumbnailCache.get(self.program)
     self.setWindowProperty('thumbnailShadow', 'mb-DialogBack.png')
     if thumbFile:
         self.setWindowProperty('thumbnail', thumbFile)
     else:
         self.setWindowProperty('thumbnail', 'mythbox-logo.png')
         log.error('Recording thumbnail preview image not found: %s' % safe_str(self.program.title()))
Пример #45
0
 def watchSelectedChannel(self):
     if not self.conn().protocol.supportsStreaming(self.platform):
         xbmcgui.Dialog().ok(self.translator.get(m.ERROR), 
             'Watching Live TV is currently not supported', 
             'with your configuration of MythTV %s and' % self.conn().protocol.mythVersion(), 
             'XBMC %s. Should be working in XBMC 11.0+' % self.platform.xbmcVersion())
         return
     
     self.lastSelected = self.channelsListBox.getSelectedPosition()
     channel = self.listItem2Channel(self.channelsListBox.getSelectedItem())
     brain = self.conn().protocol.getLiveTvBrain(self.settings, self.translator)
     
     try:
         brain.watchLiveTV(channel)
     except Exception, e:
         log.error(safe_str(e))
         xbmcgui.Dialog().ok(self.translator.get(m.ERROR), '', safe_str(e))
Пример #46
0
    def getSeasonAndEpisode(self, program):
        # TODO: try some other method if search by original air date comes up blank
        if program.isMovie(): 
            return None, None

        try:
            show = self.tvdb[program.title()]
            originalAirDate = program.originalAirDate()
            episodes = show.airedOn(originalAirDate)
            episode = episodes.pop()
            return episode['seasonnumber'], episode['episodenumber']
        except (tvdb_api.tvdb_episodenotfound, tvdb_api.tvdb_shownotfound):
            log.debug('TVDB: Show not found - %r' % safe_str(program.title()))
            return None, None
        except (tvdb_api.tvdb_error):
            log.exception(safe_str(program.title()))
            return None, None
Пример #47
0
 def _saveLastPositionAsBookmark(self):
     lastPos = self.player.tracker.getLastPosition()
     log.debug('Setting bookmark on %s to %s' %
               (safe_str(self.program.title()), formatSeconds(lastPos)))
     try:
         self.program.setBookmark(lastPos)
     except:
         log.exception('_saveLastPositionAsBookmark catchall')
Пример #48
0
 def renderThumbnail(self):
     thumbFile = self.mythThumbnailCache.get(self.program)
     self.setWindowProperty('thumbnailShadow', 'mb-DialogBack.png')
     if thumbFile:
         self.setWindowProperty('thumbnail', thumbFile)
     else:
         self.setWindowProperty('thumbnail', 'mythbox-logo.png')
         log.error('Recording thumbnail preview image not found: %s' % safe_str(self.program.title()))
Пример #49
0
 def save(self, program, show):
     '''Save tvrage.api.Show to memory/disk cache'''
     with open(
             os.path.join(self.cacheDir,
                          safe_str(program.title().replace('/', '_'))),
             'wb') as f:
         self.memcache[program.title()] = show
         pickle.dump(show, f)
Пример #50
0
 def watchLiveTV(self, channel):
     try:
         self.tuner = self._findAvailableTunerWithChannel(channel)
         livePlayer = MythLiveTvPlayer()
         livePlayer.watchChannel(self.settings, channel)
         #del livePlayer # induce GC so on* callbacks unregistered
         return self.tuner
     except ServerException, se:
         xbmcgui.Dialog().ok(self.translator.get(m.INFO), safe_str(se))
Пример #51
0
 def playRecording(self, commSkipper):
     """
     Plays the given program. Blocks until playback is stopped or until the 
     end of the recording is reached
     """
     mlog.debug('> playRecording %s' % safe_str(self.program.title()))
     assert not self.isPlaying(), 'Player is already playing a video'
     self.commSkipper = commSkipper
     self.play(self.buildPlaybackUrl(), self.buildPlayList())
     mlog.debug('< playRecording')
Пример #52
0
 def workerBee(self):
     while not self.closed and not xbmc.abortRequested:
         try:
             if not self.bannerQueue.empty():
                 log.debug('Banner queue size: %d' % self.bannerQueue.qsize())
             program = self.bannerQueue.get(block=True, timeout=1)
             bannerPath = self.fanArt.pickBanner(program)
             log.debug('workerBee resolved %s to %s' % (safe_str(program.title()), bannerPath))
         except Queue.Empty:
             pass
Пример #53
0
 def playRecording(self, commSkipper):
     """
     Plays the given program. Blocks until playback is stopped or until the 
     end of the recording is reached
     """
     mlog.debug('> playRecording %s' % safe_str(self.program.title()))
     assert not self.isPlaying(), 'Player is already playing a video'
     self.commSkipper = commSkipper
     self.play(self.buildPlaybackUrl(), self.buildPlayList())
     mlog.debug('< playRecording')
Пример #54
0
    def getSeasonAndEpisode(self, program):
        # TODO: try some other method if search by original air date comes up blank
        if program.isMovie():
            return None, None

        t = self.transform(program.title())

        try:
            show = self.tvdb[t]
            originalAirDate = program.originalAirDate()
            episodes = show.airedOn(originalAirDate)
            episode = episodes.pop()
            return episode['seasonnumber'], episode['episodenumber']
        except (tvdb_api.tvdb_episodenotfound, tvdb_api.tvdb_shownotfound):
            log.debug('TVDB: Show not found - %s' % safe_str(t))
            return None, None
        except (tvdb_api.tvdb_error):
            log.exception(safe_str(t))
            return None, None
Пример #55
0
 def workerBee(self):
     while not self.closed and not xbmc.abortRequested:
         try:
             if not self.bannerQueue.empty():
                 log.debug('Banner queue size: %d' % self.bannerQueue.qsize())
             program = self.bannerQueue.get(block=True, timeout=1)
             bannerPath = self.fanArt.pickBanner(program)
             log.debug('workerBee resolved %s to %s' % (safe_str(program.title()), bannerPath))
         except Queue.Empty:
             pass
Пример #56
0
    def render(self):
        for setting in self.settingsMap.values():
            log.debug('Rendering %s' % safe_str(setting.key))
            setting.render()

        self.renderStreaming()

        import default
        about = "[B]%s[/B]\n\n%s\n\n%s\n\n%s\n\n\n\nMythBox would not be possible without the\nfollowing opensource software and services" % (
            default.__scriptname__, default.__author__, default.__url__,
            self.platform.addonVersion())
        opensource = """
        [B]Software[/B]
        
        BiDict
        BeautifulSoup
        Decorator
        Eclipse
        ElementTree
        FeedParser
        GNU/Linux
        HTMLTestRunner
        IMDBPy
        Mockito
        MythTV
        MySQL-Connector-Python
        ODict
        PyDev for Eclipse
        Python
        Python-Twitter 
        SimpleJSON
        TheMovieDb Python API
        TVDB Python API
        TVRage Python API
        Twisted
        XBMC
        
        [B]Services[/B]
        
        Google Image Search
        Google Code Project Hosting
        Internet Movie Database
        The Movie Database
        TVDB
        TVRage
        Twitter
        """
        self.setWindowProperty('AboutText', about)
        self.setWindowProperty('OpensourceText', opensource)
        self.setWindowProperty(
            'ReadmeText', '%s\n%s' %
            (open(os.path.join(self.platform.getScriptDir(), 'README.md'),
                  'r').read(),
             open(os.path.join(self.platform.getScriptDir(), 'FAQ'),
                  'r').read()))
Пример #57
0
    def getPosters(self, program):
        posters = []
        try:
            url_values = urllib.urlencode(
                {
                    'v': '1.0',
                    'safe': 'moderate',
                    'rsz': '4',
                    'imgsz': 'medium',
                    'key': self.API_KEY,
                    'q': program.title()
                },
                doseq=True)
            searchUrl = 'http://ajax.googleapis.com/ajax/services/search/images?' + url_values
            req = urllib2.Request(
                searchUrl,
                headers={'Referer': 'http://mythbox.googlecode.com'})
            resp = urllib2.urlopen(req)
            s = resp.readlines()
            obj = json.loads(s[0])

            #if log.isEnabledFor('debug'):
            #    log.debug(json.dumps(obj, sort_keys=True, indent=4))
            #    log.debug('url = %s' % searchUrl)
            #    for result in obj['responseData']['results']:
            #        log.debug(result['unescapedUrl'])

            posters = [
                result['unescapedUrl']
                for result in obj['responseData']['results']
                if float(result['height']) / float(result['width']) > 1.0
            ]
            if len(posters) == 0:
                log.debug(
                    'GOOGLE: No images meet aspect ratio constaints for %s' %
                    safe_str(program.title()))
                posters.append(
                    obj['responseData']['results'][0]['unescapedUrl'])

        except Exception, e:
            log.exception('GOOGLE: Fanart search:  %s %s' %
                          (safe_str(program.title()), safe_str(e)))