Commit 504865fe authored by echel0n's avatar echel0n
Browse files

Restruct of javascript routines and imports.

Added in javascript router to handler controller actions and proper routing of them.
Version bump to 8.0.0
parents cb6ecf1c cb52ac7e
......@@ -17,12 +17,13 @@
"noempty": true,
"nonbsp": true,
"undef": true,
"unused": true,
"unused": "vars",
"node": true,
"jquery": true,
"globals": {
"jQuery": true,
"PNotify": true,
"URI": true,
"chai": true,
"mocha": true,
"_": true,
......
......@@ -77,7 +77,6 @@ module.exports = function (grunt) {
relative: false
},
dependencies: {
'formwizard': 'jquery',
'selectboxes': 'jquery',
'bookmarkscroll': 'jquery'
}
......
......@@ -27,12 +27,13 @@
"jqueryui-touch-punch": "*",
"jquery-confirm": "^2.5.2",
"isotope": "^2.2.2",
"formwizard": "http://www.dynamicdrive.com/dynamicindex16/formwizard.js",
"selectboxes": "https://raw.githubusercontent.com/SamWM/jQuery-Plugins/master/selectboxes/jquery.selectboxes.js",
"bookmarkscroll": "http://dynamicdrive.com/dynamicindex5/bookmarkscroll.js",
"jquery.tablesorter": "^2.25.4",
"scrollup": "^2.4.1",
"qtip2": "^2.2.1"
"qtip2": "^2.2.1",
"uri.js": "^1.17.1",
"jquery.steps": "jquery-steps#^1.1.0"
},
"resolutions": {
"bootstrap": "^3.0.0"
......
{
"name": "SiCKRAGE",
"version": "7.0.24",
"private": true,
"repository": {
"type": "git",
"url": "git+https://github.com/SiCKRAGETV/SiCKRAGE.git"
},
"bugs": {
"url": "https://www.sickrage.tv"
"url": "https://www.sickrage.ca/forums/"
},
"homepage": "https://www.sickrage.tv",
"homepage": "https://www.sickrage.ca",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-bower-concat": "^0.5.0",
......
......@@ -44,6 +44,7 @@ __all__ = [
SYS_ENCODING = "UTF-8"
DEBUG = False
DEVELOPER = False
PROG_DIR = os.path.abspath(os.path.dirname(__file__))
......@@ -244,7 +245,7 @@ def help_message(prog_dir):
def main():
global srCore, PROG_DIR, DATA_DIR, SYS_ENCODING, DEVELOPER
global srCore, PROG_DIR, DATA_DIR, SYS_ENCODING, DEVELOPER, DEBUG
# sickrage requires python 2.7+
if sys.version_info < (2, 7):
......@@ -255,20 +256,18 @@ def main():
if path not in sys.path:
sys.path.insert(0, path)
# setup locale system encoding
SYS_ENCODING = encodingInit()
try:
# setup locale system encoding
SYS_ENCODING = encodingInit()
# print logo
print_logo()
# defaults
SYS_ENCODING = None
PIDFILE = None
DAEMONIZE = False
WEB_PORT = 8081
LAUNCH_BROWSER = True
DEBUG = False
CONFIG_FILE = "config.ini"
CONSOLE = not hasattr(sys, "frozen")
......@@ -362,20 +361,26 @@ def main():
srCore = core.srCore(CONFIG_FILE, CONSOLE, DEBUG, WEB_PORT, LAUNCH_BROWSER)
srCore.start()
except ImportError as e:
# install pip package manager
install_pip()
if DEBUG:
traceback.print_exc()
if not DEVELOPER:
# install pip package manager
install_pip()
# install required packages
install_requirements()
# install required packages
install_requirements()
# restart sickrage silently
os.execl(sys.executable, sys.executable, *sys.argv)
# restart sickrage silently
os.execl(sys.executable, sys.executable, *sys.argv)
except KeyboardInterrupt:
if srCore:
srCore.shutdown()
except Exception as e:
traceback.print_exc()
if srCore:
srCore.shutdown(status=str(e))
sys.exit(str(e))
if __name__ == '__main__':
......
......@@ -27,6 +27,7 @@ import requests
from bencode import BTFailure, bdecode, bencode
import sickrage
from sickrage.core.srsession import srSession
__all__ = [
'utorrent',
......@@ -154,7 +155,7 @@ class GenericClient(object):
self.response = None
self.auth = None
self.last_time = time.time()
self.session = requests.Session()
self.session = srSession().session
self.session.auth = (self.username, self.password)
def _request(self, method='get', params=None, data=None, files=None):
......
......@@ -20,11 +20,11 @@
from __future__ import unicode_literals
import cookielib
import datetime
import httplib
import json
import urllib
import urllib2
from datetime import date, timedelta
import MultipartPostHandler
......@@ -54,7 +54,7 @@ class SabNZBd(object):
# if it aired more than 7 days ago, override with the backlog category IDs
for curEp in nzb.episodes:
if date.today() - curEp.airdate > timedelta(days=7):
if datetime.date.today() - curEp.airdate > datetime.timedelta(days=7):
category = sickrage.srConfig.SAB_CATEGORY_BACKLOG
if nzb.show.is_anime:
category = sickrage.srConfig.SAB_CATEGORY_ANIME_BACKLOG
......
......@@ -22,22 +22,21 @@ from __future__ import unicode_literals
import datetime
import os
import random
import re
import shutil
import socket
import sys
import traceback
import urllib
import urlparse
import sickrage
from sickrage.core.caches.name_cache import srNameCache
from sickrage.core.classes import SiCKRAGEURLopener, AttrDict, providersDict
from sickrage.core.classes import AttrDict, providersDict
from sickrage.core.common import SD, SKIPPED, WANTED
from sickrage.core.databases import main_db, cache_db, failed_db
from sickrage.core.helpers import encrypt, findCertainShow, \
generateCookieSecret, makeDir, removetree, restoreDB, get_lan_ip
from sickrage.core.helpers.sessions import get_temp_dir
generateCookieSecret, makeDir, removetree, restoreDB, get_lan_ip, get_temp_dir
from sickrage.core.nameparser.validator import check_force_season_folders
from sickrage.core.processors import auto_postprocessor
from sickrage.core.processors.auto_postprocessor import srPostProcessor
......@@ -52,12 +51,12 @@ from sickrage.core.searchers.trakt_searcher import srTraktSearcher
from sickrage.core.srconfig import srConfig
from sickrage.core.srlogger import srLogger
from sickrage.core.srscheduler import srIntervalTrigger, srScheduler
from sickrage.core.srsession import srSession
from sickrage.core.tv.show import TVShow
from sickrage.core.updaters.show_updater import srShowUpdater
from sickrage.core.updaters.tz_updater import update_network_dict
from sickrage.core.version_updater import srVersionUpdater
from sickrage.core.webserver import srWebServer
from sickrage.indexers import srIndexerApi
from sickrage.metadata import get_metadata_generator_dict, kodi, kodi_12plus, \
mede8er, mediabrowser, ps3, tivo, wdtv
from sickrage.notifiers.boxcar import BoxcarNotifier
......@@ -82,9 +81,6 @@ from sickrage.notifiers.synologynotifier import synologyNotifier
from sickrage.notifiers.trakt import TraktNotifier
from sickrage.notifiers.tweet import TwitterNotifier
urllib._urlopener = SiCKRAGEURLopener()
urlparse.uses_netloc.append('scgi')
class srCore(object):
def __init__(self, config_file, console=None, debug=None, web_port=None, open_broswser=None):
......@@ -93,6 +89,9 @@ class srCore(object):
self.CONSOLE = console
self.DEBUG = debug
# random user agent
urllib.FancyURLopener.version = random.choice(srSession.USER_AGENTS)
# process id
self.PID = os.getpid()
......@@ -157,8 +156,7 @@ class srCore(object):
# show list
self.SHOWLIST = []
# indexers
self.INDEXER_API = None
# updater
self.VERSIONUPDATER = None
# name cache
......@@ -206,9 +204,6 @@ class srCore(object):
# init updater and get current version
self.VERSION = self.VERSIONUPDATER.updater.version
# init indexers
self.INDEXER_API = srIndexerApi
# init caches
self.NAMECACHE = srNameCache()
......@@ -491,17 +486,6 @@ class srCore(object):
self.STARTED = True
sickrage.srWebServer.start()
def halt(self):
sickrage.srLogger.info("Aborting all threads")
# shutdown scheduler
sickrage.srLogger.info("Shutting down scheduler jobs")
sickrage.srScheduler.shutdown()
if sickrage.srConfig.ADBA_CONNECTION:
sickrage.srLogger.info("Logging out ANIDB connection")
sickrage.srConfig.ADBA_CONNECTION.logout()
def shutdown(self, status=None, restart=False):
self.RESTARTED = restart
......@@ -512,7 +496,15 @@ class srCore(object):
sickrage.srLogger.info('SiCKRAGE IS PERFORMING A SHUTDOWN!')
# stop all background services
self.halt()
sickrage.srLogger.info("Aborting all threads")
# shutdown scheduler
sickrage.srLogger.info("Shutting down scheduler jobs")
sickrage.srScheduler.shutdown()
if sickrage.srConfig.ADBA_CONNECTION:
sickrage.srLogger.info("Logging out ANIDB connection")
sickrage.srConfig.ADBA_CONNECTION.logout()
# save all settings
self.save_all()
......@@ -536,8 +528,10 @@ class srCore(object):
# write all shows
sickrage.srLogger.info("Saving all shows to the database")
for SHOW in self.SHOWLIST:
try:SHOW.saveToDB()
except:continue
try:
SHOW.saveToDB()
except:
continue
# save config
sickrage.srConfig.save()
......
......@@ -104,29 +104,28 @@ class srNameCache(object):
cache_db.CacheDB().action("INSERT OR REPLACE INTO scene_names (indexer_id, name) VALUES (?, ?)",
[indexer_id, name])
def buildNameCache(self, show=None):
def buildNameCache(self, show=None, force=False):
"""Build internal name cache
:param show: Specify show to build name cache for, if None, just do all shows
"""
if self.shouldUpdate():
if not show:
retrieve_exceptions()
for show in sickrage.srCore.SHOWLIST:
self.buildNameCache(show)
else:
self.lastUpdate = datetime.fromtimestamp(int(time.mktime(datetime.today().timetuple())))
sickrage.srLogger.debug("Building internal name cache for [{}]".format(show.name))
self.clearCache(show.indexerid)
for curSeason in [-1] + get_scene_seasons(show.indexerid):
for name in list(set(get_scene_exceptions(
show.indexerid, season=curSeason) + [show.name])):
name = full_sanitizeSceneName(name)
if name not in self.cache:
self.cache[name] = int(show.indexerid)
sickrage.srLogger.debug("Internal name cache for [{}] set to: [{}]".format(
show.name, [key for key, value in self.cache.items() if value == show.indexerid][0]))
if not show and self.shouldUpdate():
retrieve_exceptions()
for show in sickrage.srCore.SHOWLIST:
self.buildNameCache(show)
else:
self.lastUpdate = datetime.fromtimestamp(int(time.mktime(datetime.today().timetuple())))
sickrage.srLogger.debug("Building internal name cache for [{}]".format(show.name))
self.clearCache(show.indexerid)
for curSeason in [-1] + get_scene_seasons(show.indexerid):
for name in list(set(get_scene_exceptions(
show.indexerid, season=curSeason) + [show.name])):
name = full_sanitizeSceneName(name)
if name not in self.cache:
self.cache[name] = int(show.indexerid)
sickrage.srLogger.debug("Internal name cache for [{}] set to: [{}]".format(
show.name, [key for key, value in self.cache.items() if value == show.indexerid][0]))
......@@ -24,7 +24,6 @@ import os
import random
import re
import sys
import urllib
from collections import OrderedDict
from dateutil import parser
......@@ -32,51 +31,7 @@ from dill import dill
import sickrage
from sickrage.core.common import Quality, dateFormat, dateTimeFormat
from sickrage.core.helpers.sessions import USER_AGENTS
class SiCKRAGEURLopener(urllib.FancyURLopener):
version = random.choice(USER_AGENTS)
class AuthURLOpener(SiCKRAGEURLopener):
"""
URLOpener class that supports http auth without needing interactive password entry.
If the provided username/password don't work it simply fails.
user: username to use for HTTP auth
pw: password to use for HTTP auth
"""
def __init__(self, user, pw):
self.username = user
self.password = pw
# remember if we've tried the username/password before
self.numTries = 0
# call the base class
urllib.FancyURLopener.__init__(self)
def prompt_user_passwd(self, host, realm):
"""
Override this function and instead of prompting just give the
username/password that were provided when the class was instantiated.
"""
# if this is the first try then provide a username/password
if self.numTries == 0:
self.numTries = 1
return self.username, self.password
# if we've tried before then return blank which cancels the request
else:
return '', ''
# this is pretty much just a hack for convenience
def openit(self, url):
self.numTries = 0
return SiCKRAGEURLopener.open(self, url)
from sickrage.indexers import srIndexerApi
class SearchResult(object):
......@@ -272,7 +227,7 @@ class Proper(object):
def __str__(self):
return str(self.date) + " " + self.name + " " + str(self.season) + "x" + str(self.episode) + " of " + str(
self.indexerid) + " from " + str(sickrage.srCore.INDEXER_API(self.indexer).name)
self.indexerid) + " from " + str(srIndexerApi(self.indexer).name)
class UIError(object):
......@@ -370,10 +325,10 @@ class providersDict(dict):
NewznabProvider, \
TorrentRssProvider
self[GenericProvider.NZB] = {p.id: p for p in NZBProvider.getProviderList()}
self[GenericProvider.TORRENT] = {p.id: p for p in TorrentProvider.getProviderList()}
self[GenericProvider.NEWZNAB] = {p.id: p for p in NewznabProvider.getProviderList()}
self[GenericProvider.TORRENTRSS] = {p.id: p for p in TorrentRssProvider.getProviderList()}
self[GenericProvider.NZB] = {p.id: p for p in NZBProvider.getProviders()}
self[GenericProvider.TORRENT] = {p.id: p for p in TorrentProvider.getProviders()}
self[GenericProvider.NEWZNAB] = {p.id: p for p in NewznabProvider.getProviders()}
self[GenericProvider.TORRENTRSS] = {p.id: p for p in TorrentRssProvider.getProviders()}
# load providers from database file
self.load()
......
......@@ -197,8 +197,10 @@ class Connection(object):
"""Get a :class:`Transaction` object for interacting directly
with the underlying SQLite database.
"""
_ = threading.currentThread().getName()
threading.currentThread().setName("DB")
yield Transaction(self)
threading.currentThread().setName(_)
def _get_id(self):
with self._db_lock:
......
......@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import ast
import base64
import ctypes
import datetime
import errno
import hashlib
import httplib
......@@ -15,6 +16,7 @@ import re
import shutil
import socket
import stat
import tempfile
import time
import traceback
import urlparse
......@@ -22,7 +24,6 @@ import uuid
import zipfile
from _socket import timeout as SocketTimeout
from contextlib import closing, contextmanager
from datetime import datetime
from itertools import cycle, izip
import requests
......@@ -32,8 +33,8 @@ from bs4 import BeautifulSoup
import sickrage
from sickrage.clients import http_error_code
from sickrage.core.exceptions import MultipleShowObjectsException
from sickrage.core.helpers.sessions import _setUpSession
from sickrage.indexers import adba
from sickrage.core.srsession import srSession
from sickrage.indexers import adba, srIndexerApi
from sickrage.indexers.indexer_exceptions import indexer_episodenotfound, \
indexer_seasonnotfound
......@@ -406,15 +407,15 @@ def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
showNames = [re.sub('[. -]', ' ', regShowName)]
# Query Indexers for each search term and build the list of results
for i in sickrage.srCore.INDEXER_API().indexers if not indexer else int(indexer or []):
for i in srIndexerApi().indexers if not indexer else int(indexer or []):
# Query Indexers for each search term and build the list of results
lINDEXER_API_PARMS = sickrage.srCore.INDEXER_API(i).api_params.copy()
lINDEXER_API_PARMS = srIndexerApi(i).api_params.copy()
if ui is not None:
lINDEXER_API_PARMS['custom_ui'] = ui
t = sickrage.srCore.INDEXER_API(i).indexer(**lINDEXER_API_PARMS)
t = srIndexerApi(i).indexer(**lINDEXER_API_PARMS)
for name in showNames:
sickrage.srLogger.debug("Trying to find " + name + " on " + sickrage.srCore.INDEXER_API(i).name)
sickrage.srLogger.debug("Trying to find " + name + " on " + srIndexerApi(i).name)
try:
search = t[indexer_id] if indexer_id else t[name]
......@@ -1027,7 +1028,12 @@ def anon_url(*url):
"""
Return a URL string consisting of the Anonymous redirect URL and an arbitrary number of values appended.
"""
return '{}{}'.format(sickrage.srConfig.ANON_REDIRECT, ''.join(map(str, url)))
url = ''.join(map(str, url))
if not url.startswith('http://'):
url = 'http://' + url
return '{}{}'.format(sickrage.srConfig.ANON_REDIRECT, url)
unique_key1 = hex(uuid.getnode() ** 2) # Used in encryption v1
......@@ -1105,7 +1111,7 @@ def validateShow(show, season=None, episode=None):
indexer_lang = show.lang
try:
lINDEXER_API_PARMS = sickrage.srCore.INDEXER_API(show.indexer).api_params.copy()
lINDEXER_API_PARMS = srIndexerApi(show.indexer).api_params.copy()
if indexer_lang and not indexer_lang == sickrage.srConfig.INDEXER_DEFAULT_LANGUAGE:
lINDEXER_API_PARMS['language'] = indexer_lang
......@@ -1113,7 +1119,7 @@ def validateShow(show, season=None, episode=None):
if show.dvdorder != 0:
lINDEXER_API_PARMS['dvdorder'] = True
t = sickrage.srCore.INDEXER_API(show.indexer).indexer(**lINDEXER_API_PARMS)
t = srIndexerApi(show.indexer).indexer(**lINDEXER_API_PARMS)
if season is None and episode is None:
return t
......@@ -1242,7 +1248,7 @@ def restoreConfigZip(archive, targetDir):
head, tail = os.path.split(path)
return tail or os.path.basename(head)
bakFilename = '{0}-{1}'.format(path_leaf(targetDir), datetime.now().strftime('%Y%m%d_%H%M%S'))
bakFilename = '{0}-{1}'.format(path_leaf(targetDir), datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
shutil.move(targetDir, os.path.join(os.path.dirname(targetDir), bakFilename))
with zipfile.ZipFile(archive, 'r', allowZip64=True) as zip_file:
......@@ -1278,7 +1284,7 @@ def backupAll(backupDir):
for filename in files:
source += [os.path.join(path, filename)]
target = os.path.join(backupDir, 'sickrage-{}.zip'.format(datetime.now().strftime('%Y%m%d%H%M%S')))
target = os.path.join(backupDir, 'sickrage-{}.zip'.format(datetime.datetime.now().strftime('%Y%m%d%H%M%S')))
return backupConfigZip(source, target, sickrage.DATA_DIR)
......@@ -1319,7 +1325,7 @@ def codeDescription(status_code):
return 'unknown'
def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=None, json=False, needBytes=False):
def getURL(url, post_data=None, params=None, headers=None, timeout=None, session=None, json=False, needBytes=False):
"""
Returns a byte-string retrieved from the url provider.
"""
......@@ -1328,12 +1334,13 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
if headers is None:
headers = {}
if not requests.__version__ < (2, 8):
sickrage.srLogger.debug(
"Requests version 2.8+ needed to avoid SSL cert verify issues, please upgrade your copy")
url = normalize_url(url)
session = _setUpSession(session or requests.Session(), headers, params)
session = srSession(headers, params).session or session
try:
# decide if we get or post data to server
......@@ -1364,10 +1371,6 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
except Exception as e:
sickrage.srLogger.debug("Unknown exception in getURL %s Error: %r" % (url, e))
sickrage.srLogger.debug(traceback.format_exc())
finally:
if resp:
[i.raw.release_conn() for i in resp.history]
resp.raw.release_conn()
def download_file(url, filename, session=None, headers=None):
......@@ -1386,7 +1389,7 @@ def download_file(url, filename, session=None, headers=None):
if headers is None:
headers = {}
url = normalize_url(url)
session = _setUpSession(session, headers)
session = srSession(headers).session or session
session.stream = True
try:
......@@ -1415,13 +1418,13 @@ def download_file(url, filename, session=None, headers=None):
sickrage.srLogger.warning("Connection timed out (sockets) while loading download URL %s Error: %r" % (url, e))
except requests.exceptions.HTTPError as e:
remove_file_failed(filename)
sickrage.srLogger.warning("HTTP error %r while loading download URL %s " % (e), url)
sickrage.srLogger.warning("HTTP error %r while loading download URL %s " % e, url)
except requests.exceptions.ConnectionError as e:
remove_file_failed(filename)
sickrage.srLogger.warning("Connection error %r while loading download URL %s " % (e), url)
sickrage.srLogger.warning("Connection error %r while loading download URL %s " % e, url)
except requests.exceptions.Timeout as e:
remove_file_failed(filename)
sickrage.srLogger.warning("Connection timed out %r while loading download URL %s " % (e), url)
sickrage.srLogger.warning("Connection timed out %r while loading download URL %s " % e, url)
except EnvironmentError as e:
remove_file_failed(filename)
sickrage.srLogger.warning("Unable to save the file: %r " % e)
......@@ -1608,11 +1611,12 @@ def isFileLocked(checkfile, writeLockCheck=False):
lockFile = checkfile + ".lckchk"
if os.path.exists(lockFile):
os.remove(lockFile)
try:
os.rename(checkfile, lockFile)
time.sleep(1)