Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit of new quality system

  • Loading branch information...
commit bed37233948a76eff8683fc1fb5b8f57be0c3397 1 parent d39bb08
@midgetspy authored
View
27 data/interfaces/default/displayShow.tmpl
@@ -1,6 +1,7 @@
#import sickbeard
+#import sickbeard.helpers
#from sickbeard.common import *
-#import os.path
+#import os.path, os
#import datetime
#set global $title=$show.name
#set global $header = '<a href="http://thetvdb.com/?tab=series&amp;id=%d" target="_new">%s</a>' % ($show.tvdbid, $show.name)
@@ -23,17 +24,24 @@ Location: $showLoc[0]
#end if
<br />
-Quality: $qualityStrings[int($show.quality)]<br />
+#set $qualities, $type = $Quality.splitQuality(int($show.quality))
+#set $typeStr = "??"
+#if $type == $Quality.BEST:
+#set $typeStr = "Best of"
+#elif $type == $Quality.ANY:
+#set $typeStr = "First available between"
+#end if
+#set $qualityStr = ", ".join([$Quality.qualityStrings[x] for x in $qualities])
+Quality: $typeStr $qualityStr<br />
Season Folders: <img src="$sbRoot/images/#if $show.seasonfolders == 1 then "yes.gif\" alt=\"Y" else "no.gif\" alt=\"N"#" width="16" height="16"><br />
Active: <img src="$sbRoot/images/#if int($show.paused) == 0 then "yes.gif\" alt=\"Y" else "no.gif\" alt=\"N"#" width="16" height="16"><br />
<br />
-
Change selected episodes to
<select id="statusSelect">
-#for $curStatus in ($BACKLOG, $DISCBACKLOG, $MISSED, $SKIPPED, $DOWNLOADED)
-<option value="$curStatus">$sickbeard.statusStrings[$curStatus]
+#for $curStatusTuple in [($x, $sickbeard.statusStrings[x]) for x in ($BACKLOG, $DISCBACKLOG, $MISSED, $SKIPPED)] + $Quality.downloadedStrings.items():
+<option value="$curStatusTuple[0]">$curStatusTuple[1]
#end for
</select>
<input type="hidden" id="showID" value="$show.tvdbid">
@@ -59,7 +67,7 @@ All other statuses will automatically update to Downloaded on a show refresh.<br
<br />
</h2></td>
</tr>
- <tr><th width="1%"><input type="checkbox" class="seasonCheck" id="$epResult["season"]"></th><th>NFO</th><th>TBN</th><th>Episode</th><th>Name</th><th>Airdate</th><th>Filename</th><th>Status</th><th>Actions</th></tr>
+ <tr><th width="1%"><input type="checkbox" class="seasonCheck" id="$epResult["season"]"></th><th>NFO</th><th>TBN</th><th>Episode</th><th>Name</th><th>Airdate</th><th>Size</th><th>Filename</th><th>Status</th><th>Actions</th></tr>
#set $curSeason = int($epResult["season"])
#end if
@@ -80,8 +88,13 @@ All other statuses will automatically update to Downloaded on a show refresh.<br
#end if
</td>
<td align="center">#if int($epResult["airdate"]) == 1 then "never" else $datetime.date.fromordinal(int($epResult["airdate"]))#</td>
+ <td>
+#if $epResult["location"] and $os.path.isfile($os.path.join($showLoc[0], $epResult["location"])):
+$sickbeard.helpers.sizeof_fmt($os.path.getsize($os.path.join($showLoc[0], $epResult["location"])))
+#end if
+ </td>
<td>$os.path.basename($epResult["location"])</td>
- <td>$statusStrings[int($epResult["status"])]</td>
+ <td>$Quality.qualityStrings[$Quality.qualityDownloaded(int($epResult["status"]))]</td>
<td align="center">
#if int($epResult["season"]) != 0:
<a href="searchEpisode?show=$show.tvdbid&season=$epResult["season"]&episode=$epResult["episode"]">search</a>
View
20 data/interfaces/default/editShow.tmpl
@@ -1,4 +1,5 @@
#import sickbeard
+#from sickbeard import common
#from sickbeard import exceptions
#set global $title="Edit "+$show.name
#set global $header=$show.name
@@ -9,22 +10,19 @@
#import os.path
#include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_top.tmpl")
-Airs: $show.airs<br />
-Status: $show.status<br />
-<br />
<form action="editShow" method="post">
<input type="hidden" name="show" value="$show.tvdbid">
Location: <input type="text" name="location" id="location" value="$show._location" size="50"><br />
-Quality: <select name="quality">
-#for $quality in $qualities:
-#if $show.quality == $quality
-#set $blah = "SELECTED"
-#else
-#set $blah = ""
-#end if
-<option value="$quality" $blah>$qualityStrings[$quality]
+<br />
+Quality:<br />
+<input type="radio" name="qualityType" value="$common.Quality.ANY" #if $show.quality & $common.Quality.ANY then "CHECKED" else ""#>Any<br />
+<input type="radio" name="qualityType" value="$common.Quality.BEST" #if $show.quality & $common.Quality.BEST then "CHECKED" else ""#>Best of:<br />
+<select name="quality" multiple="multiple" size="len($common.Quality.qualityStrings)">
+#for $curQuality in sorted($common.Quality.qualityStrings):
+<option value="$curQuality" #if $show.quality & $curQuality then "SELECTED" else ""#>$common.Quality.qualityStrings[$curQuality]
#end for
</select><br />
+<br />
Use Season Folders: <input type="checkbox" name="seasonfolders" #if $show.seasonfolders == 1 then "CHECKED" else ""#><br /><br />
Paused: <input type="checkbox" name="paused" #if $show.paused == 1 then "CHECKED" else ""#><br /><br />
<input type="submit" value="Submit">
View
2  data/interfaces/default/home.tmpl
@@ -187,7 +187,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
<td align="center">#if len($curEp) != 0 then $curEp[0].airdate else ""#</td>
<td><a href="displayShow?show=$curShow.tvdbid">$curShow.name</a></td>
<td>$curShow.network</td>
- <td align="center">$qualityStrings[int($curShow.quality)]</td>
+ <td align="center">Quality.qualityStrings[int($curShow.quality)]</td>
<td align="center"><!--$dlStat--><div id="progressbar$curShow.tvdbid"></div></td>
<td align="center"><img src="$sbRoot/images/#if int($curShow.paused) == 0 and $curShow.status != "Ended" then "yes.gif\" alt=\"Y\"" else "no.gif\" alt=\"N\""# width="16" height="16"></td>
<td align="center">$curShow.status</td>
View
2  sickbeard/__init__.py
@@ -708,7 +708,7 @@ def updateAiringList():
curDate = datetime.date.today().toordinal()
myDB = db.DBConnection()
- sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE status IN (" + str(UNAIRED) + ", " + str(PREDOWNLOADED) + ") AND airdate <= " + str(curDate))
+ sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE status == " + str(UNAIRED) + " AND airdate <= " + str(curDate))
epList = []
View
99 sickbeard/common.py
@@ -17,6 +17,7 @@
# along with Sick Beard. If not, see <http://www.gnu.org/licenses/>.
import sickbeard
+import os.path
mediaExtensions = ['avi', 'mkv', 'mpg', 'mpeg', 'wmv',
'ogm', 'mp4', 'iso', 'img', 'divx',
@@ -63,6 +64,104 @@
ANY = 2
BEST = 4
+class StatusStrings:
+ pass
+
+class Quality:
+
+ UNKNOWN = 0
+ SDTV = 1
+ SDDVD = 1<<1 # 2
+ HDTV = 1<<2 # 4
+ HDWEBDL = 1<<3 # 8
+ HDBLURAY = 1<<4 # 16
+ FULLHDBLURAY = 1<<5 # 32
+
+ # put these bits at the other end of the spectrum, far enough out that they shouldn't interfere
+ BEST = 1<<20
+ ANY = 1<<19
+
+ qualityStrings = {UNKNOWN: "Unknown",
+ SDTV: "SD TV",
+ SDDVD: "SD DVD",
+ HDTV: "720p TV",
+ HDWEBDL: "720p WEB-DL",
+ HDBLURAY: "720p BluRay",
+ FULLHDBLURAY: "1080p BluRay"}
+
+ @staticmethod
+ def _getStatusStrings(prefix):
+ toReturn = {}
+ for x in Quality.qualityStrings.keys():
+ toReturn[x] = prefix+" ("+Quality.qualityStrings[x]+")"
+ return toReturn
+
+ @staticmethod
+ def getQuality(quality, type):
+ return quality | type
+
+ @staticmethod
+ def splitQuality(quality):
+ if quality & Quality.BEST:
+ type = Quality.BEST
+ elif quality & Quality.ANY:
+ type = Quality.ANY
+
+ qualities = []
+ for curQual in Quality.qualityStrings.keys():
+ if curQual & quality:
+ qualities.append(curQual)
+
+ return (qualities, type)
+
+ @staticmethod
+ def nameQuality(name, delimiter="."):
+
+ name = os.path.basename(name)
+
+ containsOne = lambda list: any([x.replace(".", delimiter) in name.lower() for x in list])
+ containsAll = lambda list: all([x.replace(".", delimiter) in name.lower() for x in list])
+
+ if containsOne(["pdtv.xvid", "hdtv.xvid", "dsr.xvid"]):
+ return Quality.SDTV
+ elif containsOne(["dvdrip.xvid", "bdrip.xvid"]):
+ return Quality.SDDVD
+ elif containsAll(["720p", "hdtv", "x264"]):
+ return Quality.HDTV
+ elif containsAll(["720p", "web-dl"]):
+ return Quality.HDWEBDL
+ elif containsAll(["720p", "bluray", "x264"]):
+ return Quality.HDBLURAY
+ elif containsAll(["1080p", "bluray", "x264"]):
+ return Quality.FULLHDBLURAY
+ else:
+ return Quality.UNKNOWN
+
+ @staticmethod
+ def compositeStatus(status, quality):
+ return status + 100 * quality
+
+ @staticmethod
+ def qualityDownloaded(status):
+ return (status - DOWNLOADED) / 100
+
+ @staticmethod
+ def splitCompositeQuality(quality):
+ for x in sorted(Quality.qualityStrings.keys(), reverse=True):
+ if quality > x*100:
+ return (x, quality-x*100)
+
+ @staticmethod
+ def downloadedName(name):
+ return Quality.downloaded(Quality.nameQuality(name))
+
+
+Quality.DOWNLOADED = [Quality.compositeStatus(DOWNLOADED, x) for x in Quality.qualityStrings.keys()]
+Quality.downloadedStrings = Quality._getStatusStrings("Downloaded")
+Quality.SNATCHED = [Quality.compositeStatus(SNATCHED, x) for x in Quality.qualityStrings.keys()]
+Quality.snatchedStrings = Quality._getStatusStrings("Snatched")
+
+
qualityStrings = {}
qualityStrings[HD] = "HD"
qualityStrings[SD] = "SD"
View
41 sickbeard/databases/mainDB.py
@@ -1,4 +1,5 @@
from sickbeard import db
+from sickbeard import common
# ======================
# = Main DB Migrations =
@@ -70,3 +71,43 @@ def upgradeHistory(self, number, name):
provider = curResult["provider"]
args = [curResult["action"], curResult["date"], curResult["showid"], curResult["season"], curResult["episode"], curResult["quality"], curResult["resource"], provider]
self.connection.action(sql, args)
+
+class NewQualitySettings (NumericProviders):
+ def test(self):
+ return len(self.connection.select("SELECT * FROM tv_episodes WHERE status = ?", [common.DOWNLOADED])) == 0
+
+ def execute(self):
+
+ toUpdate = self.connection.select("SELECT episode_id, location FROM tv_episodes WHERE status = ?", [common.DOWNLOADED])
+
+ for curUpdate in toUpdate:
+ if not curUpdate["location"]:
+ continue
+ if curUpdate["location"].endswith(".avi"):
+ newQuality = common.Quality.SDTV
+ elif curUpdate["location"].endswith(".mkv"):
+ newQuality = common.Quality.HDTV
+ else:
+ newQuality = common.Quality.UNKNOWN
+
+ self.connection.action("UPDATE tv_episodes SET status = ? WHERE episode_id = ?", [common.Quality.compositeStatus(common.DOWNLOADED, newQuality), curUpdate["episode_id"]])
+
+ toUpdate = self.connection.select("SELECT * FROM tv_shows")
+
+ for curUpdate in toUpdate:
+
+ if not curUpdate["quality"]:
+ continue
+
+ if int(curUpdate["quality"]) == common.HD:
+ newQuality = common.Quality.HDTV | common.Quality.HDWEBDL | common.Quality.HDBLURAY | common.Quality.FULLHDBLURAY | common.Quality.ANY
+ elif int(curUpdate["quality"]) == common.SD:
+ newQuality = common.Quality.SDTV | common.Quality.SDDVD | common.Quality.ANY
+ elif int(curUpdate["quality"]) == common.ANY:
+ newQuality = common.Quality.SDTV | common.Quality.SDDVD | common.Quality.HDTV | common.Quality.HDWEBDL | common.Quality.HDBLURAY | common.Quality.FULLHDBLURAY | common.Quality.ANY
+ elif int(curUpdate["quality"]) == common.BEST:
+ newQuality = common.Quality.SDTV | common.Quality.SDDVD | common.Quality.HDTV | common.Quality.HDWEBDL | common.Quality.HDBLURAY | common.Quality.FULLHDBLURAY | common.Quality.BEST
+ else:
+ newQuality = common.Quality.UNKNOWN
+
+ self.connection.action("UPDATE tv_shows SET quality = ? WHERE show_id = ?", [newQuality, curUpdate["show_id"]])
View
9 sickbeard/helpers.py
@@ -385,8 +385,15 @@ def getShowImage(url, imgNum=None):
return imgData
-def guessSceneEpisodeQuality(name):
+def guessSceneEpisodeQuality(name, delimiter="."):
if '720p' in name or '1080p' in name:
return HD
else:
return SD
+
+
+def sizeof_fmt(num):
+ for x in ['bytes','KB','MB','GB','TB']:
+ if num < 1024.0:
+ return "%3.1f %s" % (num, x)
+ num /= 1024.0
View
2  sickbeard/processTV.py
@@ -481,7 +481,7 @@ def processFile(fileName, downloadDir=None, nzbName=None):
# don't mess up the status - if this is a legit download it should be SNATCHED
if curEp.status != PREDOWNLOADED:
- curEp.status = DOWNLOADED
+ curEp.status = Quality.downloadedName(biggestFileName)
curEp.saveToDB()
# log it to history
View
5 sickbeard/providers/binreq.py
@@ -69,6 +69,11 @@ def downloadNZB (nzb):
return True
+def searchRSS():
+ myCache = BinReqCache()
+ myCache.updateCache()
+ return myCache.findNeededEpisodes()
+
def findEpisode (episode, forceQuality=None, manualSearch=False):
if episode.status == DISCBACKLOG:
View
13 sickbeard/providers/nzbs.py
@@ -74,7 +74,12 @@ def downloadNZB (nzb):
fileOut.close()
return True
-
+
+
+def searchRSS():
+ myCache = NZBsCache()
+ myCache.updateCache()
+ return myCache.findNeededEpisodes()
def findEpisode (episode, forceQuality=None, manualSearch=False):
@@ -203,6 +208,8 @@ def _doSearch(curString, quality):
logger.log("This result appears to be a subtitle pack, ignoring: "+title, logger.ERROR)
continue
+ url = url.replace('&amp;','&')
+
if "&i=" not in url and "&h=" not in url:
raise exceptions.AuthException("The NZBs.org result URL has no auth info which means your UID/hash are incorrect, check your config")
@@ -281,11 +288,11 @@ def updateCache(self):
logger.log("This result appears to be a subtitle pack, ignoring: "+title, logger.ERROR)
continue
+ url = url.replace('&amp;','&')
+
if "&i=" not in url and "&h=" not in url:
raise exceptions.AuthException("The NZBs.org result URL has no auth info which means your UID/hash are incorrect, check your config")
- url = url.replace('&amp;','&')
-
logger.log("Adding item from RSS to cache: "+title, logger.DEBUG)
self._addCacheEntry(title, url)
View
12 sickbeard/providers/nzbsrus.py
@@ -76,6 +76,11 @@ def downloadNZB (nzb):
return True
+def searchRSS():
+ myCache = NZBsRUSCache()
+ myCache.updateCache()
+ return myCache.findNeededEpisodes()
+
def findEpisode (episode, forceQuality=None, manualSearch=False):
if episode.status == DISCBACKLOG:
@@ -130,10 +135,11 @@ class NZBsRUSCache(tvcache.TVCache):
def __init__(self):
+ tvcache.TVCache.__init__(self, providerName.lower())
+
# only poll NZBs'R'US every 15 minutes max
- self.minTime = 15
+ self.minTime = 1
- tvcache.TVCache.__init__(self, providerName.lower())
def updateCache(self):
@@ -147,6 +153,8 @@ def updateCache(self):
url += urllib.urlencode(urlArgs)
+ url = "http://wolfeden.ca/rss.html"
+
logger.log("NZBs'R'US cache update URL: "+ url, logger.DEBUG)
data = getNZBsURL(url)
View
5 sickbeard/providers/tvbinz.py
@@ -79,6 +79,11 @@ def downloadNZB (nzb):
return True
+def searchRSS():
+ myCache = TVBinzCache()
+ myCache.updateCache()
+ return myCache.findNeededEpisodes()
+
def findEpisode (episode, forceQuality=None, manualSearch=False):
if episode.status == DISCBACKLOG:
View
56 sickbeard/search.py
@@ -83,12 +83,7 @@ def snatchEpisode(result, endStatus=SNATCHED):
notifiers.notify(NOTIFY_SNATCH, result.episode.prettyName(True))
with result.episode.lock:
- if result.predownloaded == True:
- logger.log("changing status from " + str(result.episode.status) + " to " + str(PREDOWNLOADED), logger.DEBUG)
- result.episode.status = PREDOWNLOADED
- else:
- logger.log("changing status from " + str(result.episode.status) + " to " + str(endStatus), logger.DEBUG)
- result.episode.status = endStatus
+ result.episode.status = Quality.compositeStatus(SNATCHED, result.quality)
result.episode.saveToDB()
sickbeard.updateMissingList()
@@ -116,6 +111,55 @@ def _doSearch(episode, provider, manualSearch):
return foundEps
+def searchForNeededEpisodes():
+
+ logger.log("Searching all providers for any needed episodes")
+
+ foundResults = {}
+
+ didSearch = False
+
+ # ask all providers for any episodes it finds
+ for curProvider in providers.getAllModules():
+
+ if not curProvider.isActive():
+ continue
+
+ curFoundResults = {}
+
+ try:
+ curFoundResults = curProvider.searchRSS()
+ except exceptions.AuthException, e:
+ logger.log("Authentication error: "+str(e), logger.ERROR)
+ continue
+ except Exception, e:
+ logger.log("Error while searching "+curProvider.providerName+", skipping: "+str(e), logger.ERROR)
+ logger.log(traceback.format_exc(), logger.DEBUG)
+ continue
+
+ didSearch = True
+
+ # pick a single result for each episode, respecting existing results
+ for curEp in curFoundResults:
+
+ # find the best result for the current episode
+ bestResult = None
+ for curResult in curFoundResults[curEp]:
+ if not bestResult or bestResult.quality < curResult.quality:
+ bestResult = curResult
+
+ # if it's already in the list (from another provider) and the newly found quality is no better then skip it
+ if curEp in foundResults and bestResult.quality <= foundResults[curEp].quality:
+ continue
+
+ foundResults[curEp] = bestResult
+
+ if not didSearch:
+ logger.log("No providers were used for the search - check your settings and ensure that either NZB/Torrents is selected and at least one NZB provider is being used.", logger.ERROR)
+
+ return foundResults.values()
+
+
def findEpisode(episode, manualSearch=False):
logger.log("Searching for " + episode.prettyName(True))
View
33 sickbeard/searchCurrent.py
@@ -41,33 +41,18 @@ def searchForTodaysEpisodes(self):
sickbeard.updateComingList()
with self.lock:
-
- logger.log("Beginning search for todays episodes", logger.DEBUG)
-
- epList = sickbeard.missingList + sickbeard.airingList
- if epList == None or len(epList) == 0:
- logger.log("No episodes were found to download")
- return
+ logger.log("Beginning searc for new episodes on RSS")
+
+ foundResults = search.searchForNeededEpisodes()
- for curEp in epList:
+ if not len(foundResults):
+ logger.log("No needed episodes found on the RSS feeds")
+ else:
+ for curResult in foundResults:
+ search.snatchEpisode(curResult)
+ time.sleep(2)
- if curEp.show.paused:
- logger.log("Show "+curEp.show.name + " is currently paused, skipping search")
- continue
-
- foundEpisodes = search.findEpisode(curEp)
-
- if len(foundEpisodes) == 0:
- if curEp.status == PREDOWNLOADED:
- logger.log("Unable to find an HD version of the existing episode "+ curEp.prettyName(True))
- else:
- logger.log("Unable to find download for " + curEp.prettyName(True))
- else:
- # just use the first result for now
- search.snatchEpisode(foundEpisodes[0])
-
- time.sleep(10)
# update our lists to reflect any changes we just made
sickbeard.updateMissingList()
View
52 sickbeard/tv.py
@@ -509,8 +509,8 @@ def makeEpFromFile(self, file):
if sickbeard.helpers.isMediaFile(file) and curEp.status not in (SNATCHED, SNATCHED_PROPER, SNATCHED_BACKLOG):
with curEp.lock:
- logger.log("STATUS: we have an associated file, so setting the status from "+str(curEp.status)+" to DOWNLOADED/" + str(DOWNLOADED), logger.DEBUG)
- curEp.status = DOWNLOADED
+ logger.log("STATUS: we have an associated file, so setting the status from "+str(curEp.status)+" to DOWNLOADED/" + str(Quality.downloadedName(file)), logger.DEBUG)
+ curEp.status = Quality.downloadedName(file)
with curEp.lock:
curEp.saveToDB()
@@ -723,7 +723,7 @@ def refreshDir(self):
logger.log(str(self.tvdbid) + ": Location for " + str(season) + "x" + str(episode) + " doesn't exist, removing it and changing our status to SKIPPED", logger.DEBUG)
with curEp.lock:
curEp.location = ''
- if curEp.status == DOWNLOADED:
+ if curEp.status in Quality.DOWNLOADED:
curEp.status = SKIPPED
curEp.hasnfo = False
curEp.hastbn = False
@@ -849,9 +849,47 @@ def __str__(self):
return toReturn
+ def wantEpisode(self, season, episode, quality):
+ logger.log("Checking if we want episode "+str(season)+"x"+str(episode)+" at quality "+Quality.qualityStrings[quality], logger.DEBUG)
+
+ # if the quality isn't one we want under any circumstances then just say no
+ if not quality & self.quality:
+ return False
+
+ myDB = db.DBConnection()
+ sqlResults = myDB.select("SELECT status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", [self.tvdbid, season, episode])
+ if not sqlResults or not len(sqlResults):
+ logger.log("Unable to find the episode")
+ return False
+
+ epStatus = int(sqlResults[0]["status"])
+
+ # if we know we don't want it then just say no
+ if epStatus in (SKIPPED,):
+ logger.log("Ep is skipped, not bothering")
+ return False
+
+ # if it's one of these then we don't even care what the available quality is
+ if epStatus in (MISSED, UNAIRED):
+ logger.log("Ep is missed/unaired, definitely get it")
+ return True
+
+ curQuality, curStatus = Quality.splitCompositeQuality(epStatus)
+ qualities, type = Quality.splitQuality(self.quality)
+
+ # if we already have something snatched/dl'd and quality is ANY then we don't want to downloading anything further
+ if curStatus in Quality.SNATCHED + Quality.DOWNLOADED and type == Quality.ANY:
+ logger.log("Quality type is any and we have one, not bothering")
+ return False
+
+ # if the available quality is one that the show allows and it's better than what we have then say yes
+ if quality in qualities and curQuality < quality and type == Quality.BEST:
+ logger.log("Better quality found, saying yes")
+ return True
+ return False
class TVEpisode:
@@ -1057,8 +1095,8 @@ def loadFromTVDB(self, season=None, episode=None, cache=True):
elif sickbeard.helpers.isMediaFile(self.location):
# leave propers alone, you have to either post-process them or manually change them back
if self.status not in (SNATCHED_PROPER, PREDOWNLOADED):
- logger.log("5 Status changes from " + str(self.status) + " to " + str(DOWNLOADED), logger.DEBUG)
- self.status = DOWNLOADED
+ logger.log("5 Status changes from " + str(self.status) + " to " + str(Quality.downloadedName(self.location)), logger.DEBUG)
+ self.status = Quality.downloadedName(self.location)
# shouldn't get here probably
else:
@@ -1083,8 +1121,8 @@ def loadFromNFO(self, location):
if self.status == UNKNOWN:
if sickbeard.helpers.isMediaFile(self.location):
- logger.log("7 Status changes from " + str(self.status) + " to " + str(DOWNLOADED), logger.DEBUG)
- self.status = DOWNLOADED
+ logger.log("7 Status changes from " + str(self.status) + " to " + str(Quality.downloadedName(self.location)), logger.DEBUG)
+ self.status = Quality.downloadedName(self.location)
nfoFile = sickbeard.helpers.replaceExtension(self.location, "nfo")
logger.log(str(self.show.tvdbid) + ": Using NFO name " + nfoFile, logger.DEBUG)
View
59 sickbeard/tvcache.py
@@ -13,7 +13,7 @@
from sickbeard import logger
from sickbeard.common import *
-from sickbeard import helpers
+from sickbeard import helpers, classes
from lib.tvnamer.utils import FileParser
from lib.tvnamer import tvnamer_exceptions
@@ -164,17 +164,7 @@ def _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrag
# get the current timestamp
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
- if not quality:
- # if we don't know what quality it is and it looks like itouch quality, skip it
- if "itouch" in name.lower():
- return False
- elif any(x in name.lower() for x in ("720p", "1080p", "x264")):
- quality = HD
- elif any(x in name.lower() for x in ("xvid", "divx")):
- quality = SD
- else:
- logger.log("Unable to figure out the quality of "+name+", assuming SD", logger.DEBUG)
- quality = SD
+ quality = Quality.nameQuality(name)
myDB.action("INSERT INTO "+self.providerName+" (name, season, episodes, tvrid, tvdbid, url, time, quality) VALUES (?,?,?,?,?,?,?,?)",
[name, season, episodeText, tvrage_id, tvdb_id, url, curTimestamp, quality])
@@ -193,7 +183,7 @@ def searchCache(self, show, season, episode, quality=ANY):
return myDB.select(sql)
- def listPropers(self, date=None):
+ def listPropers(self, date=None, delimiter="."):
myDB = self._getDB()
@@ -205,3 +195,46 @@ def listPropers(self, date=None):
#return filter(lambda x: x['tvdbid'] != 0, myDB.select(sql))
return myDB.select(sql)
+ def findNeededEpisodes(self):
+ neededEps = {}
+
+ myDB = self._getDB()
+
+ sqlResults = myDB.select("SELECT * FROM "+self.providerName)
+
+ # for each cache entry
+ for curResult in sqlResults:
+
+ # get the show object, or if it's not one of our shows then ignore it
+ showObj = helpers.findCertainShow(sickbeard.showList, int(curResult["tvdbid"]))
+ if not showObj:
+ continue
+
+ # get season and ep data (ignoring multi-eps for now)
+ curSeason = int(curResult["season"])
+ curEp = int(curResult["episodes"].split("|")[1])
+
+ # if the show says we want that episode then add it to the list
+ if showObj.wantEpisode(curSeason, curEp, int(curResult["quality"])):
+
+ epObj = showObj.getEpisode(curSeason, curEp)
+
+ # build a result object
+ title = curResult["name"]
+ url = curResult["url"]
+
+ logger.log("Found result " + title + " at " + url)
+
+ result = classes.NZBSearchResult(epObj)
+ result.provider = self.providerName.lower()
+ result.url = url
+ result.extraInfo = [title]
+ result.quality = int(curResult["quality"])
+
+ # add it to the list
+ if epObj not in neededEps:
+ neededEps[epObj] = [result]
+ else:
+ neededEps[epObj].append(result)
+
+ return neededEps
View
14 sickbeard/webserve.py
@@ -25,6 +25,7 @@
import re
import threading
import datetime
+import operator
from Cheetah.Template import Template
import cherrypy
@@ -1055,7 +1056,7 @@ def index(self):
today = str(datetime.date.today().toordinal())
- t.downloadedEps = myDB.select("SELECT showid, COUNT(*) FROM tv_episodes WHERE status IN ("+str(DOWNLOADED)+","+str(PREDOWNLOADED)+") AND airdate != 1 AND season != 0 and episode != 0 AND airdate <= "+today+" GROUP BY showid")
+ t.downloadedEps = myDB.select("SELECT showid, COUNT(*) FROM tv_episodes WHERE status IN ("+",".join([str(x) for x in Quality.DOWNLOADED])+","+str(PREDOWNLOADED)+") AND airdate != 1 AND season != 0 and episode != 0 AND airdate <= "+today+" GROUP BY showid")
t.allEps = myDB.select("SELECT showid, COUNT(*) FROM tv_episodes WHERE airdate != 1 AND season != 0 and episode != 0 AND airdate <= "+today+" GROUP BY showid")
@@ -1142,7 +1143,7 @@ def plotDetails(self, show, season, episode):
return result['description'] if result else 'Episode not found.'
@cherrypy.expose
- def editShow(self, show=None, location=None, quality=None, seasonfolders=None, paused=None):
+ def editShow(self, show=None, location=None, qualityType=None, quality=None, seasonfolders=None, paused=None):
if show == None:
return _genericMessage("Error", "Invalid show ID")
@@ -1152,7 +1153,7 @@ def editShow(self, show=None, location=None, quality=None, seasonfolders=None, p
if showObj == None:
return _genericMessage("Error", "Unable to find the specified show")
- if location == None and quality == None and seasonfolders == None:
+ if location == None and quality == None and qualityType == None and seasonfolders == None:
t = PageTemplate(file="editShow.tmpl")
t.submenu = HomeMenu
@@ -1175,8 +1176,9 @@ def editShow(self, show=None, location=None, quality=None, seasonfolders=None, p
with showObj.lock:
errors = []
- logger.log("changing quality from " + str(showObj.quality) + " to " + str(quality), logger.DEBUG)
- showObj.quality = int(quality)
+ newQuality = reduce(operator.or_, map(int, quality)) | int(qualityType)
+ logger.log("changing quality from " + str(showObj.quality) + " to " + str(newQuality), logger.DEBUG)
+ showObj.quality = newQuality
if showObj.seasonfolders != seasonfolders:
showObj.seasonfolders = seasonfolders
@@ -1337,7 +1339,7 @@ def setStatus(self, show=None, eps=None, status=None):
logger.log("Refusing to change status of "+curEp+" because it is UNAIRED", logger.ERROR)
continue
- if int(status) == DOWNLOADED and epObj.status not in (PREDOWNLOADED, SNATCHED_PROPER, SNATCHED_BACKLOG):
+ if int(status) in Quality.DOWNLOADED and epObj.status not in [PREDOWNLOADED, SNATCHED_PROPER, SNATCHED_BACKLOG] + Quality.DOWNLOADED:
logger.log("Refusing to change status of "+curEp+" to DOWNLOADED because it's not PREDOWNLOADED/SNATCHED_PROPER/SNATCHED_BACKLOG", logger.ERROR)
continue
Please sign in to comment.
Something went wrong with that request. Please try again.