def massEdit(self, toEdit=None): t = PageTemplate(file="manage_massEdit.tmpl") t.submenu = ManageMenu if not toEdit: redirect("/manage") showIDs = toEdit.split("|") showList = [] for curID in showIDs: curID = int(curID) showObj = helpers.findCertainShow(sickbeard.showList, curID) if showObj: showList.append(showObj) season_folders_all_same = True last_season_folders = None paused_all_same = True last_paused = None quality_all_same = True last_quality = None root_dir_list = [] for curShow in showList: cur_root_dir = ek.ek(os.path.dirname, curShow._location) if cur_root_dir not in root_dir_list: root_dir_list.append(cur_root_dir) # if we know they're not all the same then no point even bothering if paused_all_same: # if we had a value already and this value is different then they're not all the same if last_paused not in (curShow.paused, None): paused_all_same = False else: last_paused = curShow.paused if season_folders_all_same: if last_season_folders not in (None, curShow.seasonfolders): season_folders_all_same = False else: last_season_folders = curShow.seasonfolders if quality_all_same: if last_quality not in (None, curShow.quality): quality_all_same = False else: last_quality = curShow.quality t.showList = toEdit t.paused_value = last_paused if paused_all_same else None t.season_folders_value = last_season_folders if season_folders_all_same else None t.quality_value = last_quality if quality_all_same else None t.root_dir_list = root_dir_list return _munge(t)
def existingShows(self): """ Prints out the page to add existing shows from a root dir """ t = PageTemplate(file="home_addExistingShow.tmpl") t.submenu = HomeMenu() return _munge(t)
def index(self): t = PageTemplate(file="manage_manageSearches.tmpl") #t.backlogPI = sickbeard.backlogSearchScheduler.action.getProgressIndicator() t.backlogPaused = sickbeard.searchQueueScheduler.action.is_backlog_paused() #@UndefinedVariable t.backlogRunning = sickbeard.searchQueueScheduler.action.is_backlog_in_progress() #@UndefinedVariable t.searchStatus = sickbeard.currentSearchScheduler.action.amActive #@UndefinedVariable t.submenu = ManageMenu return _munge(t)
def restart(self, pid=None): if str(pid) != str(sickbeard.PID): redirect("/home") t = PageTemplate(file="restart.tmpl") t.submenu = HomeMenu() # do a soft restart threading.Timer(2, sickbeard.invoke_restart, [False]).start() return _munge(t)
def viewlog(self, minLevel=logger.MESSAGE, maxLines=500): t = PageTemplate(file="viewlogs.tmpl") t.submenu = ErrorLogsMenu minLevel = int(minLevel) data = [] if os.path.isfile(logger.sb_log_instance.log_file): f = ek.ek(open, logger.sb_log_instance.log_file) data = f.readlines() f.close() regex = "^(\w{3})\-(\d\d)\s*(\d\d)\:(\d\d):(\d\d)\s*([A-Z]+)\s*(.+?)\s*\:\:\s*(.*)$" finalData = [] numLines = 0 lastLine = False numToShow = min(maxLines, len(data)) for x in reversed(data): x = x.decode('utf-8') match = re.match(regex, x) if match: level = match.group(6) if level not in logger.reverseNames: lastLine = False continue if logger.reverseNames[level] >= minLevel: lastLine = True finalData.append(x) else: lastLine = False continue elif lastLine: finalData.append("AA"+x) numLines += 1 if numLines >= numToShow: break result = "".join(finalData) t.logLines = result t.minLevel = minLevel return _munge(t)
def episodeStatuses(self, whichStatus=None): if whichStatus: whichStatus = int(whichStatus) status_list = [whichStatus] if status_list[0] == SNATCHED: status_list = Quality.SNATCHED + Quality.SNATCHED_PROPER else: status_list = [] t = PageTemplate(file="manage_episodeStatuses.tmpl") t.submenu = ManageMenu t.whichStatus = whichStatus # if we have no status then this is as far as we need to go if not status_list: return _munge(t) myDB = db.DBConnection() status_results = myDB.select("SELECT show_name, tv_shows.tvdb_id as tvdb_id FROM tv_episodes, tv_shows WHERE tv_episodes.status IN ("+','.join(['?']*len(status_list))+") AND season != 0 AND tv_episodes.showid = tv_shows.tvdb_id ORDER BY show_name", status_list) ep_counts = {} show_names = {} sorted_show_ids = [] for cur_status_result in status_results: cur_tvdb_id = int(cur_status_result["tvdb_id"]) if cur_tvdb_id not in ep_counts: ep_counts[cur_tvdb_id] = 1 else: ep_counts[cur_tvdb_id] += 1 show_names[cur_tvdb_id] = cur_status_result["show_name"] if cur_tvdb_id not in sorted_show_ids: sorted_show_ids.append(cur_tvdb_id) t.show_names = show_names t.ep_counts = ep_counts t.sorted_show_ids = sorted_show_ids return _munge(t)
def update(self, pid=None): if str(pid) != str(sickbeard.PID): redirect("/home") updated = sickbeard.versionCheckScheduler.action.update() #@UndefinedVariable if updated: # do a hard restart threading.Timer(2, sickbeard.invoke_restart, [False]).start() t = PageTemplate(file="restart_bare.tmpl") return _munge(t) else: return _genericMessage("Update Failed","Update wasn't successful, not restarting. Check your log for more information.")
def index(self): myDB = db.DBConnection() # sqlResults = myDB.select("SELECT h.*, show_name, name FROM history h, tv_shows s, tv_episodes e WHERE h.showid=s.tvdb_id AND h.showid=e.showid AND h.season=e.season AND h.episode=e.episode ORDER BY date DESC LIMIT "+str(numPerPage*(p-1))+", "+str(numPerPage)) sqlResults = myDB.select("SELECT h.*, show_name FROM history h, tv_shows s WHERE h.showid=s.tvdb_id ORDER BY date DESC") t = PageTemplate(file="history.tmpl") t.historyResults = sqlResults t.submenu = [ { 'title': 'Clear History', 'path': 'history/clearHistory' }, { 'title': 'Trim History', 'path': 'history/trimHistory' }, ] return _munge(t)
def newShow(self, show_to_add=None, other_shows=None): """ Display the new show page which collects a tvdb id, folder, and extra options and posts them to addNewShow """ t = PageTemplate(file="home_newShow.tmpl") t.submenu = HomeMenu() show_dir, tvdb_id, show_name = self.split_extra_show(show_to_add) if tvdb_id and show_name: use_provided_info = True else: use_provided_info = False # tell the template whether we're giving it show name & TVDB ID t.use_provided_info = use_provided_info # use the given show_dir for the tvdb search if available if not show_dir: t.default_show_name = '' elif not show_name: t.default_show_name = ek.ek(os.path.basename, ek.ek(os.path.normpath, show_dir)).replace('.',' ') else: t.default_show_name = show_name # carry a list of other dirs if given if not other_shows: other_shows = [] elif type(other_shows) != list: other_shows = [other_shows] if use_provided_info: t.provided_tvdb_id = tvdb_id t.provided_tvdb_name = show_name t.provided_show_dir = show_dir t.other_shows = other_shows return _munge(t)
def backlogOverview(self): t = PageTemplate(file="manage_backlogOverview.tmpl") t.submenu = ManageMenu myDB = db.DBConnection() showCounts = {} showCats = {} showSQLResults = {} for curShow in sickbeard.showList: epCounts = {} epCats = {} epCounts[Overview.SKIPPED] = 0 epCounts[Overview.WANTED] = 0 epCounts[Overview.QUAL] = 0 epCounts[Overview.GOOD] = 0 epCounts[Overview.UNAIRED] = 0 sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE showid = ? ORDER BY season*1000+episode DESC", [curShow.tvdbid]) for curResult in sqlResults: curEpCat = curShow.getOverview(int(curResult["status"])) epCats[str(curResult["season"])+"x"+str(curResult["episode"])] = curEpCat epCounts[curEpCat] += 1 showCounts[curShow.tvdbid] = epCounts showCats[curShow.tvdbid] = epCats showSQLResults[curShow.tvdbid] = sqlResults t.showCounts = showCounts t.showCats = showCats t.showSQLResults = showSQLResults return _munge(t)
def index(self): t = PageTemplate(file="manage.tmpl") t.submenu = ManageMenu return _munge(t)
def index(self): t = PageTemplate(file="config.tmpl") t.submenu = ConfigMenu return _munge(t)
def index(self): t = PageTemplate(file="home_addShows.tmpl") t.submenu = HomeMenu() return _munge(t)
def editShow(self, show=None, location=None, anyQualities=[], bestQualities=[], seasonfolders=None, paused=None, directCall=False, air_by_date=None, tvdbLang=None): if show == None: errString = "Invalid show ID: "+str(show) if directCall: return [errString] else: return _genericMessage("Error", errString) showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show)) if showObj == None: errString = "Unable to find the specified show: "+str(show) if directCall: return [errString] else: return _genericMessage("Error", errString) if not location and not anyQualities and not bestQualities and not seasonfolders: t = PageTemplate(file="editShow.tmpl") t.submenu = HomeMenu() with showObj.lock: t.show = showObj return _munge(t) if seasonfolders == "on": seasonfolders = 1 else: seasonfolders = 0 if paused == "on": paused = 1 else: paused = 0 if air_by_date == "on": air_by_date = 1 else: air_by_date = 0 if tvdbLang and tvdbLang in tvdb_api.Tvdb().config['valid_languages']: tvdb_lang = tvdbLang else: tvdb_lang = showObj.lang # if we changed the language then kick off an update if tvdb_lang == showObj.lang: do_update = False else: do_update = True if type(anyQualities) != list: anyQualities = [anyQualities] if type(bestQualities) != list: bestQualities = [bestQualities] errors = [] with showObj.lock: newQuality = Quality.combineQualities(map(int, anyQualities), map(int, bestQualities)) showObj.quality = newQuality if bool(showObj.seasonfolders) != bool(seasonfolders): showObj.seasonfolders = seasonfolders try: sickbeard.showQueueScheduler.action.refreshShow(showObj) #@UndefinedVariable except exceptions.CantRefreshException, e: errors.append("Unable to refresh this show: "+ex(e)) showObj.paused = paused showObj.air_by_date = air_by_date showObj.lang = tvdb_lang # if we change location clear the db of episodes, change it, write to db, and rescan if os.path.normpath(showObj._location) != os.path.normpath(location): logger.log(os.path.normpath(showObj._location)+" != "+os.path.normpath(location)) if not ek.ek(os.path.isdir, location): errors.append("New location <tt>%s</tt> does not exist" % location) # don't bother if we're going to update anyway elif not do_update: # change it try: showObj.location = location try: sickbeard.showQueueScheduler.action.refreshShow(showObj) #@UndefinedVariable except exceptions.CantRefreshException, e: errors.append("Unable to refresh this show:"+ex(e)) # grab updated info from TVDB #showObj.loadEpisodesFromTVDB() # rescan the episodes in the new folder except exceptions.NoNFOException: errors.append("The folder at <tt>%s</tt> doesn't contain a tvshow.nfo - copy your files to that folder before you change the directory in Sick Beard." % location) # save it to the DB showObj.saveToDB()
def displayShow(self, show=None): if show == None: return _genericMessage("Error", "Invalid show ID") else: showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show)) if showObj == None: return _genericMessage("Error", "Unable to find the specified show.") myDB = db.DBConnection() seasonResults = myDB.select( "SELECT DISTINCT season FROM tv_episodes WHERE showid = ? ORDER BY season desc", [showObj.tvdbid] ) sqlResults = myDB.select( "SELECT * FROM tv_episodes WHERE showid = ? ORDER BY season*1000+episode DESC", [showObj.tvdbid] ) t = PageTemplate(file="displayShow.tmpl") t.submenu = [ { 'title': 'Edit', 'path': 'home/editShow?show=%d'%showObj.tvdbid } ] try: t.showLoc = (showObj.location, True) except sickbeard.exceptions.ShowDirNotFoundException: t.showLoc = (showObj._location, False) show_message = '' if sickbeard.showQueueScheduler.action.isBeingAdded(showObj): #@UndefinedVariable show_message = 'This show is in the process of being downloaded from theTVDB.com - the info below is incomplete.' elif sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): #@UndefinedVariable show_message = 'The information below is in the process of being updated.' elif sickbeard.showQueueScheduler.action.isBeingRefreshed(showObj): #@UndefinedVariable show_message = 'The episodes below are currently being refreshed from disk' elif sickbeard.showQueueScheduler.action.isInRefreshQueue(showObj): #@UndefinedVariable show_message = 'This show is queued to be refreshed.' elif sickbeard.showQueueScheduler.action.isInUpdateQueue(showObj): #@UndefinedVariable show_message = 'This show is queued and awaiting an update.' if not sickbeard.showQueueScheduler.action.isBeingAdded(showObj): #@UndefinedVariable if not sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): #@UndefinedVariable t.submenu.append({ 'title': 'Delete', 'path': 'home/deleteShow?show=%d'%showObj.tvdbid, 'confirm': True }) t.submenu.append({ 'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d'%showObj.tvdbid }) t.submenu.append({ 'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&force=1'%showObj.tvdbid }) t.submenu.append({ 'title': 'Update show in XBMC', 'path': 'home/updateXBMC?showName=%s'%urllib.quote_plus(showObj.name.encode('utf-8')), 'requires': haveXBMC }) t.submenu.append({ 'title': 'Rename Episodes', 'path': 'home/fixEpisodeNames?show=%d'%showObj.tvdbid, 'confirm': True }) t.show = showObj t.sqlResults = sqlResults t.seasonResults = seasonResults t.show_message = show_message epCounts = {} epCats = {} epCounts[Overview.SKIPPED] = 0 epCounts[Overview.WANTED] = 0 epCounts[Overview.QUAL] = 0 epCounts[Overview.GOOD] = 0 epCounts[Overview.UNAIRED] = 0 for curResult in sqlResults: curEpCat = showObj.getOverview(int(curResult["status"])) epCats[str(curResult["season"])+"x"+str(curResult["episode"])] = curEpCat epCounts[curEpCat] += 1 def titler(x): if not x: return x if x.lower().startswith('a '): x = x[2:] elif x.lower().startswith('the '): x = x[4:] return x t.sortedShowList = sorted(sickbeard.showList, lambda x, y: cmp(titler(x.name), titler(y.name))) t.epCounts = epCounts t.epCats = epCats return _munge(t)
def massAddTable(self, rootDir=None): t = PageTemplate(file="home_massAddTable.tmpl") t.submenu = HomeMenu() myDB = db.DBConnection() if not rootDir: return "No folders selected." elif type(rootDir) != list: root_dirs = [rootDir] else: root_dirs = rootDir root_dirs = [urllib.unquote_plus(x) for x in root_dirs] default_index = int(sickbeard.ROOT_DIRS.split('|')[0]) if len(root_dirs) > default_index: tmp = root_dirs[default_index] if tmp in root_dirs: root_dirs.remove(tmp) root_dirs = [tmp]+root_dirs dir_list = [] for root_dir in root_dirs: try: file_list = ek.ek(os.listdir, root_dir) except: continue for cur_file in file_list: cur_path = ek.ek(os.path.normpath, ek.ek(os.path.join, root_dir, cur_file)) if not ek.ek(os.path.isdir, cur_path): continue cur_dir = { 'dir': cur_path, 'display_dir': '<b>'+ek.ek(os.path.dirname, cur_path)+os.sep+'</b>'+ek.ek(os.path.basename, cur_path), } # see if the folder is in XBMC already dirResults = myDB.select("SELECT * FROM tv_shows WHERE location = ?", [cur_path]) if dirResults: cur_dir['added_already'] = True else: cur_dir['added_already'] = False dir_list.append(cur_dir) tvdb_id = '' show_name = '' for cur_provider in sickbeard.metadata_provider_dict.values(): (tvdb_id, show_name) = cur_provider.retrieveShowMetadata(cur_path) if tvdb_id and show_name: break cur_dir['existing_info'] = (tvdb_id, show_name) if tvdb_id and helpers.findCertainShow(sickbeard.showList, tvdb_id): cur_dir['added_already'] = True t.dirList = dir_list return _munge(t)
def index(self): t = PageTemplate(file="home_postprocess.tmpl") t.submenu = HomeMenu() return _munge(t)
def index(self): t = PageTemplate(file="errorlogs.tmpl") t.submenu = ErrorLogsMenu return _munge(t)