Updated logger code to now include the section, formatting has been modified as well.

Logging of debug messages is now optional via log_debug option location in autoProcessMedia.cfg

Lots of code cleanup has been performed including cleanup log messages and corrections of spelling errors.

Improved release lookup code for autoProcessMovie, narrows search results down by making API calls to the download clients to compare results in CouchPotato's database.
This commit is contained in:
echel0n 2014-04-18 13:16:18 -07:00
commit eb7822b60b
16 changed files with 420 additions and 441 deletions

View file

@ -1,102 +1,62 @@
import os
import re
import time
import nzbtomedia
from lib import requests
from nzbtomedia.Transcoder import Transcoder
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, create_torrent_class, clean_nzbname
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, find_imdbid, find_download
from nzbtomedia import logger
class autoProcessMovie:
def find_imdbid(self, dirName, nzbName):
imdbid = None
nzbName = clean_nzbname(nzbName)
# find imdbid in dirName
m = re.search('(tt\d{7})', dirName)
if m:
imdbid = m.group(1)
logger.postprocess("Found movie id %s in directory", imdbid)
return imdbid
# find imdbid in nzbName
m = re.search('(tt\d{7})', nzbName)
if m:
imdbid = m.group(1)
logger.postprocess("Found imdbid %s in name", imdbid)
return imdbid
m = re.search("^(.+)\W(\d{4})", os.path.basename(dirName))
if m:
title = m.group(1)
year = m.group(2)
url = "http://www.omdbapi.com"
logger.debug("Opening URL: %s", url)
try:
r = requests.get(url, params={'y':year, 't':title})
except requests.ConnectionError:
logger.error("Unable to open URL")
return
results = r.json()
try:
imdbid = results['imdbID']
except:pass
if imdbid:
return imdbid
def get_releases(self, baseURL, download_id, dirName, nzbName):
releases = {}
def get_releases(self, baseURL, imdbid=None, download_id=None):
results = {}
params = {}
imdbid = self.find_imdbid(dirName, nzbName)
# determin cmd and params to send to CouchPotato to get our results
section = 'movies'
cmd = "/media.list"
params['status'] = 'active,done'
if imdbid:
section = 'media'
cmd = "/media.get"
params['id'] = imdbid
if download_id:
params['release_status'] = 'snatched,downloaded'
url = baseURL + cmd
logger.debug("Opening URL: %s", url)
logger.debug("Opening URL: %s" % url)
try:
r = requests.get(url, params=params)
except requests.ConnectionError:
logger.error("Unable to open URL")
logger.error("Unable to open URL %s" % url)
return
results = r.json()
movies = results[section]
result = r.json()
movies = result[section]
if not isinstance(movies, list):
movies = [movies]
for movie in movies:
if movie['status'] not in ['active','done']:
continue
releases = movie['releases']
if not isinstance(releases, list):
releases = [releases]
for release in releases:
if release['status'] not in ['snatched','downloaded']:
continue
try:
if download_id:
if download_id != release['download_info']['id']:
continue
id = release['_id']
releases[id] = release
results[id] = release
except:continue
return releases
# Search downloads on clients for a match to try and narrow our results down to 1
for id, x in results.items():
try:
if not find_download(str(x['download_info']['downloader']).lower(),x['download_info']['id']):
results.pop(id)
except:continue
return results
def releases_diff(self, dict_a, dict_b):
return dict([
@ -109,21 +69,13 @@ class autoProcessMovie:
])
def process(self, dirName, nzbName=None, status=0, clientAgent = "manual", download_id = "", inputCategory=None):
if dirName is None:
logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section
section = nzbtomedia.CFG.findsection(inputCategory)
if not section:
logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory)
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory)
return 1
logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory)
logger.postprocess("#########################################################")
status = int(status)
host = nzbtomedia.CFG[section][inputCategory]["host"]
@ -141,17 +93,11 @@ class autoProcessMovie:
web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except:
web_root = ""
try:
transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"])
except:
transcode = 0
try:
remote_path = nzbtomedia.CFG[section][inputCategory]["remote_path"]
except:
remote_path = None
nzbName = str(nzbName) # make sure it is a string
if ssl:
protocol = "https://"
else:
@ -159,10 +105,11 @@ class autoProcessMovie:
baseURL = "%s%s:%s%s/api/%s" % (protocol, host, port, web_root, apikey)
releases = self.get_releases(baseURL, download_id, dirName, nzbName)
imdbid = find_imdbid(dirName,nzbName)
releases = self.get_releases(baseURL, imdbid, download_id)
if not releases:
logger.error("Could not find any releases marked as WANTED on CouchPotato to compare changes against %s, skipping ...", nzbName)
logger.error("Could not find any releases marked as WANTED matching %s, skipping ..." % nzbName, section)
return 1
# try to get release_id, media_id, and download_id if one was not passed in
@ -172,19 +119,19 @@ class autoProcessMovie:
try:
release_id = releases.keys()[0]
media_id = releases[release_id]['media_id']
download_id = releases['download_info']['id']
download_id = releases[release_id]['download_info']['id']
except:pass
process_all_exceptions(nzbName.lower(), dirName)
nzbName, dirName = convert_to_ascii(nzbName, dirName)
if status == 0:
if transcode == 1:
if nzbtomedia.TRANSCODE == 1:
result = Transcoder().Transcode_directory(dirName)
if result == 0:
logger.debug("Transcoding succeeded for files in %s", dirName)
logger.debug("Transcoding succeeded for files in %s" % (dirName),section)
else:
logger.warning("Transcoding failed for files in %s", dirName)
logger.warning("Transcoding failed for files in %s" % (dirName),section)
if method == "manage":
command = "/manage.update"
@ -201,86 +148,88 @@ class autoProcessMovie:
dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/")
params['media_folder'] = dirName_new
url = baseURL + command
url = "%s%s" % (baseURL, command)
logger.debug("Opening URL: %s", url)
logger.debug("Opening URL: %s" % (url), section)
logger.postprocess("Attempting to perform a %s scan on CouchPotato for %s", method, nzbName)
logger.postprocess("Attempting to perform a %s scan for %s" % (method, nzbName), section)
try:
r = requests.get(url, params=params)
except requests.ConnectionError:
logger.error("Unable to open URL")
logger.error("Unable to open URL", section)
return 1 # failure
result = r.json()
if result['success']:
logger.postprocess("SUCCESS: %s scan started on CouchPotatoServer for %s", method, nzbName)
logger.postprocess("SUCCESS: Started %s scan on folder %s, please wait ..." % (method, dirName), section)
else:
logger.error("FAILED: %s scan has NOT started on CouchPotato for %s. Exiting ...", method, nzbName)
logger.error("FAILED: %s scan was unable to start for folder %s. exiting!" % (method, dirName), section)
return 1 # failure
else:
logger.postprocess("Download of %s has failed.", nzbName)
logger.postprocess("FAILED DOWNLOAD DETECTED FOR %s" % (nzbName), section)
if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName:
logger.postprocess("Deleting failed files and folder %s", dirName)
logger.postprocess("Deleting failed files and folder %s" % dirName, section)
delete(dirName)
if not download_id:
logger.warning("Could not find a movie in the database for release %s", nzbName)
logger.warning("Please manually ignore this release and refresh the wanted movie from CouchPotato, Exiting ...")
logger.error("Could not find a downloaded movie in the database matching %s, exiting!" % nzbName, section)
return 1 # failure
logger.postprocess("Ignoring current failed release %s ...", nzbName)
logger.postprocess("Setting failed release %s to ignored ..." % (nzbName), section)
url = baseURL + "/release.ignore"
logger.debug("Opening URL: %s", url)
logger.debug("Opening URL: %s" % (url), section)
try:
r = requests.get(url, params={'id': release_id})
except requests.ConnectionError:
logger.error("Unable to open URL")
logger.error("Unable to open URL %s" % (url), section)
return 1 # failure
result = r.json()
if result['success']:
logger.postprocess("%s has been set to ignored on CouchPotato", nzbName)
logger.postprocess("SUCCESS: %s has been set to ignored ..." % (nzbName), section)
else:
logger.warning("Failed to ignore %s on CouchPotato ...", nzbName)
logger.warning("FAILED: Unable to set %s to ignored!" % (nzbName), section)
logger.postprocess("Snatching next highest ranked release on CouchPotato ...")
logger.postprocess("Trying to snatch the next highest ranked release.", section)
url = baseURL + "/movie.searcher.try_next"
logger.debug("Opening URL: %s", url)
url = "%s/movie.searcher.try_next" % (baseURL)
logger.debug("Opening URL: %s" % (url), section)
try:
r = requests.get(url, params={'media_id': media_id})
except requests.ConnectionError:
logger.error("Unable to open URL")
logger.error("Unable to open URL %s" % (url), section)
return 1 # failure
result = r.json()
if result['success']:
logger.postprocess("CouchPotato successfully snatched the next highest release above %s ...", nzbName)
logger.postprocess("SUCCESS: Snatched the next highest release ...", section)
return 0
else:
logger.postprocess("CouchPotato was unable to find a higher release then %s to snatch ...", nzbName)
logger.postprocess("FAILED: Unable to find a higher ranked release then %s to snatch!" % (nzbName), section)
return 1
# we will now check to see if CPS has finished renaming before returning to TorrentToMedia and unpausing.
timeout = time.time() + 60 * wait_for
while (time.time() < timeout): # only wait 2 (default) minutes, then return.
releases_current = self.get_releases(baseURL, download_id, dirName, nzbName)
releases_current = self.get_releases(baseURL, imdbid, download_id)
releasesDiff = self.releases_diff(releases, releases_current)
logger.postprocess("Checking for status change, please stand by ...", section)
if releasesDiff: # Something has changed. CPS must have processed this movie.
release_status = releasesDiff[releasesDiff.keys()[0]]['status']
logger.postprocess("SUCCESS: Release %s marked as [%s] on CouchPotato", nzbName, release_status)
return 0 # success
try:
release_status = releasesDiff[releasesDiff.keys()[0]]['status']
logger.postprocess("SUCCESS: Release %s has now been marked with a status of [%s]" % (nzbName, str(release_status).upper()), section)
return 0 # success
except:pass
# pause and let CouchPotatoServer catch its breath
time.sleep(10 * wait_for)
# The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now.
logger.warning("The movie does not appear to have changed status after %s minutes. Please check CouchPotato Logs", wait_for)
logger.warning("%s does not appear to have changed status after %s minutes, Please check your logs." % (nzbName, wait_for), section)
return 1 # failure