mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2025-08-14 10:36:52 -07:00
Merge pull request #1439 from clinton-hall/quality/refactor
Major code refactoring
This commit is contained in:
commit
aea6e12639
25 changed files with 516 additions and 537 deletions
|
@ -5,9 +5,9 @@ import os
|
|||
import sys
|
||||
|
||||
import core
|
||||
from core import logger, nzbToMediaDB
|
||||
from core.nzbToMediaUserScript import external_script
|
||||
from core.nzbToMediaUtil import char_replace, convert_to_ascii, plex_update, replace_links
|
||||
from core import logger, main_db
|
||||
from core.user_scripts import external_script
|
||||
from core.utils import char_replace, convert_to_ascii, plex_update, replace_links
|
||||
from six import text_type
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp
|
|||
if client_agent != 'manual' and not core.DOWNLOADINFO:
|
||||
logger.debug('Adding TORRENT download info for directory {0} to database'.format(input_directory))
|
||||
|
||||
my_db = nzbToMediaDB.DBConnection()
|
||||
my_db = main_db.DBConnection()
|
||||
|
||||
input_directory1 = input_directory
|
||||
input_name1 = input_name
|
||||
|
@ -237,14 +237,14 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp
|
|||
elif section_name in ['SickBeard', 'NzbDrone', 'Sonarr']:
|
||||
if input_hash:
|
||||
input_hash = input_hash.upper()
|
||||
result = core.TV().process_episode(section_name, output_destination, input_name,
|
||||
status, client_agent, input_hash, input_category)
|
||||
result = core.TV().process(section_name, output_destination, input_name,
|
||||
status, client_agent, input_hash, input_category)
|
||||
elif section_name in ['HeadPhones', 'Lidarr']:
|
||||
result = core.Music().process(section_name, output_destination, input_name,
|
||||
status, client_agent, input_category)
|
||||
elif section_name == 'Mylar':
|
||||
result = core.Comic().process_episode(section_name, output_destination, input_name,
|
||||
status, client_agent, input_category)
|
||||
result = core.Comic().process(section_name, output_destination, input_name,
|
||||
status, client_agent, input_category)
|
||||
elif section_name == 'Gamez':
|
||||
result = core.Game().process(section_name, output_destination, input_name,
|
||||
status, client_agent, input_category)
|
||||
|
|
|
@ -42,22 +42,15 @@ MYAPP = None
|
|||
import six
|
||||
from six.moves import reload_module
|
||||
|
||||
from core import logger, nzbToMediaDB, versionCheck
|
||||
from core.autoProcess.autoProcessComics import Comic
|
||||
from core.autoProcess.autoProcessGames import Game
|
||||
from core.autoProcess.autoProcessMovie import Movie
|
||||
from core.autoProcess.autoProcessMusic import Music
|
||||
from core.autoProcess.autoProcessTV import TV
|
||||
from core.databases import mainDB
|
||||
from core.nzbToMediaConfig import config
|
||||
from core.nzbToMediaUtil import (
|
||||
from core import logger, main_db, version_check, databases, transcoder
|
||||
from core.auto_process import Comic, Game, Movie, Music, TV
|
||||
from core.configuration import config
|
||||
from core.utils import (
|
||||
RunningProcess, wake_up, category_search, clean_dir, clean_dir, copy_link,
|
||||
create_torrent_class, extract_files, flatten, get_dirs, get_download_info,
|
||||
list_media_files, make_dir, parse_args, pause_torrent, remove_torrent,
|
||||
resume_torrent, remove_dir, remove_read_only, sanitize_name, update_download_info_status,
|
||||
)
|
||||
from core.transcoder import transcoder
|
||||
|
||||
|
||||
# Client Agents
|
||||
NZB_CLIENTS = ['sabnzbd', 'nzbget', 'manual']
|
||||
|
@ -326,7 +319,7 @@ def initialize(section=None):
|
|||
logger.info("{0}: {1}".format(item, os.environ[item]), "ENVIRONMENT")
|
||||
|
||||
# initialize the main SB database
|
||||
nzbToMediaDB.upgrade_database(nzbToMediaDB.DBConnection(), mainDB.InitialSchema)
|
||||
main_db.upgrade_database(main_db.DBConnection(), databases.InitialSchema)
|
||||
|
||||
# Set Version and GIT variables
|
||||
NZBTOMEDIA_VERSION = '11.06'
|
||||
|
@ -343,10 +336,10 @@ def initialize(section=None):
|
|||
NOEXTRACTFAILED = int(CFG["General"]["no_extract_failed"])
|
||||
|
||||
# Check for updates via GitHUB
|
||||
if versionCheck.CheckVersion().check_for_new_version():
|
||||
if version_check.CheckVersion().check_for_new_version():
|
||||
if AUTO_UPDATE == 1:
|
||||
logger.info("Auto-Updating nzbToMedia, Please wait ...")
|
||||
updated = versionCheck.CheckVersion().update()
|
||||
updated = version_check.CheckVersion().update()
|
||||
if updated:
|
||||
# restart nzbToMedia
|
||||
try:
|
||||
|
@ -852,7 +845,7 @@ def initialize(section=None):
|
|||
|
||||
|
||||
def restart():
|
||||
install_type = versionCheck.CheckVersion().install_type
|
||||
install_type = version_check.CheckVersion().install_type
|
||||
|
||||
status = 0
|
||||
popen_list = []
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# coding=utf-8
|
7
core/auto_process/__init__.py
Normal file
7
core/auto_process/__init__.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
# coding=utf-8
|
||||
|
||||
from core.auto_process.comics import Comic
|
||||
from core.auto_process.games import Game
|
||||
from core.auto_process.movies import Movie
|
||||
from core.auto_process.music import Music
|
||||
from core.auto_process.tv import TV
|
|
@ -6,13 +6,13 @@ import requests
|
|||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaUtil import convert_to_ascii, remote_dir, server_responding
|
||||
from core.utils import convert_to_ascii, remote_dir, server_responding
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class Comic(object):
|
||||
def process_episode(self, section, dir_name, input_name=None, status=0, client_agent='manual', input_category=None):
|
||||
def process(self, section, dir_name, input_name=None, status=0, client_agent='manual', input_category=None):
|
||||
apc_version = "2.04"
|
||||
comicrn_version = "1.01"
|
||||
|
|
@ -7,7 +7,7 @@ import requests
|
|||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaUtil import convert_to_ascii, server_responding
|
||||
from core.utils import convert_to_ascii, server_responding
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
|
@ -7,144 +7,14 @@ import time
|
|||
import requests
|
||||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaSceneExceptions import process_all_exceptions
|
||||
from core.nzbToMediaUtil import convert_to_ascii, find_download, find_imdbid, import_subs, list_media_files, remote_dir, report_nzb, remove_dir, server_responding
|
||||
from core.transcoder import transcoder
|
||||
from core import logger, transcoder
|
||||
from core.scene_exceptions import process_all_exceptions
|
||||
from core.utils import convert_to_ascii, find_download, find_imdbid, import_subs, list_media_files, remote_dir, remove_dir, report_nzb, server_responding
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class Movie(object):
|
||||
def get_release(self, base_url, imdb_id=None, download_id=None, release_id=None):
|
||||
results = {}
|
||||
params = {}
|
||||
|
||||
# determine cmd and params to send to CouchPotato to get our results
|
||||
section = 'movies'
|
||||
cmd = "media.list"
|
||||
if release_id or imdb_id:
|
||||
section = 'media'
|
||||
cmd = "media.get"
|
||||
params['id'] = release_id or imdb_id
|
||||
|
||||
if not (release_id or imdb_id or download_id):
|
||||
logger.debug("No information available to filter CP results")
|
||||
return results
|
||||
|
||||
url = "{0}{1}".format(base_url, cmd)
|
||||
logger.debug("Opening URL: {0} with PARAMS: {1}".format(url, params))
|
||||
|
||||
try:
|
||||
r = requests.get(url, params=params, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL {0}".format(url))
|
||||
return results
|
||||
|
||||
try:
|
||||
result = r.json()
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("CouchPotato returned the following non-json data")
|
||||
for line in r.iter_lines():
|
||||
logger.error("{0}".format(line))
|
||||
return results
|
||||
|
||||
if not result['success']:
|
||||
if 'error' in result:
|
||||
logger.error('{0}'.format(result['error']))
|
||||
else:
|
||||
logger.error("no media found for id {0}".format(params['id']))
|
||||
return results
|
||||
|
||||
# Gather release info and return it back, no need to narrow results
|
||||
if release_id:
|
||||
try:
|
||||
id = result[section]['_id']
|
||||
results[id] = result[section]
|
||||
return results
|
||||
except:
|
||||
pass
|
||||
|
||||
# Gather release info and proceed with trying to narrow results to one release choice
|
||||
|
||||
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 releases:
|
||||
continue
|
||||
for release in releases:
|
||||
try:
|
||||
if release['status'] not in ['snatched', 'downloaded', 'done']:
|
||||
continue
|
||||
if download_id:
|
||||
if download_id.lower() != release['download_info']['id'].lower():
|
||||
continue
|
||||
|
||||
id = release['_id']
|
||||
results[id] = release
|
||||
results[id]['title'] = movie['title']
|
||||
except:
|
||||
continue
|
||||
|
||||
# Narrow results by removing old releases by comparing their last_edit field
|
||||
if len(results) > 1:
|
||||
for id1, x1 in results.items():
|
||||
for id2, x2 in results.items():
|
||||
try:
|
||||
if x2["last_edit"] > x1["last_edit"]:
|
||||
results.pop(id1)
|
||||
except:
|
||||
continue
|
||||
|
||||
# Search downloads on clients for a match to try and narrow our results down to 1
|
||||
if len(results) > 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 command_complete(self, url, params, headers, section):
|
||||
try:
|
||||
r = requests.get(url, params=params, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url), section)
|
||||
return None
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return r.json()['state']
|
||||
except (ValueError, KeyError):
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("{0} did not return expected json data.".format(section), section)
|
||||
return None
|
||||
|
||||
def completed_download_handling(self, url2, headers, section="MAIN"):
|
||||
try:
|
||||
r = requests.get(url2, params={}, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url2), section)
|
||||
return False
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
return r.json().get("enableCompletedDownloadHandling", False)
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
return False
|
||||
|
||||
def process(self, section, dir_name, input_name=None, status=0, client_agent="manual", download_id="", input_category=None, failure_link=None):
|
||||
|
||||
cfg = dict(core.CFG[section][input_category])
|
||||
|
@ -465,3 +335,132 @@ class Movie(object):
|
|||
"{0} does not appear to have changed status after {1} minutes, Please check your logs.".format(input_name, wait_for),
|
||||
section)
|
||||
return [1, "{0}: Failed to post-process - No change in status".format(section)]
|
||||
|
||||
def command_complete(self, url, params, headers, section):
|
||||
try:
|
||||
r = requests.get(url, params=params, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url), section)
|
||||
return None
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return r.json()['state']
|
||||
except (ValueError, KeyError):
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("{0} did not return expected json data.".format(section), section)
|
||||
return None
|
||||
|
||||
def completed_download_handling(self, url2, headers, section="MAIN"):
|
||||
try:
|
||||
r = requests.get(url2, params={}, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url2), section)
|
||||
return False
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
return r.json().get("enableCompletedDownloadHandling", False)
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
return False
|
||||
|
||||
def get_release(self, base_url, imdb_id=None, download_id=None, release_id=None):
|
||||
results = {}
|
||||
params = {}
|
||||
|
||||
# determine cmd and params to send to CouchPotato to get our results
|
||||
section = 'movies'
|
||||
cmd = "media.list"
|
||||
if release_id or imdb_id:
|
||||
section = 'media'
|
||||
cmd = "media.get"
|
||||
params['id'] = release_id or imdb_id
|
||||
|
||||
if not (release_id or imdb_id or download_id):
|
||||
logger.debug("No information available to filter CP results")
|
||||
return results
|
||||
|
||||
url = "{0}{1}".format(base_url, cmd)
|
||||
logger.debug("Opening URL: {0} with PARAMS: {1}".format(url, params))
|
||||
|
||||
try:
|
||||
r = requests.get(url, params=params, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL {0}".format(url))
|
||||
return results
|
||||
|
||||
try:
|
||||
result = r.json()
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("CouchPotato returned the following non-json data")
|
||||
for line in r.iter_lines():
|
||||
logger.error("{0}".format(line))
|
||||
return results
|
||||
|
||||
if not result['success']:
|
||||
if 'error' in result:
|
||||
logger.error('{0}'.format(result['error']))
|
||||
else:
|
||||
logger.error("no media found for id {0}".format(params['id']))
|
||||
return results
|
||||
|
||||
# Gather release info and return it back, no need to narrow results
|
||||
if release_id:
|
||||
try:
|
||||
id = result[section]['_id']
|
||||
results[id] = result[section]
|
||||
return results
|
||||
except:
|
||||
pass
|
||||
|
||||
# Gather release info and proceed with trying to narrow results to one release choice
|
||||
|
||||
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 releases:
|
||||
continue
|
||||
for release in releases:
|
||||
try:
|
||||
if release['status'] not in ['snatched', 'downloaded', 'done']:
|
||||
continue
|
||||
if download_id:
|
||||
if download_id.lower() != release['download_info']['id'].lower():
|
||||
continue
|
||||
|
||||
id = release['_id']
|
||||
results[id] = release
|
||||
results[id]['title'] = movie['title']
|
||||
except:
|
||||
continue
|
||||
|
||||
# Narrow results by removing old releases by comparing their last_edit field
|
||||
if len(results) > 1:
|
||||
for id1, x1 in results.items():
|
||||
for id2, x2 in results.items():
|
||||
try:
|
||||
if x2["last_edit"] > x1["last_edit"]:
|
||||
results.pop(id1)
|
||||
except:
|
||||
continue
|
||||
|
||||
# Search downloads on clients for a match to try and narrow our results down to 1
|
||||
if len(results) > 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
|
|
@ -8,94 +8,13 @@ import requests
|
|||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaSceneExceptions import process_all_exceptions
|
||||
from core.nzbToMediaUtil import convert_to_ascii, list_media_files, remote_dir, remove_dir, server_responding
|
||||
from core.scene_exceptions import process_all_exceptions
|
||||
from core.utils import convert_to_ascii, list_media_files, remote_dir, remove_dir, server_responding
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class Music(object):
|
||||
def command_complete(self, url, params, headers, section):
|
||||
try:
|
||||
r = requests.get(url, params=params, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url), section)
|
||||
return None
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return r.json()['state']
|
||||
except (ValueError, KeyError):
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("{0} did not return expected json data.".format(section), section)
|
||||
return None
|
||||
|
||||
def get_status(self, url, apikey, dir_name):
|
||||
logger.debug("Attempting to get current status for release:{0}".format(os.path.basename(dir_name)))
|
||||
|
||||
params = {
|
||||
'apikey': apikey,
|
||||
'cmd': "getHistory"
|
||||
}
|
||||
|
||||
logger.debug("Opening URL: {0} with PARAMS: {1}".format(url, params))
|
||||
|
||||
try:
|
||||
r = requests.get(url, params=params, verify=False, timeout=(30, 120))
|
||||
except requests.RequestException:
|
||||
logger.error("Unable to open URL")
|
||||
return None
|
||||
|
||||
try:
|
||||
result = r.json()
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
return None
|
||||
|
||||
for album in result:
|
||||
if os.path.basename(dir_name) == album['FolderName']:
|
||||
return album["Status"].lower()
|
||||
|
||||
def force_process(self, params, url, apikey, input_name, dir_name, section, wait_for):
|
||||
release_status = self.get_status(url, apikey, dir_name)
|
||||
if not release_status:
|
||||
logger.error("Could not find a status for {0}, is it in the wanted list ?".format(input_name), section)
|
||||
|
||||
logger.debug("Opening URL: {0} with PARAMS: {1}".format(url, params), section)
|
||||
|
||||
try:
|
||||
r = requests.get(url, params=params, verify=False, timeout=(30, 300))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL {0}".format(url), section)
|
||||
return [1, "{0}: Failed to post-process - Unable to connect to {1}".format(section, section)]
|
||||
|
||||
logger.debug("Result: {0}".format(r.text), section)
|
||||
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return [1, "{0}: Failed to post-process - Server returned status {1}".format(section, r.status_code)]
|
||||
elif r.text == "OK":
|
||||
logger.postprocess("SUCCESS: Post-Processing started for {0} in folder {1} ...".format(input_name, dir_name), section)
|
||||
else:
|
||||
logger.error("FAILED: Post-Processing has NOT started for {0} in folder {1}. exiting!".format(input_name, dir_name), section)
|
||||
return [1, "{0}: Failed to post-process - Returned log from {1} was not as expected.".format(section, section)]
|
||||
|
||||
# we will now wait for this album to be processed before returning to TorrentToMedia and unpausing.
|
||||
timeout = time.time() + 60 * wait_for
|
||||
while time.time() < timeout:
|
||||
current_status = self.get_status(url, apikey, dir_name)
|
||||
if current_status is not None and current_status != release_status: # Something has changed. CPS must have processed this movie.
|
||||
logger.postprocess("SUCCESS: This release is now marked as status [{0}]".format(current_status), section)
|
||||
return [0, "{0}: Successfully post-processed {1}".format(section, input_name)]
|
||||
if not os.path.isdir(dir_name):
|
||||
logger.postprocess("SUCCESS: The input directory {0} has been removed Processing must have finished.".format(dir_name), section)
|
||||
return [0, "{0}: Successfully post-processed {1}".format(section, input_name)]
|
||||
time.sleep(10 * wait_for)
|
||||
# The status hasn't changed.
|
||||
return [2, "no change"]
|
||||
|
||||
def process(self, section, dir_name, input_name=None, status=0, client_agent="manual", input_category=None):
|
||||
status = int(status)
|
||||
|
||||
|
@ -236,4 +155,85 @@ class Music(object):
|
|||
if delete_failed and os.path.isdir(dir_name) and not os.path.dirname(dir_name) == dir_name:
|
||||
logger.postprocess("Deleting failed files and folder {0}".format(dir_name), section)
|
||||
remove_dir(dir_name)
|
||||
return [1, "{0}: Failed to post-process. {1} does not support failed downloads".format(section, section)] # Return as failed to flag this in the downloader.
|
||||
return [1, "{0}: Failed to post-process. {1} does not support failed downloads".format(section, section)] # Return as failed to flag this in the downloader.
|
||||
|
||||
def command_complete(self, url, params, headers, section):
|
||||
try:
|
||||
r = requests.get(url, params=params, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url), section)
|
||||
return None
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return r.json()['state']
|
||||
except (ValueError, KeyError):
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("{0} did not return expected json data.".format(section), section)
|
||||
return None
|
||||
|
||||
def get_status(self, url, apikey, dir_name):
|
||||
logger.debug("Attempting to get current status for release:{0}".format(os.path.basename(dir_name)))
|
||||
|
||||
params = {
|
||||
'apikey': apikey,
|
||||
'cmd': "getHistory"
|
||||
}
|
||||
|
||||
logger.debug("Opening URL: {0} with PARAMS: {1}".format(url, params))
|
||||
|
||||
try:
|
||||
r = requests.get(url, params=params, verify=False, timeout=(30, 120))
|
||||
except requests.RequestException:
|
||||
logger.error("Unable to open URL")
|
||||
return None
|
||||
|
||||
try:
|
||||
result = r.json()
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
return None
|
||||
|
||||
for album in result:
|
||||
if os.path.basename(dir_name) == album['FolderName']:
|
||||
return album["Status"].lower()
|
||||
|
||||
def force_process(self, params, url, apikey, input_name, dir_name, section, wait_for):
|
||||
release_status = self.get_status(url, apikey, dir_name)
|
||||
if not release_status:
|
||||
logger.error("Could not find a status for {0}, is it in the wanted list ?".format(input_name), section)
|
||||
|
||||
logger.debug("Opening URL: {0} with PARAMS: {1}".format(url, params), section)
|
||||
|
||||
try:
|
||||
r = requests.get(url, params=params, verify=False, timeout=(30, 300))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL {0}".format(url), section)
|
||||
return [1, "{0}: Failed to post-process - Unable to connect to {1}".format(section, section)]
|
||||
|
||||
logger.debug("Result: {0}".format(r.text), section)
|
||||
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return [1, "{0}: Failed to post-process - Server returned status {1}".format(section, r.status_code)]
|
||||
elif r.text == "OK":
|
||||
logger.postprocess("SUCCESS: Post-Processing started for {0} in folder {1} ...".format(input_name, dir_name), section)
|
||||
else:
|
||||
logger.error("FAILED: Post-Processing has NOT started for {0} in folder {1}. exiting!".format(input_name, dir_name), section)
|
||||
return [1, "{0}: Failed to post-process - Returned log from {1} was not as expected.".format(section, section)]
|
||||
|
||||
# we will now wait for this album to be processed before returning to TorrentToMedia and unpausing.
|
||||
timeout = time.time() + 60 * wait_for
|
||||
while time.time() < timeout:
|
||||
current_status = self.get_status(url, apikey, dir_name)
|
||||
if current_status is not None and current_status != release_status: # Something has changed. CPS must have processed this movie.
|
||||
logger.postprocess("SUCCESS: This release is now marked as status [{0}]".format(current_status), section)
|
||||
return [0, "{0}: Successfully post-processed {1}".format(section, input_name)]
|
||||
if not os.path.isdir(dir_name):
|
||||
logger.postprocess("SUCCESS: The input directory {0} has been removed Processing must have finished.".format(dir_name), section)
|
||||
return [0, "{0}: Successfully post-processed {1}".format(section, input_name)]
|
||||
time.sleep(10 * wait_for)
|
||||
# The status hasn't changed.
|
||||
return [2, "no change"]
|
|
@ -9,50 +9,16 @@ import time
|
|||
import requests
|
||||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaAutoFork import auto_fork
|
||||
from core.nzbToMediaSceneExceptions import process_all_exceptions
|
||||
from core.nzbToMediaUtil import convert_to_ascii, flatten, import_subs, list_media_files, remote_dir, report_nzb, remove_dir, server_responding
|
||||
from core.transcoder import transcoder
|
||||
from core import logger, transcoder
|
||||
from core.forks import auto_fork
|
||||
from core.scene_exceptions import process_all_exceptions
|
||||
from core.utils import convert_to_ascii, flatten, import_subs, list_media_files, remote_dir, remove_dir, report_nzb, server_responding
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class TV(object):
|
||||
def command_complete(self, url, params, headers, section):
|
||||
try:
|
||||
r = requests.get(url, params=params, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url), section)
|
||||
return None
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return r.json()['state']
|
||||
except (ValueError, KeyError):
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("{0} did not return expected json data.".format(section), section)
|
||||
return None
|
||||
|
||||
def completed_download_handling(self, url2, headers, section="MAIN"):
|
||||
try:
|
||||
r = requests.get(url2, params={}, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url2), section)
|
||||
return False
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
return r.json().get("enableCompletedDownloadHandling", False)
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
return False
|
||||
|
||||
def process_episode(self, section, dir_name, input_name=None, failed=False, client_agent="manual", download_id=None, input_category=None, failure_link=None):
|
||||
def process(self, section, dir_name, input_name=None, failed=False, client_agent="manual", download_id=None, input_category=None, failure_link=None):
|
||||
|
||||
cfg = dict(core.CFG[section][input_category])
|
||||
|
||||
|
@ -373,3 +339,36 @@ class TV(object):
|
|||
return [1, "{0}: Failed to post-process {1}".format(section, input_name)]
|
||||
else:
|
||||
return [1, "{0}: Failed to post-process - Returned log from {1} was not as expected.".format(section, section)] # We did not receive Success confirmation.
|
||||
|
||||
def command_complete(self, url, params, headers, section):
|
||||
try:
|
||||
r = requests.get(url, params=params, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url), section)
|
||||
return None
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return r.json()['state']
|
||||
except (ValueError, KeyError):
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
logger.error("{0} did not return expected json data.".format(section), section)
|
||||
return None
|
||||
|
||||
def completed_download_handling(self, url2, headers, section="MAIN"):
|
||||
try:
|
||||
r = requests.get(url2, params={}, headers=headers, stream=True, verify=False, timeout=(30, 60))
|
||||
except requests.ConnectionError:
|
||||
logger.error("Unable to open URL: {0}".format(url2), section)
|
||||
return False
|
||||
if r.status_code not in [requests.codes.ok, requests.codes.created, requests.codes.accepted]:
|
||||
logger.error("Server returned status {0}".format(r.status_code), section)
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
return r.json().get("enableCompletedDownloadHandling", False)
|
||||
except ValueError:
|
||||
# ValueError catches simplejson's JSONDecodeError and json's ValueError
|
||||
return False
|
|
@ -1,7 +1,7 @@
|
|||
# coding=utf-8
|
||||
|
||||
from core import logger, nzbToMediaDB
|
||||
from core.nzbToMediaUtil import backup_versioned_file
|
||||
from core import logger, main_db
|
||||
from core.utils import backup_versioned_file
|
||||
|
||||
MIN_DB_VERSION = 1 # oldest db version we support migrating from
|
||||
MAX_DB_VERSION = 2
|
||||
|
@ -9,7 +9,7 @@ MAX_DB_VERSION = 2
|
|||
|
||||
def backup_database(version):
|
||||
logger.info("Backing up database before upgrade")
|
||||
if not backup_versioned_file(nzbToMediaDB.db_filename(), version):
|
||||
if not backup_versioned_file(main_db.db_filename(), version):
|
||||
logger.log_error_and_exit("Database backup failed, abort upgrading database")
|
||||
else:
|
||||
logger.info("Proceeding with upgrade")
|
||||
|
@ -20,7 +20,7 @@ def backup_database(version):
|
|||
# ======================
|
||||
# Add new migrations at the bottom of the list; subclass the previous migration.
|
||||
|
||||
class InitialSchema(nzbToMediaDB.SchemaUpgrade):
|
||||
class InitialSchema(main_db.SchemaUpgrade):
|
||||
def test(self):
|
||||
no_update = False
|
||||
if self.has_table("db_version"):
|
|
@ -1 +0,0 @@
|
|||
# coding=utf-8
|
|
@ -1 +1,181 @@
|
|||
# coding=utf-8
|
||||
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
from subprocess import Popen, call
|
||||
from time import sleep
|
||||
|
||||
import core
|
||||
|
||||
|
||||
def extract(file_path, output_destination):
|
||||
success = 0
|
||||
# Using Windows
|
||||
if platform.system() == 'Windows':
|
||||
if not os.path.exists(core.SEVENZIP):
|
||||
core.logger.error("EXTRACTOR: Could not find 7-zip, Exiting")
|
||||
return False
|
||||
wscriptlocation = os.path.join(os.environ['WINDIR'], 'system32', 'wscript.exe')
|
||||
invislocation = os.path.join(core.PROGRAM_DIR, 'core', 'extractor', 'bin', 'invisible.vbs')
|
||||
cmd_7zip = [wscriptlocation, invislocation, str(core.SHOWEXTRACT), core.SEVENZIP, "x", "-y"]
|
||||
ext_7zip = [".rar", ".zip", ".tar.gz", "tgz", ".tar.bz2", ".tbz", ".tar.lzma", ".tlz", ".7z", ".xz"]
|
||||
extract_commands = dict.fromkeys(ext_7zip, cmd_7zip)
|
||||
# Using unix
|
||||
else:
|
||||
required_cmds = ["unrar", "unzip", "tar", "unxz", "unlzma", "7zr", "bunzip2"]
|
||||
# ## Possible future suport:
|
||||
# gunzip: gz (cmd will delete original archive)
|
||||
# ## the following do not extract to dest dir
|
||||
# ".xz": ["xz", "-d --keep"],
|
||||
# ".lzma": ["xz", "-d --format=lzma --keep"],
|
||||
# ".bz2": ["bzip2", "-d --keep"],
|
||||
|
||||
extract_commands = {
|
||||
".rar": ["unrar", "x", "-o+", "-y"],
|
||||
".tar": ["tar", "-xf"],
|
||||
".zip": ["unzip"],
|
||||
".tar.gz": ["tar", "-xzf"], ".tgz": ["tar", "-xzf"],
|
||||
".tar.bz2": ["tar", "-xjf"], ".tbz": ["tar", "-xjf"],
|
||||
".tar.lzma": ["tar", "--lzma", "-xf"], ".tlz": ["tar", "--lzma", "-xf"],
|
||||
".tar.xz": ["tar", "--xz", "-xf"], ".txz": ["tar", "--xz", "-xf"],
|
||||
".7z": ["7zr", "x"],
|
||||
}
|
||||
# Test command exists and if not, remove
|
||||
if not os.getenv('TR_TORRENT_DIR'):
|
||||
devnull = open(os.devnull, 'w')
|
||||
for cmd in required_cmds:
|
||||
if call(['which', cmd], stdout=devnull,
|
||||
stderr=devnull): # note, returns 0 if exists, or 1 if doesn't exist.
|
||||
for k, v in extract_commands.items():
|
||||
if cmd in v[0]:
|
||||
if not call(["which", "7zr"], stdout=devnull, stderr=devnull): # we do have "7zr"
|
||||
extract_commands[k] = ["7zr", "x", "-y"]
|
||||
elif not call(["which", "7z"], stdout=devnull, stderr=devnull): # we do have "7z"
|
||||
extract_commands[k] = ["7z", "x", "-y"]
|
||||
elif not call(["which", "7za"], stdout=devnull, stderr=devnull): # we do have "7za"
|
||||
extract_commands[k] = ["7za", "x", "-y"]
|
||||
else:
|
||||
core.logger.error("EXTRACTOR: {cmd} not found, "
|
||||
"disabling support for {feature}".format
|
||||
(cmd=cmd, feature=k))
|
||||
del extract_commands[k]
|
||||
devnull.close()
|
||||
else:
|
||||
core.logger.warning("EXTRACTOR: Cannot determine which tool to use when called from Transmission")
|
||||
|
||||
if not extract_commands:
|
||||
core.logger.warning("EXTRACTOR: No archive extracting programs found, plugin will be disabled")
|
||||
|
||||
ext = os.path.splitext(file_path)
|
||||
cmd = []
|
||||
if ext[1] in (".gz", ".bz2", ".lzma"):
|
||||
# Check if this is a tar
|
||||
if os.path.splitext(ext[0])[1] == ".tar":
|
||||
cmd = extract_commands[".tar{ext}".format(ext=ext[1])]
|
||||
elif ext[1] in (".1", ".01", ".001") and os.path.splitext(ext[0])[1] in (".rar", ".zip", ".7z"):
|
||||
cmd = extract_commands[os.path.splitext(ext[0])[1]]
|
||||
elif ext[1] in (".cb7", ".cba", ".cbr", ".cbt", ".cbz"): # don't extract these comic book archives.
|
||||
return False
|
||||
else:
|
||||
if ext[1] in extract_commands:
|
||||
cmd = extract_commands[ext[1]]
|
||||
else:
|
||||
core.logger.debug("EXTRACTOR: Unknown file type: {ext}".format
|
||||
(ext=ext[1]))
|
||||
return False
|
||||
|
||||
# Create outputDestination folder
|
||||
core.make_dir(output_destination)
|
||||
|
||||
if core.PASSWORDSFILE and os.path.isfile(os.path.normpath(core.PASSWORDSFILE)):
|
||||
passwords = [line.strip() for line in open(os.path.normpath(core.PASSWORDSFILE))]
|
||||
else:
|
||||
passwords = []
|
||||
|
||||
core.logger.info("Extracting {file} to {destination}".format
|
||||
(file=file_path, destination=output_destination))
|
||||
core.logger.debug("Extracting {cmd} {file} {destination}".format
|
||||
(cmd=cmd, file=file_path, destination=output_destination))
|
||||
|
||||
orig_files = []
|
||||
orig_dirs = []
|
||||
for dir, subdirs, files in os.walk(output_destination):
|
||||
for subdir in subdirs:
|
||||
orig_dirs.append(os.path.join(dir, subdir))
|
||||
for file in files:
|
||||
orig_files.append(os.path.join(dir, file))
|
||||
|
||||
pwd = os.getcwd() # Get our Present Working Directory
|
||||
os.chdir(output_destination) # Not all unpack commands accept full paths, so just extract into this directory
|
||||
devnull = open(os.devnull, 'w')
|
||||
|
||||
try: # now works same for nt and *nix
|
||||
info = None
|
||||
cmd.append(file_path) # add filePath to final cmd arg.
|
||||
if platform.system() == 'Windows':
|
||||
info = subprocess.STARTUPINFO()
|
||||
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
else:
|
||||
cmd = core.NICENESS + cmd
|
||||
cmd2 = cmd
|
||||
cmd2.append("-p-") # don't prompt for password.
|
||||
p = Popen(cmd2, stdout=devnull, stderr=devnull, startupinfo=info) # should extract files fine.
|
||||
res = p.wait()
|
||||
if res == 0: # Both Linux and Windows return 0 for successful.
|
||||
core.logger.info("EXTRACTOR: Extraction was successful for {file} to {destination}".format
|
||||
(file=file_path, destination=output_destination))
|
||||
success = 1
|
||||
elif len(passwords) > 0:
|
||||
core.logger.info("EXTRACTOR: Attempting to extract with passwords")
|
||||
for password in passwords:
|
||||
if password == "": # if edited in windows or otherwise if blank lines.
|
||||
continue
|
||||
cmd2 = cmd
|
||||
# append password here.
|
||||
passcmd = "-p{pwd}".format(pwd=password)
|
||||
cmd2.append(passcmd)
|
||||
p = Popen(cmd2, stdout=devnull, stderr=devnull, startupinfo=info) # should extract files fine.
|
||||
res = p.wait()
|
||||
if (res >= 0 and platform == 'Windows') or res == 0:
|
||||
core.logger.info("EXTRACTOR: Extraction was successful "
|
||||
"for {file} to {destination} using password: {pwd}".format
|
||||
(file=file_path, destination=output_destination, pwd=password))
|
||||
success = 1
|
||||
break
|
||||
else:
|
||||
continue
|
||||
except:
|
||||
core.logger.error("EXTRACTOR: Extraction failed for {file}. "
|
||||
"Could not call command {cmd}".format
|
||||
(file=file_path, cmd=cmd))
|
||||
os.chdir(pwd)
|
||||
return False
|
||||
|
||||
devnull.close()
|
||||
os.chdir(pwd) # Go back to our Original Working Directory
|
||||
if success:
|
||||
# sleep to let files finish writing to disk
|
||||
sleep(3)
|
||||
perms = stat.S_IMODE(os.lstat(os.path.split(file_path)[0]).st_mode)
|
||||
for dir, subdirs, files in os.walk(output_destination):
|
||||
for subdir in subdirs:
|
||||
if not os.path.join(dir, subdir) in orig_files:
|
||||
try:
|
||||
os.chmod(os.path.join(dir, subdir), perms)
|
||||
except:
|
||||
pass
|
||||
for file in files:
|
||||
if not os.path.join(dir, file) in orig_files:
|
||||
try:
|
||||
shutil.copymode(file_path, os.path.join(dir, file))
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
else:
|
||||
core.logger.error("EXTRACTOR: Extraction failed for {file}. "
|
||||
"Result was {result}".format
|
||||
(file=file_path, result=res))
|
||||
return False
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
# coding=utf-8
|
||||
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
from subprocess import Popen, call
|
||||
from time import sleep
|
||||
|
||||
import core
|
||||
|
||||
|
||||
def extract(file_path, output_destination):
|
||||
success = 0
|
||||
# Using Windows
|
||||
if platform.system() == 'Windows':
|
||||
if not os.path.exists(core.SEVENZIP):
|
||||
core.logger.error("EXTRACTOR: Could not find 7-zip, Exiting")
|
||||
return False
|
||||
wscriptlocation = os.path.join(os.environ['WINDIR'], 'system32', 'wscript.exe')
|
||||
invislocation = os.path.join(core.PROGRAM_DIR, 'core', 'extractor', 'bin', 'invisible.vbs')
|
||||
cmd_7zip = [wscriptlocation, invislocation, str(core.SHOWEXTRACT), core.SEVENZIP, "x", "-y"]
|
||||
ext_7zip = [".rar", ".zip", ".tar.gz", "tgz", ".tar.bz2", ".tbz", ".tar.lzma", ".tlz", ".7z", ".xz"]
|
||||
extract_commands = dict.fromkeys(ext_7zip, cmd_7zip)
|
||||
# Using unix
|
||||
else:
|
||||
required_cmds = ["unrar", "unzip", "tar", "unxz", "unlzma", "7zr", "bunzip2"]
|
||||
# ## Possible future suport:
|
||||
# gunzip: gz (cmd will delete original archive)
|
||||
# ## the following do not extract to dest dir
|
||||
# ".xz": ["xz", "-d --keep"],
|
||||
# ".lzma": ["xz", "-d --format=lzma --keep"],
|
||||
# ".bz2": ["bzip2", "-d --keep"],
|
||||
|
||||
extract_commands = {
|
||||
".rar": ["unrar", "x", "-o+", "-y"],
|
||||
".tar": ["tar", "-xf"],
|
||||
".zip": ["unzip"],
|
||||
".tar.gz": ["tar", "-xzf"], ".tgz": ["tar", "-xzf"],
|
||||
".tar.bz2": ["tar", "-xjf"], ".tbz": ["tar", "-xjf"],
|
||||
".tar.lzma": ["tar", "--lzma", "-xf"], ".tlz": ["tar", "--lzma", "-xf"],
|
||||
".tar.xz": ["tar", "--xz", "-xf"], ".txz": ["tar", "--xz", "-xf"],
|
||||
".7z": ["7zr", "x"],
|
||||
}
|
||||
# Test command exists and if not, remove
|
||||
if not os.getenv('TR_TORRENT_DIR'):
|
||||
devnull = open(os.devnull, 'w')
|
||||
for cmd in required_cmds:
|
||||
if call(['which', cmd], stdout=devnull,
|
||||
stderr=devnull): # note, returns 0 if exists, or 1 if doesn't exist.
|
||||
for k, v in extract_commands.items():
|
||||
if cmd in v[0]:
|
||||
if not call(["which", "7zr"], stdout=devnull, stderr=devnull): # we do have "7zr"
|
||||
extract_commands[k] = ["7zr", "x", "-y"]
|
||||
elif not call(["which", "7z"], stdout=devnull, stderr=devnull): # we do have "7z"
|
||||
extract_commands[k] = ["7z", "x", "-y"]
|
||||
elif not call(["which", "7za"], stdout=devnull, stderr=devnull): # we do have "7za"
|
||||
extract_commands[k] = ["7za", "x", "-y"]
|
||||
else:
|
||||
core.logger.error("EXTRACTOR: {cmd} not found, "
|
||||
"disabling support for {feature}".format
|
||||
(cmd=cmd, feature=k))
|
||||
del extract_commands[k]
|
||||
devnull.close()
|
||||
else:
|
||||
core.logger.warning("EXTRACTOR: Cannot determine which tool to use when called from Transmission")
|
||||
|
||||
if not extract_commands:
|
||||
core.logger.warning("EXTRACTOR: No archive extracting programs found, plugin will be disabled")
|
||||
|
||||
ext = os.path.splitext(file_path)
|
||||
cmd = []
|
||||
if ext[1] in (".gz", ".bz2", ".lzma"):
|
||||
# Check if this is a tar
|
||||
if os.path.splitext(ext[0])[1] == ".tar":
|
||||
cmd = extract_commands[".tar{ext}".format(ext=ext[1])]
|
||||
elif ext[1] in (".1", ".01", ".001") and os.path.splitext(ext[0])[1] in (".rar", ".zip", ".7z"):
|
||||
cmd = extract_commands[os.path.splitext(ext[0])[1]]
|
||||
elif ext[1] in (".cb7", ".cba", ".cbr", ".cbt", ".cbz"): # don't extract these comic book archives.
|
||||
return False
|
||||
else:
|
||||
if ext[1] in extract_commands:
|
||||
cmd = extract_commands[ext[1]]
|
||||
else:
|
||||
core.logger.debug("EXTRACTOR: Unknown file type: {ext}".format
|
||||
(ext=ext[1]))
|
||||
return False
|
||||
|
||||
# Create outputDestination folder
|
||||
core.make_dir(output_destination)
|
||||
|
||||
if core.PASSWORDSFILE and os.path.isfile(os.path.normpath(core.PASSWORDSFILE)):
|
||||
passwords = [line.strip() for line in open(os.path.normpath(core.PASSWORDSFILE))]
|
||||
else:
|
||||
passwords = []
|
||||
|
||||
core.logger.info("Extracting {file} to {destination}".format
|
||||
(file=file_path, destination=output_destination))
|
||||
core.logger.debug("Extracting {cmd} {file} {destination}".format
|
||||
(cmd=cmd, file=file_path, destination=output_destination))
|
||||
|
||||
orig_files = []
|
||||
orig_dirs = []
|
||||
for dir, subdirs, files in os.walk(output_destination):
|
||||
for subdir in subdirs:
|
||||
orig_dirs.append(os.path.join(dir, subdir))
|
||||
for file in files:
|
||||
orig_files.append(os.path.join(dir, file))
|
||||
|
||||
pwd = os.getcwd() # Get our Present Working Directory
|
||||
os.chdir(output_destination) # Not all unpack commands accept full paths, so just extract into this directory
|
||||
devnull = open(os.devnull, 'w')
|
||||
|
||||
try: # now works same for nt and *nix
|
||||
info = None
|
||||
cmd.append(file_path) # add filePath to final cmd arg.
|
||||
if platform.system() == 'Windows':
|
||||
info = subprocess.STARTUPINFO()
|
||||
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
else:
|
||||
cmd = core.NICENESS + cmd
|
||||
cmd2 = cmd
|
||||
cmd2.append("-p-") # don't prompt for password.
|
||||
p = Popen(cmd2, stdout=devnull, stderr=devnull, startupinfo=info) # should extract files fine.
|
||||
res = p.wait()
|
||||
if res == 0: # Both Linux and Windows return 0 for successful.
|
||||
core.logger.info("EXTRACTOR: Extraction was successful for {file} to {destination}".format
|
||||
(file=file_path, destination=output_destination))
|
||||
success = 1
|
||||
elif len(passwords) > 0:
|
||||
core.logger.info("EXTRACTOR: Attempting to extract with passwords")
|
||||
for password in passwords:
|
||||
if password == "": # if edited in windows or otherwise if blank lines.
|
||||
continue
|
||||
cmd2 = cmd
|
||||
# append password here.
|
||||
passcmd = "-p{pwd}".format(pwd=password)
|
||||
cmd2.append(passcmd)
|
||||
p = Popen(cmd2, stdout=devnull, stderr=devnull, startupinfo=info) # should extract files fine.
|
||||
res = p.wait()
|
||||
if (res >= 0 and platform == 'Windows') or res == 0:
|
||||
core.logger.info("EXTRACTOR: Extraction was successful "
|
||||
"for {file} to {destination} using password: {pwd}".format
|
||||
(file=file_path, destination=output_destination, pwd=password))
|
||||
success = 1
|
||||
break
|
||||
else:
|
||||
continue
|
||||
except:
|
||||
core.logger.error("EXTRACTOR: Extraction failed for {file}. "
|
||||
"Could not call command {cmd}".format
|
||||
(file=file_path, cmd=cmd))
|
||||
os.chdir(pwd)
|
||||
return False
|
||||
|
||||
devnull.close()
|
||||
os.chdir(pwd) # Go back to our Original Working Directory
|
||||
if success:
|
||||
# sleep to let files finish writing to disk
|
||||
sleep(3)
|
||||
perms = stat.S_IMODE(os.lstat(os.path.split(file_path)[0]).st_mode)
|
||||
for dir, subdirs, files in os.walk(output_destination):
|
||||
for subdir in subdirs:
|
||||
if not os.path.join(dir, subdir) in orig_files:
|
||||
try:
|
||||
os.chmod(os.path.join(dir, subdir), perms)
|
||||
except:
|
||||
pass
|
||||
for file in files:
|
||||
if not os.path.join(dir, file) in orig_files:
|
||||
try:
|
||||
shutil.copymode(file_path, os.path.join(dir, file))
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
else:
|
||||
core.logger.error("EXTRACTOR: Extraction failed for {file}. "
|
||||
"Result was {result}".format
|
||||
(file=file_path, result=res))
|
||||
return False
|
|
@ -8,7 +8,7 @@ import subprocess
|
|||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaUtil import list_media_files
|
||||
from core.utils import list_media_files
|
||||
|
||||
reverse_list = [r"\.\d{2}e\d{2}s\.", r"\.[pi]0801\.", r"\.p027\.", r"\.[pi]675\.", r"\.[pi]084\.", r"\.p063\.",
|
||||
r"\b[45]62[xh]\.", r"\.yarulb\.", r"\.vtd[hp]\.",
|
|
@ -9,11 +9,13 @@ import shutil
|
|||
import subprocess
|
||||
|
||||
from babelfish import Language
|
||||
from six import iteritems, text_type, string_types
|
||||
from six import iteritems, string_types, text_type
|
||||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaUtil import make_dir
|
||||
from core.utils import make_dir
|
||||
|
||||
__author__ = 'Justin'
|
||||
|
||||
|
||||
def is_video_good(videofile, status):
|
|
@ -1,2 +0,0 @@
|
|||
# coding=utf-8
|
||||
__author__ = 'Justin'
|
|
@ -4,9 +4,8 @@ import os
|
|||
from subprocess import Popen
|
||||
|
||||
import core
|
||||
from core import logger
|
||||
from core.nzbToMediaUtil import import_subs, list_media_files, remove_dir
|
||||
from core.transcoder import transcoder
|
||||
from core import logger, transcoder
|
||||
from core.utils import import_subs, list_media_files, remove_dir
|
||||
|
||||
|
||||
def external_script(output_destination, torrent_name, torrent_label, settings):
|
|
@ -3,31 +3,43 @@
|
|||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import datetime
|
||||
from functools import partial
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import socket
|
||||
import stat
|
||||
import struct
|
||||
import time
|
||||
from functools import partial
|
||||
|
||||
from babelfish import Language
|
||||
import beets
|
||||
import guessit
|
||||
import linktastic
|
||||
import requests
|
||||
import subliminal
|
||||
from babelfish import Language
|
||||
from qbittorrent import Client as qBittorrentClient
|
||||
import requests
|
||||
from six import text_type
|
||||
import subliminal
|
||||
from synchronousdeluge.client import DelugeClient
|
||||
from transmissionrpc.client import Client as TransmissionClient
|
||||
from utorrent.client import UTorrentClient
|
||||
|
||||
import core
|
||||
from core import logger, nzbToMediaDB
|
||||
from core.extractor import extractor
|
||||
from core import extractor, logger, main_db
|
||||
|
||||
try:
|
||||
from win32event import CreateMutex
|
||||
from win32api import CloseHandle, GetLastError
|
||||
from winerror import ERROR_ALREADY_EXISTS
|
||||
except ImportError:
|
||||
if os.name == 'nt':
|
||||
raise
|
||||
|
||||
try:
|
||||
import jaraco
|
||||
except ImportError:
|
||||
if os.name == 'nt':
|
||||
raise
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
@ -286,7 +298,6 @@ def replace_links(link):
|
|||
n = 0
|
||||
target = link
|
||||
if os.name == 'nt':
|
||||
import jaraco
|
||||
if not jaraco.windows.filesystem.islink(link):
|
||||
logger.debug('{0} is not a link'.format(link))
|
||||
return
|
||||
|
@ -1284,7 +1295,7 @@ def backup_versioned_file(old_file, version):
|
|||
def update_download_info_status(input_name, status):
|
||||
logger.db("Updating status of our download {0} in the DB to {1}".format(input_name, status))
|
||||
|
||||
my_db = nzbToMediaDB.DBConnection()
|
||||
my_db = main_db.DBConnection()
|
||||
my_db.action("UPDATE downloads SET status=?, last_update=? WHERE input_name=?",
|
||||
[status, datetime.date.today().toordinal(), text_type(input_name)])
|
||||
|
||||
|
@ -1292,47 +1303,20 @@ def update_download_info_status(input_name, status):
|
|||
def get_download_info(input_name, status):
|
||||
logger.db("Getting download info for {0} from the DB".format(input_name))
|
||||
|
||||
my_db = nzbToMediaDB.DBConnection()
|
||||
my_db = main_db.DBConnection()
|
||||
sql_results = my_db.select("SELECT * FROM downloads WHERE input_name=? AND status=?",
|
||||
[text_type(input_name), status])
|
||||
|
||||
return sql_results
|
||||
|
||||
|
||||
class RunningProcess(object):
|
||||
""" Limits application to single instance """
|
||||
|
||||
def __init__(self):
|
||||
if platform.system() == 'Windows':
|
||||
self.process = WindowsProcess()
|
||||
else:
|
||||
self.process = PosixProcess()
|
||||
|
||||
def alreadyrunning(self):
|
||||
return self.process.alreadyrunning()
|
||||
|
||||
# def __del__(self):
|
||||
# self.process.__del__()
|
||||
|
||||
|
||||
class WindowsProcess(object):
|
||||
def __init__(self):
|
||||
self.mutex = None
|
||||
self.mutexname = "nzbtomedia_{pid}".format(pid=core.PID_FILE.replace('\\', '/')) # {D0E858DF-985E-4907-B7FB-8D732C3FC3B9}"
|
||||
if platform.system() == 'Windows':
|
||||
try:
|
||||
from win32.win32event import CreateMutex
|
||||
from win32.win32api import CloseHandle, GetLastError
|
||||
from win32.lib.winerror import ERROR_ALREADY_EXISTS
|
||||
except ImportError:
|
||||
from win32event import CreateMutex
|
||||
from win32api import CloseHandle, GetLastError
|
||||
from winerror import ERROR_ALREADY_EXISTS
|
||||
|
||||
self.CreateMutex = CreateMutex
|
||||
self.CloseHandle = CloseHandle
|
||||
self.GetLastError = GetLastError
|
||||
self.ERROR_ALREADY_EXISTS = ERROR_ALREADY_EXISTS
|
||||
self.CreateMutex = CreateMutex
|
||||
self.CloseHandle = CloseHandle
|
||||
self.GetLastError = GetLastError
|
||||
self.ERROR_ALREADY_EXISTS = ERROR_ALREADY_EXISTS
|
||||
|
||||
def alreadyrunning(self):
|
||||
self.mutex = self.CreateMutex(None, 0, self.mutexname)
|
||||
|
@ -1400,3 +1384,8 @@ class PosixProcess(object):
|
|||
self.lock_socket.close()
|
||||
if os.path.isfile(self.pidpath):
|
||||
os.unlink(self.pidpath)
|
||||
|
||||
if os.name == 'nt':
|
||||
RunningProcess = WindowsProcess
|
||||
else:
|
||||
RunningProcess = PosixProcess
|
|
@ -14,7 +14,7 @@ import traceback
|
|||
from six.moves.urllib.request import urlretrieve
|
||||
|
||||
import core
|
||||
from core import gh_api as github, logger
|
||||
from core import github_api as github, logger
|
||||
|
||||
|
||||
class CheckVersion(object):
|
|
@ -628,14 +628,10 @@ import os
|
|||
import sys
|
||||
|
||||
import core
|
||||
from core import logger, nzbToMediaDB
|
||||
from core.autoProcess.autoProcessComics import Comic
|
||||
from core.autoProcess.autoProcessGames import Game
|
||||
from core.autoProcess.autoProcessMovie import Movie
|
||||
from core.autoProcess.autoProcessMusic import Music
|
||||
from core.autoProcess.autoProcessTV import TV
|
||||
from core.nzbToMediaUserScript import external_script
|
||||
from core.nzbToMediaUtil import char_replace, clean_dir, convert_to_ascii, extract_files, get_dirs, get_download_info, get_nzoid, plex_update, update_download_info_status
|
||||
from core import logger, main_db
|
||||
from core.auto_process import Comic, Game, Movie, Music, TV
|
||||
from core.user_scripts import external_script
|
||||
from core.utils import char_replace, clean_dir, convert_to_ascii, extract_files, get_dirs, get_download_info, get_nzoid, plex_update, update_download_info_status
|
||||
|
||||
try:
|
||||
text_type = unicode
|
||||
|
@ -657,7 +653,7 @@ def process(input_directory, input_name=None, status=0, client_agent='manual', d
|
|||
if client_agent != 'manual' and not core.DOWNLOADINFO:
|
||||
logger.debug('Adding NZB download info for directory {0} to database'.format(input_directory))
|
||||
|
||||
my_db = nzbToMediaDB.DBConnection()
|
||||
my_db = main_db.DBConnection()
|
||||
|
||||
input_directory1 = input_directory
|
||||
input_name1 = input_name
|
||||
|
@ -732,13 +728,13 @@ def process(input_directory, input_name=None, status=0, client_agent='manual', d
|
|||
result = Movie().process(section_name, input_directory, input_name, status, client_agent, download_id,
|
||||
input_category, failure_link)
|
||||
elif section_name in ["SickBeard", "NzbDrone", "Sonarr"]:
|
||||
result = TV().process_episode(section_name, input_directory, input_name, status, client_agent,
|
||||
download_id, input_category, failure_link)
|
||||
result = TV().process(section_name, input_directory, input_name, status, client_agent,
|
||||
download_id, input_category, failure_link)
|
||||
elif section_name in ["HeadPhones", "Lidarr"]:
|
||||
result = Music().process(section_name, input_directory, input_name, status, client_agent, input_category)
|
||||
elif section_name == "Mylar":
|
||||
result = Comic().process_episode(section_name, input_directory, input_name, status, client_agent,
|
||||
input_category)
|
||||
result = Comic().process(section_name, input_directory, input_name, status, client_agent,
|
||||
input_category)
|
||||
elif section_name == "Gamez":
|
||||
result = Game().process(section_name, input_directory, input_name, status, client_agent, input_category)
|
||||
elif section_name == 'UserScript':
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
#! /usr/bin/env python2
|
||||
from __future__ import print_function
|
||||
|
||||
from babelfish import Language
|
||||
import guessit
|
||||
import requests
|
||||
import subliminal
|
||||
|
||||
import core
|
||||
from core.nzbToMediaAutoFork import auto_fork
|
||||
from core.nzbToMediaUtil import server_responding
|
||||
from core.transcoder import transcoder
|
||||
from core import transcoder
|
||||
from core.forks import auto_fork
|
||||
from core.utils import server_responding
|
||||
|
||||
# Initialize the config
|
||||
core.initialize()
|
||||
|
@ -38,7 +40,6 @@ if server_responding("http://127.0.0.1:8085"):
|
|||
if server_responding("http://127.0.0.1:8090"):
|
||||
print("Mylar Running")
|
||||
|
||||
from babelfish import Language
|
||||
lan = 'pt'
|
||||
lan = Language.fromalpha2(lan)
|
||||
print(lan.alpha3)
|
||||
|
@ -59,7 +60,6 @@ if guess:
|
|||
results = r.json()
|
||||
print(results)
|
||||
|
||||
import subliminal
|
||||
subliminal.region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'})
|
||||
languages = set()
|
||||
languages.add(lan)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue