2014-03-10 01:18:05 -04:00
|
|
|
# Author: Jasper Lanting
|
|
|
|
# Based on nmj.py by Nico Berlee: http://nico.berlee.nl/
|
|
|
|
# URL: http://code.google.com/p/sickbeard/
|
|
|
|
#
|
2014-05-23 08:37:22 -04:00
|
|
|
# This file is part of SickRage.
|
2014-03-10 01:18:05 -04:00
|
|
|
#
|
2014-05-23 08:37:22 -04:00
|
|
|
# SickRage is free software: you can redistribute it and/or modify
|
2014-03-10 01:18:05 -04:00
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
2014-05-23 08:37:22 -04:00
|
|
|
# SickRage is distributed in the hope that it will be useful,
|
2014-03-10 01:18:05 -04:00
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2014-05-23 08:37:22 -04:00
|
|
|
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
2014-03-10 01:18:05 -04:00
|
|
|
|
2014-03-25 01:57:24 -04:00
|
|
|
import urllib, urllib2, xml.dom.minidom
|
2014-03-10 01:18:05 -04:00
|
|
|
from xml.dom.minidom import parseString
|
|
|
|
import sickbeard
|
|
|
|
import telnetlib
|
|
|
|
import re
|
|
|
|
import time
|
|
|
|
|
|
|
|
from sickbeard import logger
|
|
|
|
|
|
|
|
try:
|
|
|
|
import xml.etree.cElementTree as etree
|
|
|
|
except ImportError:
|
|
|
|
import xml.etree.ElementTree as etree
|
|
|
|
|
|
|
|
|
|
|
|
class NMJv2Notifier:
|
|
|
|
def notify_snatch(self, ep_name):
|
|
|
|
return False
|
|
|
|
#Not implemented: Start the scanner when snatched does not make any sense
|
|
|
|
|
|
|
|
def notify_download(self, ep_name):
|
|
|
|
self._notifyNMJ()
|
|
|
|
|
|
|
|
def notify_subtitle_download(self, ep_name, lang):
|
|
|
|
self._notifyNMJ()
|
2014-07-03 02:43:48 -04:00
|
|
|
|
2014-07-03 17:04:26 -04:00
|
|
|
def notify_git_update(self, new_version):
|
2014-07-03 02:43:48 -04:00
|
|
|
return False
|
|
|
|
# Not implemented, no reason to start scanner.
|
2014-03-10 01:18:05 -04:00
|
|
|
|
|
|
|
def test_notify(self, host):
|
|
|
|
return self._sendNMJ(host)
|
|
|
|
|
|
|
|
def notify_settings(self, host, dbloc, instance):
|
|
|
|
"""
|
|
|
|
Retrieves the NMJv2 database location from Popcorn hour
|
|
|
|
|
|
|
|
host: The hostname/IP of the Popcorn Hour server
|
|
|
|
dbloc: 'local' for PCH internal harddrive. 'network' for PCH network shares
|
|
|
|
instance: Allows for selection of different DB in case of multiple databases
|
|
|
|
|
|
|
|
Returns: True if the settings were retrieved successfully, False otherwise
|
|
|
|
"""
|
|
|
|
try:
|
2014-03-25 01:57:24 -04:00
|
|
|
url_loc = "http://" + host + ":8008/file_operation?arg0=list_user_storage_file&arg1=&arg2=" + instance + "&arg3=20&arg4=true&arg5=true&arg6=true&arg7=all&arg8=name_asc&arg9=false&arg10=false"
|
2014-03-10 01:18:05 -04:00
|
|
|
req = urllib2.Request(url_loc)
|
|
|
|
handle1 = urllib2.urlopen(req)
|
|
|
|
response1 = handle1.read()
|
|
|
|
xml = parseString(response1)
|
2014-03-25 01:57:24 -04:00
|
|
|
time.sleep(300.0 / 1000.0)
|
2014-03-10 01:18:05 -04:00
|
|
|
for node in xml.getElementsByTagName('path'):
|
2014-03-25 01:57:24 -04:00
|
|
|
xmlTag = node.toxml();
|
|
|
|
xmlData = xmlTag.replace('<path>', '').replace('</path>', '').replace('[=]', '')
|
|
|
|
url_db = "http://" + host + ":8008/metadata_database?arg0=check_database&arg1=" + xmlData
|
2014-03-10 01:18:05 -04:00
|
|
|
reqdb = urllib2.Request(url_db)
|
|
|
|
handledb = urllib2.urlopen(reqdb)
|
|
|
|
responsedb = handledb.read()
|
|
|
|
xmldb = parseString(responsedb)
|
2014-03-25 01:57:24 -04:00
|
|
|
returnvalue = xmldb.getElementsByTagName('returnValue')[0].toxml().replace('<returnValue>', '').replace(
|
|
|
|
'</returnValue>', '')
|
|
|
|
if returnvalue == "0":
|
|
|
|
DB_path = xmldb.getElementsByTagName('database_path')[0].toxml().replace('<database_path>',
|
|
|
|
'').replace(
|
|
|
|
'</database_path>', '').replace('[=]', '')
|
|
|
|
if dbloc == "local" and DB_path.find("localhost") > -1:
|
|
|
|
sickbeard.NMJv2_HOST = host
|
|
|
|
sickbeard.NMJv2_DATABASE = DB_path
|
2014-03-10 01:18:05 -04:00
|
|
|
return True
|
2014-03-25 01:57:24 -04:00
|
|
|
if dbloc == "network" and DB_path.find("://") > -1:
|
|
|
|
sickbeard.NMJv2_HOST = host
|
|
|
|
sickbeard.NMJv2_DATABASE = DB_path
|
2014-03-10 01:18:05 -04:00
|
|
|
return True
|
2014-03-25 01:57:24 -04:00
|
|
|
|
2014-03-10 01:18:05 -04:00
|
|
|
except IOError, e:
|
2014-05-28 20:30:38 -04:00
|
|
|
logger.log(u"Warning: Couldn't contact popcorn hour on host %s: %s" % (host, e), logger.WARNING)
|
2014-03-10 01:18:05 -04:00
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
|
|
def _sendNMJ(self, host):
|
|
|
|
"""
|
|
|
|
Sends a NMJ update command to the specified machine
|
|
|
|
|
|
|
|
host: The hostname/IP to send the request to (no port)
|
|
|
|
database: The database to send the requst to
|
|
|
|
mount: The mount URL to use (optional)
|
|
|
|
|
|
|
|
Returns: True if the request succeeded, False otherwise
|
|
|
|
"""
|
2014-03-25 01:57:24 -04:00
|
|
|
|
2014-03-10 01:18:05 -04:00
|
|
|
#if a host is provided then attempt to open a handle to that URL
|
|
|
|
try:
|
2014-03-25 01:57:24 -04:00
|
|
|
url_scandir = "http://" + host + ":8008/metadata_database?arg0=update_scandir&arg1=" + sickbeard.NMJv2_DATABASE + "&arg2=&arg3=update_all"
|
2014-05-28 20:30:38 -04:00
|
|
|
logger.log(u"NMJ scan update command sent to host: %s" % (host), logger.DEBUG)
|
2014-03-25 01:57:24 -04:00
|
|
|
url_updatedb = "http://" + host + ":8008/metadata_database?arg0=scanner_start&arg1=" + sickbeard.NMJv2_DATABASE + "&arg2=background&arg3="
|
2014-03-10 01:18:05 -04:00
|
|
|
logger.log(u"Try to mount network drive via url: %s" % (host), logger.DEBUG)
|
|
|
|
prereq = urllib2.Request(url_scandir)
|
|
|
|
req = urllib2.Request(url_updatedb)
|
|
|
|
handle1 = urllib2.urlopen(prereq)
|
|
|
|
response1 = handle1.read()
|
2014-03-25 01:57:24 -04:00
|
|
|
time.sleep(300.0 / 1000.0)
|
2014-03-10 01:18:05 -04:00
|
|
|
handle2 = urllib2.urlopen(req)
|
|
|
|
response2 = handle2.read()
|
|
|
|
except IOError, e:
|
2014-05-28 20:30:38 -04:00
|
|
|
logger.log(u"Warning: Couldn't contact popcorn hour on host %s: %s" % (host, e), logger.WARNING)
|
2014-03-10 01:18:05 -04:00
|
|
|
return False
|
2014-03-25 01:57:24 -04:00
|
|
|
try:
|
2014-03-10 01:18:05 -04:00
|
|
|
et = etree.fromstring(response1)
|
|
|
|
result1 = et.findtext("returnValue")
|
|
|
|
except SyntaxError, e:
|
2014-03-25 01:57:24 -04:00
|
|
|
logger.log(u"Unable to parse XML returned from the Popcorn Hour: update_scandir, %s" % (e), logger.ERROR)
|
|
|
|
return False
|
|
|
|
try:
|
2014-03-10 01:18:05 -04:00
|
|
|
et = etree.fromstring(response2)
|
|
|
|
result2 = et.findtext("returnValue")
|
|
|
|
except SyntaxError, e:
|
|
|
|
logger.log(u"Unable to parse XML returned from the Popcorn Hour: scanner_start, %s" % (e), logger.ERROR)
|
|
|
|
return False
|
2014-03-25 01:57:24 -04:00
|
|
|
|
2014-03-10 01:18:05 -04:00
|
|
|
# if the result was a number then consider that an error
|
2014-03-25 01:57:24 -04:00
|
|
|
error_codes = ["8", "11", "22", "49", "50", "51", "60"]
|
|
|
|
error_messages = ["Invalid parameter(s)/argument(s)",
|
|
|
|
"Invalid database path",
|
|
|
|
"Insufficient size",
|
|
|
|
"Database write error",
|
|
|
|
"Database read error",
|
|
|
|
"Open fifo pipe failed",
|
|
|
|
"Read only file system"]
|
2014-03-10 01:18:05 -04:00
|
|
|
if int(result1) > 0:
|
2014-03-25 01:57:24 -04:00
|
|
|
index = error_codes.index(result1)
|
2014-05-28 20:30:38 -04:00
|
|
|
logger.log(u"Popcorn Hour returned an error: %s" % (error_messages[index]), logger.ERROR)
|
2014-03-10 01:18:05 -04:00
|
|
|
return False
|
|
|
|
else:
|
|
|
|
if int(result2) > 0:
|
2014-03-25 01:57:24 -04:00
|
|
|
index = error_codes.index(result2)
|
2014-05-28 20:30:38 -04:00
|
|
|
logger.log(u"Popcorn Hour returned an error: %s" % (error_messages[index]), logger.ERROR)
|
2014-03-10 01:18:05 -04:00
|
|
|
return False
|
|
|
|
else:
|
2014-12-16 05:24:06 -05:00
|
|
|
logger.log(u"NMJv2 started background scan", logger.INFO)
|
2014-03-10 01:18:05 -04:00
|
|
|
return True
|
|
|
|
|
|
|
|
def _notifyNMJ(self, host=None, force=False):
|
|
|
|
"""
|
|
|
|
Sends a NMJ update command based on the SB config settings
|
|
|
|
|
|
|
|
host: The host to send the command to (optional, defaults to the host in the config)
|
|
|
|
database: The database to use (optional, defaults to the database in the config)
|
|
|
|
mount: The mount URL (optional, defaults to the mount URL in the config)
|
|
|
|
force: If True then the notification will be sent even if NMJ is disabled in the config
|
|
|
|
"""
|
|
|
|
if not sickbeard.USE_NMJv2 and not force:
|
|
|
|
logger.log("Notification for NMJ scan update not enabled, skipping this notification", logger.DEBUG)
|
|
|
|
return False
|
|
|
|
|
|
|
|
# fill in omitted parameters
|
|
|
|
if not host:
|
|
|
|
host = sickbeard.NMJv2_HOST
|
|
|
|
|
|
|
|
logger.log(u"Sending scan command for NMJ ", logger.DEBUG)
|
|
|
|
|
|
|
|
return self._sendNMJ(host)
|
|
|
|
|
2014-03-25 01:57:24 -04:00
|
|
|
|
2014-03-10 01:18:05 -04:00
|
|
|
notifier = NMJv2Notifier
|