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
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'')
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()
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)))
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
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'')
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))
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))))
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
def createEpisodeKey(self, methodName, program): return '-'.join( str(k) for k in [ methodName, safe_str(program.title()), safe_str(program.subtitle()), program.originalAirDate() ])
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
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)))
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 ----')
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))))
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
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)))
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)))
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()
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))))
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'')
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')
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()
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')
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])
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
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())
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)
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
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)))
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')
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')
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])
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(), ), )
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))
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()
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
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()))
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
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')
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)
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))
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')
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
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
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()))
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)))