Added working version 2.2

Previous work was done over at couchpota.to and QNAP forums. This commit
includes previous history in the helpfile.
This commit is contained in:
Clinton Hall 2012-11-11 09:35:56 +10:30
commit 26ac4b5353
4 changed files with 338 additions and 0 deletions

View file

@ -0,0 +1,22 @@
[CouchPotato]
host = localhost
port = 5050
username =
password =
ssl = 0
web_root =
apikey = xxxxxxxx
delay = 60
method = renamer
[Comments]
host = (ip address for CouchPotato Server. Use "localhost" if SABnzbd and CPS on same system)
port = (port for CouchPotato Server)
username = (username if set for CouchPotato Server)
password = (password if set for CouchPotato Server)
ssl = 0 (set to 1 if you want to use ssl. -untested. Default is 0)
web_root = (set URL base if needed.)
apikey = (apikey for CouchPotato Server... Required)
delay = (set delay in seconds before sending api call. Minimum 60)
method = "renamer" or "manage". renamer is the default. Read the help file.

143
autoProcessMovie.py Normal file
View file

@ -0,0 +1,143 @@
import sys
import urllib
import os.path
import ConfigParser
import time
import json
from pprint import pprint
class AuthURLOpener(urllib.FancyURLopener):
def __init__(self, user, pw):
self.username = user
self.password = pw
self.numTries = 0
urllib.FancyURLopener.__init__(self)
def prompt_user_passwd(self, host, realm):
if self.numTries == 0:
self.numTries = 1
return (self.username, self.password)
else:
return ('', '')
def openit(self, url):
self.numTries = 0
return urllib.FancyURLopener.open(self, url)
def process(dirName, nzbName=None, status=0):
config = ConfigParser.ConfigParser()
configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMovie.cfg")
print "autoProcessMovie v 2.2"
print "Loading config from", configFilename
if not os.path.isfile(configFilename):
print "ERROR: You need an autoProcessMovie.cfg file - did you rename and edit the .sample?"
sys.exit(-1)
config.read(configFilename)
host = config.get("CouchPotato", "host")
port = config.get("CouchPotato", "port")
username = config.get("CouchPotato", "username")
password = config.get("CouchPotato", "password")
apikey = config.get("CouchPotato", "apikey")
delay = float(config.get("CouchPotato", "delay"))
method = config.get("CouchPotato", "method")
try:
ssl = int(config.get("CouchPotato", "ssl"))
except (ConfigParser.NoOptionError, ValueError):
ssl = 0
try:
web_root = config.get("CouchPotato", "web_root")
except ConfigParser.NoOptionError:
web_root = ""
myOpener = AuthURLOpener(username, password)
nzbName1 = str(nzbName)
if ssl:
protocol = "https://"
else:
protocol = "http://"
if status == 0:
if method == "manage":
command = "manage.update"
else:
command = "renamer.scan"
url = protocol + host + ":" + port + web_root + "/api/" + apikey + "/" + command
print "waiting for", str(delay), "seconds to allow CPS to process newly extracted files"
time.sleep(delay)
print "Opening URL:", url
try:
urlObj = myOpener.openit(url)
except IOError, e:
print "Unable to open URL: ", str(e)
sys.exit(1)
result = urlObj.readlines()
for line in result:
print line
print command, "started on CouchPotatoServer for", nzbName1
else:
print "download of", nzbName1, "has failed."
print "trying to re-cue the next highest ranked release"
a=nzbName1.find('.cp')+4
b=nzbName1.find('.nzb')-1
imdbid=nzbName1[a:b]
#print imdbid
url = protocol + host + ":" + port + web_root + "/api/" + apikey + "/movie.list"
print "Opening URL:", url
try:
urlObj = myOpener.openit(url)
except IOError, e:
print "Unable to open URL: ", str(e)
sys.exit(1)
n=0
result = json.load(urlObj)
movieid = [item["id"] for item in result["movies"]]
library = [item["library"] for item in result["movies"]]
identifier = [item["identifier"] for item in library]
for index in range(len(movieid)):
if identifier[index] == imdbid:
movid = str(movieid[index])
print "found movie id", movid, "in database for release", nzbName1
n = n + 1
break
if n == 0:
print "cound not find a mvie in the database for release", nzbName1
print "please manually ignore this release and refresh the wanted movie"
print "exiting postprocessing script"
sys.exit(1)
url = protocol + host + ":" + port + web_root + "/api/" + apikey + "/searcher.try_next/?id=" + movid
print "Opening URL:", url
try:
urlObj = myOpener.openit(url)
except IOError, e:
print "Unable to open URL: ", str(e)
sys.exit(1)
result = urlObj.readlines()
for line in result:
print line
print "movie", movid, "set to try the next best release on CouchPotatoServer"

View file

@ -0,0 +1,149 @@
Rename the file autoProcessMovie.cfg.sample to autoProcessMovie.cfg
Fill in the appropriate fields as they apply to your installation.
[Notes_On_Delay]
delay must be a minimum of 60 seconds for the renamer.scan to run successfully. CouchPotato
performs a test to ensure files/folder are not newer than 1 minute to prevent renaming of
files that are still extracting.
[Notes_On_Method_renamer]
method "renamer" is the default which will cause CouchPotato to move and rename downloaded files
as specified in the CouchPotato renamer settings.
This will also add the movie to the manage list and initiate any configured notifications.
In this case SABnzbd (or your download client) must extract the files to the "from" folder
as specified in your CouchPotato renamer settings. Renamer must be enabled but you should
increase the "run every" option in CouchPotato renamer settings (advanced settings) to only
run daily (1440) or weekly (10080) or automatic scan can be disabled by setting run every =0.
[Notes_On_Method_manage]
method "manage" will make CouchPotato update the list of managed movies if manager
is enabled but renamer is not enabled.
In this case SABnzbd (or your download client) must extract the files directly
to your final movies folder (as configured in CouchPotato manage settings) and Manage must
be enabled.
If you have added .py to your PATHEXT (in windows) or you have given sabToCouchPotato.py executable
permissions, or you are using the compiled executables you can manually call this process outside of
sabnzbd for testing your configuration or in case a postprocessing event failed.
To do this, execute sabToCouchPotato.py
e.g. via ssl issue the following command: #./sabToCouchPotato.py
when in the directory where sabToCouchPotato.py is located.
Change_LOG / History
V2.2 05/10/2012
Re-wrote the failed downlaod handling to just search for the imdb ttXXXX identifier (as received from the nzb name)
Now issues only two api calls. movie.list and searcher.try_next
Should be more robust with regards changes to CPS and also utilises less resources (i.e. less api call and and less processing).
V2.1 04/10/2012
detected a change in the movie release info format. Fixed the script to work with new format.
V2.0 04/10/2012
Fixed an issue with the failed download handling in that the status id for "snatched" can be different on each installation. now performs a status.list via api to verify the status.
Also including a version print (currently 2.0... yeah original I know) so you know if you are current.
removed the multiple versions. The former _recue version will perform the standard renamer only if "postprocess only verified downloads" (default) is enabled in SABnzbd. Also, the "unix" version works fine in Windows, only the "dos" version gave issue in Linux. In other words, this one version should work for all systems.
For historical reasons, the former download stats apply to the old versions:
sabToCouchPotato-dos - downloaded 143 times
sabToCouchPotato-unix - downloaded 205 times
sabToCouchPotato_recue - downloaded 105 times
Also updated the Windows Build to include the same changes. I have removed the link to the linux build as this didn't work on all systems and it really shouldn't be necessary. Let me know if you need this updated.
V1.9 18/09/2012
compiled (build) versions of sabToSickBeard and sabToCouchPotato added for both Linux and Windows. links at top of post.
V1.9 16/09/2012
Added a compiled .exe version for windows. Should prevent the "python not recognised" issue and allow this to be used in conjunction with the windows build on systems that do not have python installed.
This is the full (_recue version) if sabnzbd is set to post ptocess only verified jobs, this will not recue and will function as a standard renamer.
V1.9 27/08/2012
Following the latest CPS update on the master branch, this script is not really needed as CPS actually polls the SABnzbd api and does the same as this script (internally).
However, if you have any issues with CPS constantly downloading the same movies, or filling the log with polling SABnzbd for completed movies, or otherwise prefer to use this method, then you can still use this script and make the following changes in CPS:
Settings, renamer, run every (advanced) = set to 1440 (or some longer interval)
Settings, renamer, next On_failed = off
Settings, downloaders, SABnzbd, Delete failed = off.
V1.9 06/08/2012
Also added the integer handling of status in the sabToSickBeard.py script to prevent SickBeard trying to postprocess a failed TV download. Only impacts the _recue version
V1.8 05/08/2012
Modified the _recue version as SABnzbd 0.7.3 now appears to pass the "status" variable as a string not an integer!!! (or i had it wrong on first attempt :~)
This causes the old script to identify completed downloads as failed and recues the next download!
The fix here should work with any conceivable subsequent updates in that I now make the sys.argv[7] an integer before passing it. if the variable already is an integer, this shouldn't cause any issues.
status = int(sys.argv[7])
autoProcessMovie.process(sys.argv[1], sys.argv[2], status)
V1.7 02/08/2012
Added a new version sabToCouchPotato_recue
This works the same as the other versions, but includes support for recuing failed downloads.
This is new, and only tested once (with success ) at my end.
To get this to run you will need to uncheck the "post-process only verified jobs" option in SABnzbd. Also, to avoid issues with SickBeard postprocessing, I have included a modified postprocessing for SickBeard that just checks for failed status and then exits (the SickBeard Team are currently working on failed download handling and I will hopefully make this script work with that in the future)
This re-cue works as follows:
Performs an api call to CPS to get a list of all wanted movies (with all data including the releases and status etc)
It finds the nzbname (from SABnzbd) in the json list returned from the api call (movie.list) and identifies the movie id and release id.
It performs an api call to make the release as "ignore" and then performs another api call to refresh the movie.
If another (next best) release that meets your criteria is already available it will send that to SABnzbd, otherwise it will wait until a new release becomes availabe.
I have left the old versions here for now for those who don't want to try this. Also, if you don't uncheck the "post-process only verified jobs" in SABnzbd this code will perform the same as the previous versions.
The next issue to tackle (if this works) is automating the deletion of failed download files in SABnzbd.... but I figured this was a start.
V1.6 22/07/2012
no functionality change, but providing scripts in both unix and dos format to prevent exit(127) errors.
if you are using windows, use the dos format. if you are using linux, use the unix format and unzip the files in linux.
V1.5 17/07/2012
add back the web_root parameter to set the URL base.
V1.4 17/07/2012
Have uploaded the latest version.
changes
Removed support for a movie.downlaoded api call that was only used in a seperate branch and is not expected to be merged.
Modified the passthrough to allow a manual call to this script (i.e. does not need to be called from SABnzbd).
Have added a helpfile that explains the setup options in a bit more detail.
Modified the .cfg.sample file to use 60 as a default delay and now specify that 60 should be your minimum to ensure the renamer.scan finds newly extracted movies.
V1.3 and earlier were not fully tracked, as the script itself (not files) was posted on the QNAP forums.

24
sabToCouchPotato.py Normal file
View file

@ -0,0 +1,24 @@
#!/usr/bin/env python
import sys
import autoProcessMovie
if len(sys.argv) < 8:
print "Not enough arguments received from SABnzbd."
print "Running autoProcessMovie as a manual run"
autoProcessMovie.process('Manual Run', 'Manual Run', 0)
else:
status = int(sys.argv[7])
autoProcessMovie.process(sys.argv[1], sys.argv[2], status)
# SABnzbd argv:
# 1 The final directory of the job (full path)
# 2 The original name of the NZB file
# 3 Clean version of the job name (no path info and ".nzb" removed)
# 4 Indexer's report number (if supported)
# 5 User-defined category
# 6 Group that the NZB was posted in e.g. alt.binaries.x
# 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2