2014-03-10 05:18:05 +00:00
# Author: Nic Wolfe <nic@wolfeden.ca>
# URL: http://code.google.com/p/sickbeard/
#
2014-05-23 12:37:22 +00:00
# This file is part of SickRage.
2014-03-10 05:18:05 +00:00
#
2014-05-23 12:37:22 +00:00
# SickRage is free software: you can redistribute it and/or modify
2014-03-10 05:18:05 +00: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 12:37:22 +00:00
# SickRage is distributed in the hope that it will be useful,
2014-03-10 05:18:05 +00: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 12:37:22 +00:00
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
2014-03-10 05:18:05 +00:00
from __future__ import with_statement
2014-07-27 10:59:21 +00:00
2014-06-11 08:34:28 +00:00
import base64
import inspect
2014-06-29 10:05:33 +00:00
import traceback
2014-03-10 05:18:05 +00:00
2014-07-06 14:45:01 +00:00
import os
2014-03-10 05:18:05 +00:00
import time
import urllib
import re
import datetime
import random
2014-06-11 08:34:28 +00:00
import sys
2014-06-16 05:45:52 +00:00
2014-03-10 05:18:05 +00:00
import sickbeard
from sickbeard import config , sab
from sickbeard import clients
from sickbeard import history , notifiers , processTV
from sickbeard import ui
from sickbeard import logger , helpers , exceptions , classes , db
from sickbeard import encodingKludge as ek
from sickbeard import search_queue
from sickbeard import image_cache
from sickbeard import naming
from sickbeard import scene_exceptions
from sickbeard import subtitles
from sickbeard import network_timezones
from sickbeard . providers import newznab , rsstorrent
2014-07-28 01:46:15 +00:00
from sickbeard . common import Quality , Overview , statusStrings , qualityPresetStrings , cpu_presets
2014-06-30 01:54:41 +00:00
from sickbeard . common import SNATCHED , UNAIRED , IGNORED , ARCHIVED , WANTED , FAILED
2014-03-10 05:18:05 +00:00
from sickbeard . common import SD , HD720p , HD1080p
from sickbeard . exceptions import ex
from sickbeard . scene_exceptions import get_scene_exceptions
2014-03-25 05:57:24 +00:00
from sickbeard . scene_numbering import get_scene_numbering , set_scene_numbering , get_scene_numbering_for_show , \
2014-05-30 05:48:02 +00:00
get_xem_numbering_for_show , get_scene_absolute_numbering_for_show , get_xem_absolute_numbering_for_show , \
get_scene_absolute_numbering
2014-03-10 05:18:05 +00:00
2014-05-27 07:44:23 +00:00
from sickbeard . blackandwhitelist import BlackAndWhiteList
2014-06-11 08:34:28 +00:00
from browser import WebFileBrowser
2014-03-10 05:18:05 +00:00
from lib . dateutil import tz
2014-05-30 05:48:02 +00:00
from lib . unrar2 import RarFile
2014-03-10 05:18:05 +00:00
from lib import subliminal
2014-06-27 11:00:16 +00:00
from trakt import TraktCall
2014-03-10 05:18:05 +00:00
try :
import json
except ImportError :
from lib import simplejson as json
try :
import xml . etree . cElementTree as etree
except ImportError :
import xml . etree . ElementTree as etree
2014-05-26 06:29:22 +00:00
from lib import adba
2014-05-20 20:51:54 +00:00
2014-06-16 05:45:52 +00:00
from Cheetah . Template import Template
2014-07-27 12:51:22 +00:00
from tornado . web import RequestHandler , HTTPError , asynchronous
2014-07-01 08:49:12 +00:00
2014-07-27 14:39:33 +00:00
2014-06-17 19:51:23 +00:00
def authenticated ( handler_class ) :
2014-06-11 08:34:28 +00:00
def wrap_execute ( handler_execute ) :
2014-06-17 18:16:04 +00:00
def basicauth ( handler , transforms , * args , * * kwargs ) :
def _request_basic_auth ( handler ) :
2014-06-11 08:34:28 +00:00
handler . set_status ( 401 )
2014-06-18 15:38:43 +00:00
handler . set_header ( ' WWW-Authenticate ' , ' Basic realm= " SickRage " ' )
2014-06-17 19:51:23 +00:00
handler . _transforms = [ ]
2014-06-11 08:34:28 +00:00
handler . finish ( )
return False
2014-06-17 18:16:04 +00:00
try :
2014-06-17 20:04:17 +00:00
if not ( sickbeard . WEB_USERNAME and sickbeard . WEB_PASSWORD ) :
return True
2014-11-02 15:50:47 +00:00
elif ( handler . request . uri . startswith ( sickbeard . WEB_ROOT + ' /api ' ) and
' /api/builder ' not in handler . request . uri ) :
2014-10-08 18:05:41 +00:00
return True
2014-11-02 15:50:47 +00:00
elif ( handler . request . uri . startswith ( sickbeard . WEB_ROOT + ' /calendar ' ) and
sickbeard . CALENDAR_UNPROTECTED ) :
2014-06-18 12:56:26 +00:00
return True
2014-06-17 20:04:17 +00:00
2014-06-17 18:16:04 +00:00
auth_hdr = handler . request . headers . get ( ' Authorization ' )
2014-06-15 04:38:13 +00:00
2014-06-17 18:16:04 +00:00
if auth_hdr == None :
return _request_basic_auth ( handler )
if not auth_hdr . startswith ( ' Basic ' ) :
return _request_basic_auth ( handler )
auth_decoded = base64 . decodestring ( auth_hdr [ 6 : ] )
username , password = auth_decoded . split ( ' : ' , 2 )
2014-06-17 19:51:23 +00:00
if username != sickbeard . WEB_USERNAME or password != sickbeard . WEB_PASSWORD :
2014-06-17 18:16:04 +00:00
return _request_basic_auth ( handler )
except Exception , e :
return _request_basic_auth ( handler )
return True
2014-06-16 05:45:52 +00:00
2014-06-11 08:34:28 +00:00
def _execute ( self , transforms , * args , * * kwargs ) :
2014-06-17 18:16:04 +00:00
if not basicauth ( self , transforms , * args , * * kwargs ) :
2014-06-11 08:34:28 +00:00
return False
return handler_execute ( self , transforms , * args , * * kwargs )
2014-06-16 05:45:52 +00:00
2014-06-11 08:34:28 +00:00
return _execute
handler_class . _execute = wrap_execute ( handler_class . _execute )
return handler_class
2014-07-01 08:49:12 +00:00
2014-06-30 01:54:41 +00:00
class HTTPRedirect ( Exception ) :
""" Exception raised when the request should be redirected. """
def __init__ ( self , url , permanent = False , status = None ) :
2014-07-11 19:33:49 +00:00
self . url = url
2014-06-30 01:54:41 +00:00
self . permanent = permanent
self . status = status
2014-06-30 08:15:10 +00:00
Exception . __init__ ( self , self . url , self . permanent , self . status )
2014-06-30 01:54:41 +00:00
def __call__ ( self ) :
""" Use this exception as a request.handler (raise self). """
raise self
2014-07-01 08:49:12 +00:00
2014-06-30 01:54:41 +00:00
def redirect ( url , permanent = False , status = None ) :
2014-07-11 19:33:49 +00:00
assert url [ 0 ] == ' / '
raise HTTPRedirect ( sickbeard . WEB_ROOT + url , permanent , status )
2014-07-06 14:45:01 +00:00
2014-07-27 14:39:33 +00:00
2014-06-17 19:51:23 +00:00
@authenticated
2014-06-19 08:37:44 +00:00
class MainHandler ( RequestHandler ) :
2014-06-18 12:56:26 +00:00
def http_error_401_handler ( self ) :
""" Custom handler for 401 error """
return r ''' <!DOCTYPE html>
< html >
< head >
< title > % s < / title >
< / head >
< body >
< br / >
< font color = " #0000FF " > Error % s : You need to provide a valid username and password . < / font >
< / body >
< / html >
''' % ( ' Access denied ' , 401)
def write_error ( self , status_code , * * kwargs ) :
2014-06-29 10:05:33 +00:00
if status_code == 401 :
2014-06-30 02:52:04 +00:00
self . finish ( self . http_error_401_handler ( ) )
2014-06-29 10:05:33 +00:00
elif status_code == 404 :
2014-07-11 19:33:49 +00:00
self . redirect ( sickbeard . WEB_ROOT + ' /home/ ' )
2014-07-06 00:57:43 +00:00
elif self . settings . get ( " debug " ) and " exc_info " in kwargs :
2014-07-06 14:45:01 +00:00
exc_info = kwargs [ " exc_info " ]
trace_info = ' ' . join ( [ " %s <br/> " % line for line in traceback . format_exception ( * exc_info ) ] )
request_info = ' ' . join ( [ " <strong> %s </strong>: %s <br/> " % ( k , self . request . __dict__ [ k ] ) for k in
self . request . __dict__ . keys ( ) ] )
error = exc_info [ 1 ]
self . set_header ( ' Content-Type ' , ' text/html ' )
self . finish ( """ <html>
2014-07-06 00:57:43 +00:00
< title > % s < / title >
< body >
< h2 > Error < / h2 >
< p > % s < / p >
< h2 > Traceback < / h2 >
< p > % s < / p >
< h2 > Request Info < / h2 >
< p > % s < / p >
< / body >
< / html > """ % (error, error,
trace_info , request_info ) )
2014-06-18 12:56:26 +00:00
2014-06-17 19:51:23 +00:00
def _dispatch ( self ) :
2014-06-18 12:56:26 +00:00
path = self . request . uri . replace ( sickbeard . WEB_ROOT , ' ' ) . split ( ' ? ' ) [ 0 ]
2014-06-16 06:19:14 +00:00
2014-06-11 08:34:28 +00:00
method = path . strip ( ' / ' ) . split ( ' / ' ) [ - 1 ]
2014-06-30 08:12:41 +00:00
if method == ' robots.txt ' :
method = ' robots_txt '
2014-06-19 15:47:28 +00:00
if path . startswith ( ' /api ' ) and method != ' builder ' :
2014-06-16 06:19:14 +00:00
apikey = path . strip ( ' / ' ) . split ( ' / ' ) [ - 1 ]
method = path . strip ( ' / ' ) . split ( ' / ' ) [ 0 ]
2014-06-17 19:51:23 +00:00
self . request . arguments . update ( { ' apikey ' : [ apikey ] } )
2014-06-11 08:34:28 +00:00
def pred ( c ) :
return inspect . isclass ( c ) and c . __module__ == pred . __module__
try :
2014-06-16 05:45:52 +00:00
klass = [ cls [ 1 ] for cls in
inspect . getmembers ( sys . modules [ __name__ ] , pred ) + [ ( self . __class__ . __name__ , self . __class__ ) ] if
cls [ 0 ] . lower ( ) == method . lower ( ) or method in cls [ 1 ] . __dict__ . keys ( ) ] [ 0 ] ( self . application ,
self . request )
2014-06-11 08:34:28 +00:00
except :
klass = None
if klass and not method . startswith ( ' _ ' ) :
# Sanitize argument lists:
2014-06-18 06:55:45 +00:00
args = self . request . arguments
for arg , value in args . items ( ) :
if len ( value ) == 1 :
args [ arg ] = value [ 0 ]
2014-06-11 08:34:28 +00:00
# Regular method handler for classes
func = getattr ( klass , method , None )
# Special index method handler for classes and subclasses:
2014-06-15 21:45:09 +00:00
if path . startswith ( ' /api ' ) or path . endswith ( ' / ' ) :
2014-06-11 08:34:28 +00:00
if func and getattr ( func , ' index ' , None ) :
func = getattr ( func ( self . application , self . request ) , ' index ' , None )
elif not func :
func = getattr ( klass , ' index ' , None )
2014-07-06 00:57:43 +00:00
if callable ( func ) :
2014-06-18 06:55:45 +00:00
return func ( * * args )
2014-06-11 08:34:28 +00:00
2014-06-17 19:51:23 +00:00
raise HTTPError ( 404 )
2014-06-19 14:31:44 +00:00
2014-07-27 12:51:22 +00:00
@asynchronous
2014-06-17 21:25:35 +00:00
def get ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
try :
2014-06-30 02:52:04 +00:00
self . finish ( self . _dispatch ( ) )
2014-07-06 00:57:43 +00:00
except HTTPRedirect , e :
self . redirect ( e . url , e . permanent , e . status )
2014-06-11 08:34:28 +00:00
2014-07-27 12:51:22 +00:00
@asynchronous
2014-06-17 21:25:35 +00:00
def post ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
try :
2014-06-30 02:52:04 +00:00
self . finish ( self . _dispatch ( ) )
2014-07-06 00:57:43 +00:00
except HTTPRedirect , e :
self . redirect ( e . url , e . permanent , e . status )
2014-06-18 06:55:45 +00:00
2014-06-11 08:34:28 +00:00
def robots_txt ( self , * args , * * kwargs ) :
""" Keep web crawlers out """
self . set_header ( ' Content-Type ' , ' text/plain ' )
2014-06-30 08:12:41 +00:00
return " User-agent: * \n Disallow: / "
2014-06-11 08:34:28 +00:00
def showPoster ( self , show = None , which = None ) :
# Redirect initial poster/banner thumb to default images
if which [ 0 : 6 ] == ' poster ' :
default_image_name = ' poster.png '
else :
default_image_name = ' banner.png '
default_image_path = ek . ek ( os . path . join , sickbeard . PROG_DIR , ' gui ' , ' slick ' , ' images ' , default_image_name )
if show and sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) ) :
cache_obj = image_cache . ImageCache ( )
image_file_name = None
if which == ' poster ' :
image_file_name = cache_obj . poster_path ( show )
if which == ' poster_thumb ' :
image_file_name = cache_obj . poster_thumb_path ( show )
if which == ' banner ' :
image_file_name = cache_obj . banner_path ( show )
if which == ' banner_thumb ' :
image_file_name = cache_obj . banner_thumb_path ( show )
if ek . ek ( os . path . isfile , image_file_name ) :
with file ( image_file_name , ' rb ' ) as img :
2014-06-15 11:08:41 +00:00
return img . read ( )
2014-06-11 08:34:28 +00:00
with file ( default_image_path , ' rb ' ) as img :
2014-06-15 11:08:41 +00:00
return img . read ( )
2014-06-11 08:34:28 +00:00
def setHomeLayout ( self , layout ) :
2014-10-09 00:00:36 +00:00
if layout not in ( ' poster ' , ' small ' , ' banner ' , ' simple ' ) :
2014-06-11 08:34:28 +00:00
layout = ' poster '
sickbeard . HOME_LAYOUT = layout
2014-06-30 01:54:41 +00:00
redirect ( " /home/ " )
2014-06-11 08:34:28 +00:00
2014-10-26 05:42:45 +00:00
def setPosterSortBy ( self , sort ) :
if sort not in ( ' name ' , ' date ' , ' network ' , ' progress ' ) :
sort = ' name '
sickbeard . POSTER_SORTBY = sort
sickbeard . save_config ( )
def setPosterSortDir ( self , direction ) :
sickbeard . POSTER_SORTDIR = int ( direction )
sickbeard . save_config ( )
2014-06-11 08:34:28 +00:00
def setHistoryLayout ( self , layout ) :
if layout not in ( ' compact ' , ' detailed ' ) :
layout = ' detailed '
sickbeard . HISTORY_LAYOUT = layout
2014-06-30 01:54:41 +00:00
redirect ( " /history/ " )
2014-06-11 08:34:28 +00:00
def toggleDisplayShowSpecials ( self , show ) :
sickbeard . DISPLAY_SHOW_SPECIALS = not sickbeard . DISPLAY_SHOW_SPECIALS
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + show )
2014-06-11 08:34:28 +00:00
def setComingEpsLayout ( self , layout ) :
2014-09-15 17:43:49 +00:00
if layout not in ( ' poster ' , ' banner ' , ' list ' , ' calendar ' ) :
2014-06-11 08:34:28 +00:00
layout = ' banner '
2014-09-15 17:43:49 +00:00
if layout == ' calendar ' :
sickbeard . COMING_EPS_SORT = ' date '
2014-06-11 08:34:28 +00:00
sickbeard . COMING_EPS_LAYOUT = layout
2014-06-30 01:54:41 +00:00
redirect ( " /comingEpisodes/ " )
2014-06-11 08:34:28 +00:00
def toggleComingEpsDisplayPaused ( self , * args , * * kwargs ) :
sickbeard . COMING_EPS_DISPLAY_PAUSED = not sickbeard . COMING_EPS_DISPLAY_PAUSED
2014-06-30 01:54:41 +00:00
redirect ( " /comingEpisodes/ " )
2014-06-11 08:34:28 +00:00
def setComingEpsSort ( self , sort ) :
if sort not in ( ' date ' , ' network ' , ' show ' ) :
sort = ' date '
2014-09-15 17:43:49 +00:00
if sickbeard . COMING_EPS_LAYOUT == ' calendar ' :
sort = ' date '
2014-06-11 08:34:28 +00:00
sickbeard . COMING_EPS_SORT = sort
2014-06-30 01:54:41 +00:00
redirect ( " /comingEpisodes/ " )
2014-06-11 08:34:28 +00:00
def comingEpisodes ( self , layout = " None " ) :
today1 = datetime . date . today ( )
today = today1 . toordinal ( )
next_week1 = ( datetime . date . today ( ) + datetime . timedelta ( days = 7 ) )
next_week = next_week1 . toordinal ( )
recently = ( datetime . date . today ( ) - datetime . timedelta ( days = sickbeard . COMING_EPS_MISSED_RANGE ) ) . toordinal ( )
done_show_list = [ ]
qualList = Quality . DOWNLOADED + Quality . SNATCHED + [ ARCHIVED , IGNORED ]
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
sql_results = myDB . select (
" SELECT *, tv_shows.status as show_status FROM tv_episodes, tv_shows WHERE season != 0 AND airdate >= ? AND airdate < ? AND tv_shows.indexer_id = tv_episodes.showid AND tv_episodes.status NOT IN ( " + ' , ' . join (
[ ' ? ' ] * len ( qualList ) ) + " ) " , [ today , next_week ] + qualList )
2014-06-11 08:34:28 +00:00
2014-06-21 22:46:59 +00:00
for cur_result in sql_results :
done_show_list . append ( int ( cur_result [ " showid " ] ) )
2014-06-11 08:34:28 +00:00
2014-06-21 22:46:59 +00:00
more_sql_results = myDB . select (
" SELECT *, tv_shows.status as show_status FROM tv_episodes outer_eps, tv_shows WHERE season != 0 AND showid NOT IN ( " + ' , ' . join (
[ ' ? ' ] * len (
done_show_list ) ) + " ) AND tv_shows.indexer_id = outer_eps.showid AND airdate = (SELECT airdate FROM tv_episodes inner_eps WHERE inner_eps.season != 0 AND inner_eps.showid = outer_eps.showid AND inner_eps.airdate >= ? ORDER BY inner_eps.airdate ASC LIMIT 1) AND outer_eps.status NOT IN ( " + ' , ' . join (
[ ' ? ' ] * len ( Quality . DOWNLOADED + Quality . SNATCHED ) ) + " ) " ,
done_show_list + [ next_week ] + Quality . DOWNLOADED + Quality . SNATCHED )
sql_results + = more_sql_results
2014-06-11 08:34:28 +00:00
2014-06-21 22:46:59 +00:00
more_sql_results = myDB . select (
" SELECT *, tv_shows.status as show_status FROM tv_episodes, tv_shows WHERE season != 0 AND tv_shows.indexer_id = tv_episodes.showid AND airdate < ? AND airdate >= ? AND tv_episodes.status = ? AND tv_episodes.status NOT IN ( " + ' , ' . join (
[ ' ? ' ] * len ( qualList ) ) + " ) " , [ today , recently , WANTED ] + qualList )
sql_results + = more_sql_results
2014-06-11 08:34:28 +00:00
# sort by localtime
sorts = {
' date ' : ( lambda x , y : cmp ( x [ " localtime " ] , y [ " localtime " ] ) ) ,
' show ' : ( lambda a , b : cmp ( ( a [ " show_name " ] , a [ " localtime " ] ) , ( b [ " show_name " ] , b [ " localtime " ] ) ) ) ,
' network ' : ( lambda a , b : cmp ( ( a [ " network " ] , a [ " localtime " ] ) , ( b [ " network " ] , b [ " localtime " ] ) ) ) ,
}
# make a dict out of the sql results
sql_results = [ dict ( row ) for row in sql_results ]
# add localtime to the dict
for index , item in enumerate ( sql_results ) :
sql_results [ index ] [ ' localtime ' ] = network_timezones . parse_date_time ( item [ ' airdate ' ] , item [ ' airs ' ] ,
item [ ' network ' ] )
sql_results . sort ( sorts [ sickbeard . COMING_EPS_SORT ] )
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " comingEpisodes.tmpl " )
2014-06-11 08:34:28 +00:00
# paused_item = { 'title': '', 'path': 'toggleComingEpsDisplayPaused' }
# paused_item['title'] = 'Hide Paused' if sickbeard.COMING_EPS_DISPLAY_PAUSED else 'Show Paused'
paused_item = { ' title ' : ' View Paused: ' , ' path ' : { ' ' : ' ' } }
paused_item [ ' path ' ] = { ' Hide ' : ' toggleComingEpsDisplayPaused ' } if sickbeard . COMING_EPS_DISPLAY_PAUSED else {
' Show ' : ' toggleComingEpsDisplayPaused ' }
t . submenu = [
{ ' title ' : ' Sort by: ' , ' path ' : { ' Date ' : ' setComingEpsSort/?sort=date ' ,
' Show ' : ' setComingEpsSort/?sort=show ' ,
' Network ' : ' setComingEpsSort/?sort=network ' ,
} } ,
{ ' title ' : ' Layout: ' , ' path ' : { ' Banner ' : ' setComingEpsLayout/?layout=banner ' ,
' Poster ' : ' setComingEpsLayout/?layout=poster ' ,
' List ' : ' setComingEpsLayout/?layout=list ' ,
2014-09-15 17:43:49 +00:00
' Calendar ' : ' setComingEpsLayout/?layout=calendar ' ,
2014-06-11 08:34:28 +00:00
} } ,
paused_item ,
]
t . next_week = datetime . datetime . combine ( next_week1 , datetime . time ( tzinfo = network_timezones . sb_timezone ) )
t . today = datetime . datetime . now ( ) . replace ( tzinfo = network_timezones . sb_timezone )
t . sql_results = sql_results
# Allow local overriding of layout parameter
2014-09-15 17:43:49 +00:00
if layout and layout in ( ' poster ' , ' banner ' , ' list ' , ' calendar ' ) :
2014-06-11 08:34:28 +00:00
t . layout = layout
else :
t . layout = sickbeard . COMING_EPS_LAYOUT
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
# Raw iCalendar implementation by Pedro Jose Pereira Vieito (@pvieito).
#
# iCalendar (iCal) - Standard RFC 5545 <http://tools.ietf.org/html/rfc5546>
# Works with iCloud, Google Calendar and Outlook.
def calendar ( self , * args , * * kwargs ) :
""" Provides a subscribeable URL for iCal subscriptions
"""
2014-06-16 05:45:52 +00:00
logger . log ( u " Receiving iCal request from %s " % self . request . remote_ip )
2014-06-11 08:34:28 +00:00
# Create a iCal string
ical = ' BEGIN:VCALENDAR \r \n '
ical + = ' VERSION:2.0 \r \n '
ical + = ' X-WR-CALNAME:SickRage \r \n '
ical + = ' X-WR-CALDESC:SickRage \r \n '
ical + = ' PRODID://Sick-Beard Upcoming Episodes// \r \n '
2014-06-07 12:36:50 +00:00
2014-06-11 08:34:28 +00:00
# Limit dates
past_date = ( datetime . date . today ( ) + datetime . timedelta ( weeks = - 52 ) ) . toordinal ( )
future_date = ( datetime . date . today ( ) + datetime . timedelta ( weeks = 52 ) ) . toordinal ( )
# Get all the shows that are not paused and are currently on air (from kjoconnor Fork)
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
calendar_shows = myDB . select (
" SELECT show_name, indexer_id, network, airs, runtime FROM tv_shows WHERE ( status = ' Continuing ' OR status = ' Returning Series ' ) AND paused != ' 1 ' " )
for show in calendar_shows :
# Get all episodes of this show airing between today and next month
episode_list = myDB . select (
" SELECT indexerid, name, season, episode, description, airdate FROM tv_episodes WHERE airdate >= ? AND airdate < ? AND showid = ? " ,
( past_date , future_date , int ( show [ " indexer_id " ] ) ) )
utc = tz . gettz ( ' GMT ' )
for episode in episode_list :
air_date_time = network_timezones . parse_date_time ( episode [ ' airdate ' ] , show [ " airs " ] ,
show [ ' network ' ] ) . astimezone ( utc )
air_date_time_end = air_date_time + datetime . timedelta (
minutes = helpers . tryInt ( show [ " runtime " ] , 60 ) )
# Create event for episode
ical = ical + ' BEGIN:VEVENT \r \n '
ical = ical + ' DTSTART: ' + air_date_time . strftime ( " % Y % m %d " ) + ' T ' + air_date_time . strftime (
" % H % M % S " ) + ' Z \r \n '
ical = ical + ' DTEND: ' + air_date_time_end . strftime (
" % Y % m %d " ) + ' T ' + air_date_time_end . strftime (
" % H % M % S " ) + ' Z \r \n '
2014-10-07 11:55:58 +00:00
ical = ical + ' SUMMARY: ' + show [ ' show_name ' ] + ' - ' + str (
episode [ ' season ' ] ) + " x " + str ( episode [ ' episode ' ] ) + " - " + episode [ ' name ' ] + ' \r \n '
2014-06-21 22:46:59 +00:00
ical = ical + ' UID:Sick-Beard- ' + str ( datetime . date . today ( ) . isoformat ( ) ) + ' - ' + show [
' show_name ' ] . replace ( " " , " - " ) + ' -E ' + str ( episode [ ' episode ' ] ) + ' S ' + str (
episode [ ' season ' ] ) + ' \r \n '
if ( episode [ ' description ' ] is not None and episode [ ' description ' ] != ' ' ) :
ical = ical + ' DESCRIPTION: ' + show [ ' airs ' ] + ' on ' + show [ ' network ' ] + ' \\ n \\ n ' + \
episode [ ' description ' ] . splitlines ( ) [ 0 ] + ' \r \n '
else :
2014-10-02 00:31:13 +00:00
ical = ical + ' DESCRIPTION: ' + ( show [ ' airs ' ] or ' (Unknown airs) ' ) + ' on ' + ( show [ ' network ' ] or ' Unknown network ' ) + ' \r \n '
2014-10-07 11:55:58 +00:00
2014-06-21 22:46:59 +00:00
ical = ical + ' END:VEVENT \r \n '
2014-06-11 08:34:28 +00:00
# Ending the iCal
ical + = ' END:VCALENDAR '
return ical
2014-06-30 01:54:41 +00:00
def _genericMessage ( self , subject , message ) :
t = PageTemplate ( headers = self . request . headers , file = " genericMessage.tmpl " )
t . submenu = HomeMenu ( )
t . subject = subject
t . message = message
return _munge ( t )
2014-06-11 08:34:28 +00:00
browser = WebFileBrowser
2014-03-10 05:18:05 +00:00
2014-07-01 08:49:12 +00:00
2014-03-25 05:57:24 +00:00
class PageTemplate ( Template ) :
2014-06-30 01:54:41 +00:00
def __init__ ( self , headers , * args , * * KWs ) :
2014-07-08 03:27:24 +00:00
KWs [ ' file ' ] = os . path . join ( sickbeard . PROG_DIR , " gui/ " + sickbeard . GUI_NAME + " /interfaces/default/ " ,
KWs [ ' file ' ] )
2014-03-10 05:18:05 +00:00
super ( PageTemplate , self ) . __init__ ( * args , * * KWs )
2014-06-16 05:45:52 +00:00
2014-03-10 05:18:05 +00:00
self . sbRoot = sickbeard . WEB_ROOT
self . sbHttpPort = sickbeard . WEB_PORT
self . sbHttpsPort = sickbeard . WEB_PORT
self . sbHttpsEnabled = sickbeard . ENABLE_HTTPS
2014-05-13 09:58:27 +00:00
self . sbHandleReverseProxy = sickbeard . HANDLE_REVERSE_PROXY
2014-10-28 04:27:25 +00:00
self . sbThemeName = sickbeard . THEME_NAME
2014-05-13 09:58:27 +00:00
2014-06-30 01:54:41 +00:00
if headers [ ' Host ' ] [ 0 ] == ' [ ' :
self . sbHost = re . match ( " ^ \ [.* \ ] " , headers [ ' Host ' ] , re . X | re . M | re . S ) . group ( 0 )
2014-06-16 05:45:52 +00:00
else :
2014-06-30 01:54:41 +00:00
self . sbHost = re . match ( " ^[^:]+ " , headers [ ' Host ' ] , re . X | re . M | re . S ) . group ( 0 )
2014-06-16 05:45:52 +00:00
2014-06-30 01:54:41 +00:00
if " X-Forwarded-Host " in headers :
self . sbHost = headers [ ' X-Forwarded-Host ' ]
if " X-Forwarded-Port " in headers :
sbHttpPort = headers [ ' X-Forwarded-Port ' ]
2014-06-16 05:45:52 +00:00
self . sbHttpsPort = sbHttpPort
2014-06-30 01:54:41 +00:00
if " X-Forwarded-Proto " in headers :
self . sbHttpsEnabled = True if headers [ ' X-Forwarded-Proto ' ] == ' https ' else False
2014-06-16 05:45:52 +00:00
2014-03-10 05:18:05 +00:00
logPageTitle = ' Logs & Errors '
if len ( classes . ErrorViewer . errors ) :
logPageTitle + = ' ( ' + str ( len ( classes . ErrorViewer . errors ) ) + ' ) '
self . logPageTitle = logPageTitle
self . sbPID = str ( sickbeard . PID )
self . menu = [
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Home ' , ' key ' : ' home ' } ,
{ ' title ' : ' Coming Episodes ' , ' key ' : ' comingEpisodes ' } ,
{ ' title ' : ' History ' , ' key ' : ' history ' } ,
{ ' title ' : ' Manage ' , ' key ' : ' manage ' } ,
{ ' title ' : ' Config ' , ' key ' : ' config ' } ,
{ ' title ' : logPageTitle , ' key ' : ' errorlogs ' } ,
2014-07-01 08:49:12 +00:00
]
2014-03-10 05:18:05 +00:00
2014-07-06 14:45:01 +00:00
def compile ( self , * args , * * kwargs ) :
if not os . path . exists ( os . path . join ( sickbeard . CACHE_DIR , ' cheetah ' ) ) :
os . mkdir ( os . path . join ( sickbeard . CACHE_DIR , ' cheetah ' ) )
kwargs [ ' cacheModuleFilesForTracebacks ' ] = True
kwargs [ ' cacheDirForModuleFiles ' ] = os . path . join ( sickbeard . CACHE_DIR , ' cheetah ' )
return super ( PageTemplate , self ) . compile ( * args , * * kwargs )
2014-03-10 05:18:05 +00:00
2014-07-08 03:27:24 +00:00
2014-06-19 08:37:44 +00:00
class IndexerWebUI ( MainHandler ) :
2014-03-10 05:18:05 +00:00
def __init__ ( self , config , log = None ) :
self . config = config
self . log = log
def selectSeries ( self , allSeries ) :
searchList = " , " . join ( [ x [ ' id ' ] for x in allSeries ] )
showDirList = " "
for curShowDir in self . config [ ' _showDir ' ] :
showDirList + = " showDir= " + curShowDir + " & "
2014-06-30 01:54:41 +00:00
redirect ( " /home/addShows/addShow? " + showDirList + " seriesList= " + searchList )
2014-03-10 05:18:05 +00:00
def _munge ( string ) :
2014-06-29 10:05:33 +00:00
return unicode ( string ) . encode ( ' utf-8 ' , ' xmlcharrefreplace ' )
2014-03-10 05:18:05 +00:00
2014-07-06 14:45:01 +00:00
2014-05-30 05:48:02 +00:00
def _getEpisode ( show , season = None , episode = None , absolute = None ) :
if show is None :
return " Invalid show parameters "
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-05-30 14:36:06 +00:00
return " Invalid show paramaters "
2014-03-10 05:18:05 +00:00
2014-05-30 14:36:06 +00:00
if absolute :
2014-08-17 19:17:20 +00:00
epObj = showObj . getEpisode ( absolute_number = int ( absolute ) )
2014-05-30 14:36:06 +00:00
elif season and episode :
2014-05-30 05:48:02 +00:00
epObj = showObj . getEpisode ( int ( season ) , int ( episode ) )
2014-05-30 14:36:06 +00:00
else :
return " Invalid paramaters "
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if epObj is None :
2014-03-10 05:18:05 +00:00
return " Episode couldn ' t be retrieved "
return epObj
2014-06-17 19:51:23 +00:00
2014-03-10 05:18:05 +00:00
def ManageMenu ( ) :
manageMenu = [
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Backlog Overview ' , ' path ' : ' manage/backlogOverview/ ' } ,
{ ' title ' : ' Manage Searches ' , ' path ' : ' manage/manageSearches/ ' } ,
{ ' title ' : ' Episode Status Management ' , ' path ' : ' manage/episodeStatuses/ ' } , ]
2014-03-10 05:18:05 +00:00
if sickbeard . USE_TORRENTS and sickbeard . TORRENT_METHOD != ' blackhole ' \
2014-03-25 05:57:24 +00:00
and ( sickbeard . ENABLE_HTTPS and sickbeard . TORRENT_HOST [ : 5 ] == ' https '
2014-03-27 02:01:53 +00:00
or not sickbeard . ENABLE_HTTPS and sickbeard . TORRENT_HOST [ : 5 ] == ' http: ' ) :
2014-03-25 05:57:24 +00:00
manageMenu . append ( { ' title ' : ' Manage Torrents ' , ' path ' : ' manage/manageTorrents/ ' } )
2014-03-10 05:18:05 +00:00
if sickbeard . USE_SUBTITLES :
2014-03-25 05:57:24 +00:00
manageMenu . append ( { ' title ' : ' Missed Subtitle Management ' , ' path ' : ' manage/subtitleMissed/ ' } )
2014-03-10 05:18:05 +00:00
if sickbeard . USE_FAILED_DOWNLOADS :
2014-03-25 05:57:24 +00:00
manageMenu . append ( { ' title ' : ' Failed Downloads ' , ' path ' : ' manage/failedDownloads/ ' } )
2014-03-10 05:18:05 +00:00
return manageMenu
2014-06-19 08:37:44 +00:00
class ManageSearches ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_manageSearches.tmpl " )
2014-06-07 12:36:50 +00:00
# t.backlogPI = sickbeard.backlogSearchScheduler.action.getProgressIndicator()
2014-03-25 05:57:24 +00:00
t . backlogPaused = sickbeard . searchQueueScheduler . action . is_backlog_paused ( ) # @UndefinedVariable
t . backlogRunning = sickbeard . searchQueueScheduler . action . is_backlog_in_progress ( ) # @UndefinedVariable
2014-05-26 21:09:14 +00:00
t . dailySearchStatus = sickbeard . dailySearchScheduler . action . amActive # @UndefinedVariable
2014-05-19 17:40:25 +00:00
t . findPropersStatus = sickbeard . properFinderScheduler . action . amActive # @UndefinedVariable
2014-09-08 02:48:48 +00:00
t . queueLength = sickbeard . searchQueueScheduler . action . queue_length ( )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
t . submenu = ManageMenu ( )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-05-15 22:06:13 +00:00
2014-07-27 17:58:19 +00:00
def forceVersionCheck ( self , * args , * * kwargs ) :
# force a check to see if there is a new version
if sickbeard . versionCheckScheduler . action . check_for_new_version ( force = True ) :
logger . log ( u " Forcing version check " )
redirect ( " /home/ " )
2014-06-11 08:34:28 +00:00
def forceBacklog ( self , * args , * * kwargs ) :
2014-05-15 22:06:13 +00:00
# force it to run the next time it looks
result = sickbeard . backlogSearchScheduler . forceRun ( )
if result :
logger . log ( u " Backlog search forced " )
ui . notifications . message ( ' Backlog search started ' )
2014-06-30 01:54:41 +00:00
redirect ( " /manage/manageSearches/ " )
2014-05-15 22:06:13 +00:00
2014-06-11 08:34:28 +00:00
def forceSearch ( self , * args , * * kwargs ) :
2014-05-15 04:16:46 +00:00
# force it to run the next time it looks
result = sickbeard . dailySearchScheduler . forceRun ( )
if result :
logger . log ( u " Daily search forced " )
2014-05-19 17:40:25 +00:00
ui . notifications . message ( ' Daily search started ' )
2014-06-30 01:54:41 +00:00
redirect ( " /manage/manageSearches/ " )
2014-06-11 08:34:28 +00:00
2014-05-19 17:40:25 +00:00
2014-06-11 08:34:28 +00:00
def forceFindPropers ( self , * args , * * kwargs ) :
2014-05-19 17:40:25 +00:00
# force it to run the next time it looks
result = sickbeard . properFinderScheduler . forceRun ( )
if result :
logger . log ( u " Find propers search forced " )
ui . notifications . message ( ' Find propers search started ' )
2014-05-15 21:43:45 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /manage/manageSearches/ " )
2014-06-11 08:34:28 +00:00
2014-05-15 21:43:45 +00:00
2014-03-10 05:18:05 +00:00
def pauseBacklog ( self , paused = None ) :
if paused == " 1 " :
2014-03-25 05:57:24 +00:00
sickbeard . searchQueueScheduler . action . pause_backlog ( ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
else :
2014-03-25 05:57:24 +00:00
sickbeard . searchQueueScheduler . action . unpause_backlog ( ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /manage/manageSearches/ " )
2014-06-11 08:34:28 +00:00
2014-06-17 19:51:23 +00:00
2014-06-19 08:37:44 +00:00
class Manage ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ManageMenu ( )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
def showEpisodeStatuses ( self , indexer_id , whichStatus ) :
status_list = [ int ( whichStatus ) ]
if status_list [ 0 ] == SNATCHED :
status_list = Quality . SNATCHED + Quality . SNATCHED_PROPER
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
cur_show_results = myDB . select (
" SELECT season, episode, name FROM tv_episodes WHERE showid = ? AND season != 0 AND status IN ( " + ' , ' . join (
[ ' ? ' ] * len ( status_list ) ) + " ) " , [ int ( indexer_id ) ] + status_list )
2014-03-10 05:18:05 +00:00
result = { }
for cur_result in cur_show_results :
cur_season = int ( cur_result [ " season " ] )
cur_episode = int ( cur_result [ " episode " ] )
if cur_season not in result :
result [ cur_season ] = { }
result [ cur_season ] [ cur_episode ] = cur_result [ " name " ]
return json . dumps ( result )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def episodeStatuses ( self , whichStatus = None ) :
if whichStatus :
whichStatus = int ( whichStatus )
status_list = [ whichStatus ]
if status_list [ 0 ] == SNATCHED :
status_list = Quality . SNATCHED + Quality . SNATCHED_PROPER
else :
status_list = [ ]
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_episodeStatuses.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ManageMenu ( )
t . whichStatus = whichStatus
# if we have no status then this is as far as we need to go
if not status_list :
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
status_results = myDB . select (
" SELECT show_name, tv_shows.indexer_id as indexer_id FROM tv_episodes, tv_shows WHERE tv_episodes.status IN ( " + ' , ' . join (
[ ' ? ' ] * len (
status_list ) ) + " ) AND season != 0 AND tv_episodes.showid = tv_shows.indexer_id ORDER BY show_name " ,
status_list )
2014-03-10 05:18:05 +00:00
ep_counts = { }
show_names = { }
sorted_show_ids = [ ]
for cur_status_result in status_results :
cur_indexer_id = int ( cur_status_result [ " indexer_id " ] )
if cur_indexer_id not in ep_counts :
ep_counts [ cur_indexer_id ] = 1
else :
ep_counts [ cur_indexer_id ] + = 1
show_names [ cur_indexer_id ] = cur_status_result [ " show_name " ]
if cur_indexer_id not in sorted_show_ids :
sorted_show_ids . append ( cur_indexer_id )
t . show_names = show_names
t . ep_counts = ep_counts
t . sorted_show_ids = sorted_show_ids
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def changeEpisodeStatuses ( self , oldStatus , newStatus , * args , * * kwargs ) :
status_list = [ int ( oldStatus ) ]
if status_list [ 0 ] == SNATCHED :
status_list = Quality . SNATCHED + Quality . SNATCHED_PROPER
to_change = { }
# make a list of all shows and their associated args
for arg in kwargs :
indexer_id , what = arg . split ( ' - ' )
# we don't care about unchecked checkboxes
if kwargs [ arg ] != ' on ' :
continue
if indexer_id not in to_change :
to_change [ indexer_id ] = [ ]
to_change [ indexer_id ] . append ( what )
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
for cur_indexer_id in to_change :
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
# get a list of all the eps we want to change if they just said "all"
if ' all ' in to_change [ cur_indexer_id ] :
all_eps_results = myDB . select (
" SELECT season, episode FROM tv_episodes WHERE status IN ( " + ' , ' . join (
[ ' ? ' ] * len ( status_list ) ) + " ) AND season != 0 AND showid = ? " ,
status_list + [ cur_indexer_id ] )
all_eps = [ str ( x [ " season " ] ) + ' x ' + str ( x [ " episode " ] ) for x in all_eps_results ]
to_change [ cur_indexer_id ] = all_eps
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
Home ( self . application , self . request ) . setStatus ( cur_indexer_id , ' | ' . join ( to_change [ cur_indexer_id ] ) ,
newStatus , direct = True )
2014-06-11 08:34:28 +00:00
2014-06-30 01:54:41 +00:00
redirect ( ' /manage/episodeStatuses/ ' )
2014-03-10 05:18:05 +00:00
def showSubtitleMissed ( self , indexer_id , whichSubs ) :
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
cur_show_results = myDB . select (
" SELECT season, episode, name, subtitles FROM tv_episodes WHERE showid = ? AND season != 0 AND status LIKE ' % 4 ' " ,
[ int ( indexer_id ) ] )
2014-03-10 05:18:05 +00:00
result = { }
for cur_result in cur_show_results :
if whichSubs == ' all ' :
2014-03-25 05:57:24 +00:00
if len ( set ( cur_result [ " subtitles " ] . split ( ' , ' ) ) . intersection ( set ( subtitles . wantedLanguages ( ) ) ) ) > = len (
subtitles . wantedLanguages ( ) ) :
2014-03-10 05:18:05 +00:00
continue
elif whichSubs in cur_result [ " subtitles " ] . split ( ' , ' ) :
continue
cur_season = int ( cur_result [ " season " ] )
cur_episode = int ( cur_result [ " episode " ] )
if cur_season not in result :
result [ cur_season ] = { }
if cur_episode not in result [ cur_season ] :
result [ cur_season ] [ cur_episode ] = { }
result [ cur_season ] [ cur_episode ] [ " name " ] = cur_result [ " name " ]
2014-03-25 05:57:24 +00:00
result [ cur_season ] [ cur_episode ] [ " subtitles " ] = " , " . join (
subliminal . language . Language ( subtitle ) . alpha2 for subtitle in cur_result [ " subtitles " ] . split ( ' , ' ) ) if not \
2014-03-27 02:01:53 +00:00
cur_result [ " subtitles " ] == ' ' else ' '
2014-03-10 05:18:05 +00:00
return json . dumps ( result )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def subtitleMissed ( self , whichSubs = None ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_subtitleMissed.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ManageMenu ( )
t . whichSubs = whichSubs
if not whichSubs :
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
status_results = myDB . select (
" SELECT show_name, tv_shows.indexer_id as indexer_id, tv_episodes.subtitles subtitles FROM tv_episodes, tv_shows WHERE tv_shows.subtitles = 1 AND tv_episodes.status LIKE ' % 4 ' AND tv_episodes.season != 0 AND tv_episodes.showid = tv_shows.indexer_id ORDER BY show_name " )
2014-03-10 05:18:05 +00:00
ep_counts = { }
show_names = { }
sorted_show_ids = [ ]
for cur_status_result in status_results :
if whichSubs == ' all ' :
2014-03-25 05:57:24 +00:00
if len ( set ( cur_status_result [ " subtitles " ] . split ( ' , ' ) ) . intersection (
set ( subtitles . wantedLanguages ( ) ) ) ) > = len ( subtitles . wantedLanguages ( ) ) :
2014-03-10 05:18:05 +00:00
continue
elif whichSubs in cur_status_result [ " subtitles " ] . split ( ' , ' ) :
continue
cur_indexer_id = int ( cur_status_result [ " indexer_id " ] )
if cur_indexer_id not in ep_counts :
ep_counts [ cur_indexer_id ] = 1
else :
ep_counts [ cur_indexer_id ] + = 1
show_names [ cur_indexer_id ] = cur_status_result [ " show_name " ]
if cur_indexer_id not in sorted_show_ids :
sorted_show_ids . append ( cur_indexer_id )
t . show_names = show_names
t . ep_counts = ep_counts
t . sorted_show_ids = sorted_show_ids
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def downloadSubtitleMissed ( self , * args , * * kwargs ) :
to_download = { }
# make a list of all shows and their associated args
for arg in kwargs :
indexer_id , what = arg . split ( ' - ' )
# we don't care about unchecked checkboxes
if kwargs [ arg ] != ' on ' :
continue
if indexer_id not in to_download :
to_download [ indexer_id ] = [ ]
to_download [ indexer_id ] . append ( what )
for cur_indexer_id in to_download :
# get a list of all the eps we want to download subtitles if they just said "all"
if ' all ' in to_download [ cur_indexer_id ] :
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
all_eps_results = myDB . select (
" SELECT season, episode FROM tv_episodes WHERE status LIKE ' % 4 ' AND season != 0 AND showid = ? " ,
[ cur_indexer_id ] )
2014-03-10 05:18:05 +00:00
to_download [ cur_indexer_id ] = [ str ( x [ " season " ] ) + ' x ' + str ( x [ " episode " ] ) for x in all_eps_results ]
for epResult in to_download [ cur_indexer_id ] :
2014-05-30 05:48:02 +00:00
season , episode = epResult . split ( ' x ' )
2014-03-10 05:18:05 +00:00
show = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( cur_indexer_id ) )
subtitles = show . getEpisode ( int ( season ) , int ( episode ) ) . downloadSubtitles ( )
2014-06-30 01:54:41 +00:00
redirect ( ' /manage/subtitleMissed/ ' )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def backlogShow ( self , indexer_id ) :
show_obj = helpers . findCertainShow ( sickbeard . showList , int ( indexer_id ) )
if show_obj :
2014-03-25 05:57:24 +00:00
sickbeard . backlogSearchScheduler . action . searchBacklog ( [ show_obj ] ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /manage/backlogOverview/ " )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def backlogOverview ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_backlogOverview.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ManageMenu ( )
showCounts = { }
showCats = { }
showSQLResults = { }
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
for curShow in sickbeard . showList :
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
epCounts = { }
epCats = { }
epCounts [ Overview . SKIPPED ] = 0
epCounts [ Overview . WANTED ] = 0
epCounts [ Overview . QUAL ] = 0
epCounts [ Overview . GOOD ] = 0
epCounts [ Overview . UNAIRED ] = 0
epCounts [ Overview . SNATCHED ] = 0
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
sqlResults = myDB . select (
" SELECT * FROM tv_episodes WHERE showid = ? ORDER BY season DESC, episode DESC " ,
[ curShow . indexerid ] )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
for curResult in sqlResults :
curEpCat = curShow . getOverview ( int ( curResult [ " status " ] ) )
2014-06-22 05:03:59 +00:00
if curEpCat :
epCats [ str ( curResult [ " season " ] ) + " x " + str ( curResult [ " episode " ] ) ] = curEpCat
epCounts [ curEpCat ] + = 1
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
showCounts [ curShow . indexerid ] = epCounts
showCats [ curShow . indexerid ] = epCats
showSQLResults [ curShow . indexerid ] = sqlResults
2014-03-10 05:18:05 +00:00
t . showCounts = showCounts
t . showCats = showCats
t . showSQLResults = showSQLResults
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def massEdit ( self , toEdit = None ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_massEdit.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ManageMenu ( )
if not toEdit :
2014-06-30 01:54:41 +00:00
redirect ( " /manage/ " )
2014-03-10 05:18:05 +00:00
showIDs = toEdit . split ( " | " )
showList = [ ]
for curID in showIDs :
curID = int ( curID )
showObj = helpers . findCertainShow ( sickbeard . showList , curID )
if showObj :
showList . append ( showObj )
2014-10-16 20:45:07 +00:00
archive_firstmatch_all_same = True
last_archive_firstmatch = None
2014-03-10 05:18:05 +00:00
flatten_folders_all_same = True
last_flatten_folders = None
paused_all_same = True
last_paused = None
2014-05-26 06:29:22 +00:00
anime_all_same = True
last_anime = None
2014-07-31 02:32:12 +00:00
sports_all_same = True
last_sports = None
2014-03-10 05:18:05 +00:00
quality_all_same = True
last_quality = None
subtitles_all_same = True
last_subtitles = None
2014-05-30 06:22:01 +00:00
scene_all_same = True
last_scene = None
2014-07-31 02:32:12 +00:00
air_by_date_all_same = True
last_air_by_date = None
2014-03-10 05:18:05 +00:00
root_dir_list = [ ]
for curShow in showList :
cur_root_dir = ek . ek ( os . path . dirname , curShow . _location )
if cur_root_dir not in root_dir_list :
root_dir_list . append ( cur_root_dir )
2014-10-16 20:45:07 +00:00
if archive_firstmatch_all_same :
# if we had a value already and this value is different then they're not all the same
if last_archive_firstmatch not in ( None , curShow . archive_firstmatch ) :
archive_firstmatch_all_same = False
else :
last_archive_firstmatch = curShow . archive_firstmatch
2014-03-10 05:18:05 +00:00
# if we know they're not all the same then no point even bothering
if paused_all_same :
# if we had a value already and this value is different then they're not all the same
2014-07-31 02:32:12 +00:00
if last_paused not in ( None , curShow . paused ) :
2014-03-10 05:18:05 +00:00
paused_all_same = False
else :
last_paused = curShow . paused
2014-05-26 06:29:22 +00:00
if anime_all_same :
# if we had a value already and this value is different then they're not all the same
2014-07-31 02:32:12 +00:00
if last_anime not in ( None , curShow . is_anime ) :
2014-05-26 06:29:22 +00:00
anime_all_same = False
else :
2014-07-31 02:32:12 +00:00
last_anime = curShow . anime
2014-05-26 06:29:22 +00:00
2014-03-10 05:18:05 +00:00
if flatten_folders_all_same :
if last_flatten_folders not in ( None , curShow . flatten_folders ) :
flatten_folders_all_same = False
else :
last_flatten_folders = curShow . flatten_folders
if quality_all_same :
if last_quality not in ( None , curShow . quality ) :
quality_all_same = False
else :
last_quality = curShow . quality
if subtitles_all_same :
if last_subtitles not in ( None , curShow . subtitles ) :
subtitles_all_same = False
else :
last_subtitles = curShow . subtitles
2014-05-30 06:22:01 +00:00
if scene_all_same :
if last_scene not in ( None , curShow . scene ) :
scene_all_same = False
else :
last_scene = curShow . scene
2014-07-31 02:32:12 +00:00
if sports_all_same :
if last_sports not in ( None , curShow . sports ) :
sports_all_same = False
else :
last_sports = curShow . sports
if air_by_date_all_same :
if last_air_by_date not in ( None , curShow . air_by_date ) :
air_by_date_all_same = False
else :
last_air_by_date = curShow . air_by_date
2014-03-10 05:18:05 +00:00
t . showList = toEdit
2014-10-16 20:45:07 +00:00
t . archive_firstmatch_value = last_archive_firstmatch if archive_firstmatch_all_same else None
2014-03-10 05:18:05 +00:00
t . paused_value = last_paused if paused_all_same else None
2014-05-26 06:29:22 +00:00
t . anime_value = last_anime if anime_all_same else None
2014-03-10 05:18:05 +00:00
t . flatten_folders_value = last_flatten_folders if flatten_folders_all_same else None
t . quality_value = last_quality if quality_all_same else None
t . subtitles_value = last_subtitles if subtitles_all_same else None
2014-05-30 06:22:01 +00:00
t . scene_value = last_scene if scene_all_same else None
2014-07-31 02:32:12 +00:00
t . sports_value = last_sports if sports_all_same else None
t . air_by_date_value = last_air_by_date if air_by_date_all_same else None
2014-03-10 05:18:05 +00:00
t . root_dir_list = root_dir_list
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
2014-10-16 20:45:07 +00:00
def massEditSubmit ( self , archive_firstmatch = None , paused = None , anime = None , sports = None , scene = None , flatten_folders = None ,
2014-08-29 10:29:56 +00:00
quality_preset = False ,
subtitles = None , air_by_date = None , anyQualities = [ ] , bestQualities = [ ] , toEdit = None , * args ,
* * kwargs ) :
2014-03-10 05:18:05 +00:00
dir_map = { }
for cur_arg in kwargs :
if not cur_arg . startswith ( ' orig_root_dir_ ' ) :
continue
which_index = cur_arg . replace ( ' orig_root_dir_ ' , ' ' )
end_dir = kwargs [ ' new_root_dir_ ' + which_index ]
dir_map [ kwargs [ cur_arg ] ] = end_dir
showIDs = toEdit . split ( " | " )
errors = [ ]
for curShow in showIDs :
curErrors = [ ]
showObj = helpers . findCertainShow ( sickbeard . showList , int ( curShow ) )
if not showObj :
continue
cur_root_dir = ek . ek ( os . path . dirname , showObj . _location )
cur_show_dir = ek . ek ( os . path . basename , showObj . _location )
if cur_root_dir in dir_map and cur_root_dir != dir_map [ cur_root_dir ] :
new_show_dir = ek . ek ( os . path . join , dir_map [ cur_root_dir ] , cur_show_dir )
2014-03-25 05:57:24 +00:00
logger . log (
u " For show " + showObj . name + " changing dir from " + showObj . _location + " to " + new_show_dir )
2014-03-10 05:18:05 +00:00
else :
new_show_dir = showObj . _location
2014-10-16 20:45:07 +00:00
if archive_firstmatch == ' keep ' :
new_archive_firstmatch = showObj . archive_firstmatch
else :
new_archive_firstmatch = True if archive_firstmatch == ' enable ' else False
new_archive_firstmatch = ' on ' if new_archive_firstmatch else ' off '
2014-03-10 05:18:05 +00:00
if paused == ' keep ' :
new_paused = showObj . paused
else :
new_paused = True if paused == ' enable ' else False
new_paused = ' on ' if new_paused else ' off '
2014-05-26 06:29:22 +00:00
if anime == ' keep ' :
2014-07-31 02:32:12 +00:00
new_anime = showObj . anime
2014-05-26 06:29:22 +00:00
else :
new_anime = True if anime == ' enable ' else False
new_anime = ' on ' if new_anime else ' off '
2014-07-31 02:32:12 +00:00
if sports == ' keep ' :
new_sports = showObj . sports
else :
new_sports = True if sports == ' enable ' else False
new_sports = ' on ' if new_sports else ' off '
2014-06-04 07:34:35 +00:00
if scene == ' keep ' :
2014-06-04 07:35:43 +00:00
new_scene = showObj . is_scene
2014-06-04 07:34:35 +00:00
else :
new_scene = True if scene == ' enable ' else False
new_scene = ' on ' if new_scene else ' off '
2014-07-31 02:32:12 +00:00
if air_by_date == ' keep ' :
new_air_by_date = showObj . air_by_date
else :
new_air_by_date = True if air_by_date == ' enable ' else False
new_air_by_date = ' on ' if new_air_by_date else ' off '
2014-03-10 05:18:05 +00:00
if flatten_folders == ' keep ' :
new_flatten_folders = showObj . flatten_folders
else :
new_flatten_folders = True if flatten_folders == ' enable ' else False
new_flatten_folders = ' on ' if new_flatten_folders else ' off '
if subtitles == ' keep ' :
new_subtitles = showObj . subtitles
else :
new_subtitles = True if subtitles == ' enable ' else False
new_subtitles = ' on ' if new_subtitles else ' off '
if quality_preset == ' keep ' :
anyQualities , bestQualities = Quality . splitQuality ( showObj . quality )
exceptions_list = [ ]
2014-08-29 10:29:56 +00:00
curErrors + = Home ( self . application , self . request ) . editShow ( curShow , new_show_dir , anyQualities ,
bestQualities , exceptions_list ,
2014-10-16 20:45:07 +00:00
archive_firstmatch = new_archive_firstmatch ,
2014-07-06 14:45:01 +00:00
flatten_folders = new_flatten_folders ,
2014-07-31 02:32:12 +00:00
paused = new_paused , sports = new_sports ,
2014-06-27 11:00:16 +00:00
subtitles = new_subtitles , anime = new_anime ,
2014-07-31 02:32:12 +00:00
scene = new_scene , air_by_date = new_air_by_date ,
directCall = True )
2014-03-10 05:18:05 +00:00
if curErrors :
logger . log ( u " Errors: " + str ( curErrors ) , logger . ERROR )
2014-03-25 05:57:24 +00:00
errors . append ( ' <b> %s :</b> \n <ul> ' % showObj . name + ' ' . join (
[ ' <li> %s </li> ' % error for error in curErrors ] ) + " </ul> " )
2014-03-10 05:18:05 +00:00
if len ( errors ) > 0 :
ui . notifications . error ( ' %d error %s while saving changes: ' % ( len ( errors ) , " " if len ( errors ) == 1 else " s " ) ,
2014-03-25 05:57:24 +00:00
" " . join ( errors ) )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /manage/ " )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
2014-08-29 17:05:15 +00:00
def massUpdate ( self , toUpdate = None , toRefresh = None , toRename = None , toDelete = None , toRemove = None , toMetadata = None , toSubtitle = None ) :
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if toUpdate is not None :
2014-03-10 05:18:05 +00:00
toUpdate = toUpdate . split ( ' | ' )
else :
toUpdate = [ ]
2014-03-25 05:57:24 +00:00
if toRefresh is not None :
2014-03-10 05:18:05 +00:00
toRefresh = toRefresh . split ( ' | ' )
else :
toRefresh = [ ]
2014-03-25 05:57:24 +00:00
if toRename is not None :
2014-03-10 05:18:05 +00:00
toRename = toRename . split ( ' | ' )
else :
toRename = [ ]
2014-03-25 05:57:24 +00:00
if toSubtitle is not None :
2014-03-10 05:18:05 +00:00
toSubtitle = toSubtitle . split ( ' | ' )
else :
toSubtitle = [ ]
2014-03-25 05:57:24 +00:00
if toDelete is not None :
2014-03-10 05:18:05 +00:00
toDelete = toDelete . split ( ' | ' )
else :
toDelete = [ ]
2014-08-29 17:05:15 +00:00
if toRemove is not None :
toRemove = toRemove . split ( ' | ' )
else :
toRemove = [ ]
2014-03-25 05:57:24 +00:00
if toMetadata is not None :
2014-03-10 05:18:05 +00:00
toMetadata = toMetadata . split ( ' | ' )
else :
toMetadata = [ ]
errors = [ ]
refreshes = [ ]
updates = [ ]
renames = [ ]
subtitles = [ ]
2014-08-29 17:05:15 +00:00
for curShowID in set ( toUpdate + toRefresh + toRename + toSubtitle + toDelete + toRemove + toMetadata ) :
2014-03-10 05:18:05 +00:00
if curShowID == ' ' :
continue
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( curShowID ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-03-10 05:18:05 +00:00
continue
if curShowID in toDelete :
2014-08-29 17:05:15 +00:00
showObj . deleteShow ( True )
2014-03-10 05:18:05 +00:00
# don't do anything else if it's being deleted
continue
2014-08-29 17:05:15 +00:00
if curShowID in toRemove :
showObj . deleteShow ( )
# don't do anything else if it's being remove
continue
2014-03-10 05:18:05 +00:00
if curShowID in toUpdate :
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . updateShow ( showObj , True ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
updates . append ( showObj . name )
except exceptions . CantUpdateException , e :
errors . append ( " Unable to update show " + showObj . name + " : " + ex ( e ) )
# don't bother refreshing shows that were updated anyway
if curShowID in toRefresh and curShowID not in toUpdate :
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . refreshShow ( showObj ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
refreshes . append ( showObj . name )
except exceptions . CantRefreshException , e :
errors . append ( " Unable to refresh show " + showObj . name + " : " + ex ( e ) )
if curShowID in toRename :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . renameShowEpisodes ( showObj ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
renames . append ( showObj . name )
if curShowID in toSubtitle :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . downloadSubtitles ( showObj ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
subtitles . append ( showObj . name )
if len ( errors ) > 0 :
ui . notifications . error ( " Errors encountered " ,
2014-03-25 05:57:24 +00:00
' <br > \n ' . join ( errors ) )
2014-03-10 05:18:05 +00:00
messageDetail = " "
if len ( updates ) > 0 :
messageDetail + = " <br /><b>Updates</b><br /><ul><li> "
messageDetail + = " </li><li> " . join ( updates )
messageDetail + = " </li></ul> "
if len ( refreshes ) > 0 :
messageDetail + = " <br /><b>Refreshes</b><br /><ul><li> "
messageDetail + = " </li><li> " . join ( refreshes )
messageDetail + = " </li></ul> "
if len ( renames ) > 0 :
messageDetail + = " <br /><b>Renames</b><br /><ul><li> "
messageDetail + = " </li><li> " . join ( renames )
messageDetail + = " </li></ul> "
if len ( subtitles ) > 0 :
messageDetail + = " <br /><b>Subtitles</b><br /><ul><li> "
messageDetail + = " </li><li> " . join ( subtitles )
messageDetail + = " </li></ul> "
if len ( updates + refreshes + renames + subtitles ) > 0 :
ui . notifications . message ( " The following actions were queued: " ,
2014-03-25 05:57:24 +00:00
messageDetail )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /manage/ " )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def manageTorrents ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_torrents.tmpl " )
2014-03-10 05:18:05 +00:00
t . info_download_station = ' '
t . submenu = ManageMenu ( )
if re . search ( ' localhost ' , sickbeard . TORRENT_HOST ) :
if sickbeard . LOCALHOST_IP == ' ' :
t . webui_url = re . sub ( ' localhost ' , helpers . get_lan_ip ( ) , sickbeard . TORRENT_HOST )
else :
t . webui_url = re . sub ( ' localhost ' , sickbeard . LOCALHOST_IP , sickbeard . TORRENT_HOST )
else :
t . webui_url = sickbeard . TORRENT_HOST
if sickbeard . TORRENT_METHOD == ' utorrent ' :
t . webui_url = ' / ' . join ( s . strip ( ' / ' ) for s in ( t . webui_url , ' gui/ ' ) )
if sickbeard . TORRENT_METHOD == ' download_station ' :
if helpers . check_url ( t . webui_url + ' download/ ' ) :
2014-03-20 18:03:22 +00:00
t . webui_url = t . webui_url + ' download/ '
2014-03-10 05:18:05 +00:00
else :
2014-05-05 09:06:15 +00:00
t . info_download_station = ' <p>To have a better experience please set the Download Station alias as <code>download</code>, you can check this setting in the Synology DSM <b>Control Panel</b> > <b>Application Portal</b>. Make sure you allow DSM to be embedded with iFrames too in <b>Control Panel</b> > <b>DSM Settings</b> > <b>Security</b>.</p><br/><p>There is more information about this available <a href= " https://github.com/midgetspy/Sick-Beard/pull/338 " >here</a>.</p><br/> '
2014-03-10 05:18:05 +00:00
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def failedDownloads ( self , limit = 100 , toRemove = None ) :
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( ' failed.db ' )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
if limit == " 0 " :
sqlResults = myDB . select ( " SELECT * FROM failed " )
else :
sqlResults = myDB . select ( " SELECT * FROM failed LIMIT ? " , [ limit ] )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
toRemove = toRemove . split ( " | " ) if toRemove is not None else [ ]
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
for release in toRemove :
myDB . action ( ' DELETE FROM failed WHERE release = ? ' , [ release ] )
2014-03-10 05:18:05 +00:00
if toRemove :
2014-06-30 01:54:41 +00:00
redirect ( ' /manage/failedDownloads/ ' )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " manage_failedDownloads.tmpl " )
2014-03-10 05:18:05 +00:00
t . failedResults = sqlResults
t . limit = limit
t . submenu = ManageMenu ( )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-19 08:37:44 +00:00
class History ( MainHandler ) :
2014-03-10 05:18:05 +00:00
def index ( self , limit = 100 ) :
2014-06-07 12:36:50 +00:00
# sqlResults = myDB.select("SELECT h.*, show_name, name FROM history h, tv_shows s, tv_episodes e WHERE h.showid=s.indexer_id AND h.showid=e.showid AND h.season=e.season AND h.episode=e.episode ORDER BY date DESC LIMIT "+str(numPerPage*(p-1))+", "+str(numPerPage))
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
if limit == " 0 " :
sqlResults = myDB . select (
" SELECT h.*, show_name FROM history h, tv_shows s WHERE h.showid=s.indexer_id ORDER BY date DESC " )
else :
sqlResults = myDB . select (
" SELECT h.*, show_name FROM history h, tv_shows s WHERE h.showid=s.indexer_id ORDER BY date DESC LIMIT ? " ,
[ limit ] )
2014-03-25 05:57:24 +00:00
history = { ' show_id ' : 0 , ' season ' : 0 , ' episode ' : 0 , ' quality ' : 0 ,
' actions ' : [ { ' time ' : ' ' , ' action ' : ' ' , ' provider ' : ' ' } ] }
compact = [ ]
2014-03-10 05:18:05 +00:00
for sql_result in sqlResults :
2014-03-25 05:57:24 +00:00
2014-04-23 01:58:35 +00:00
if not any ( ( history [ ' show_id ' ] == sql_result [ ' showid ' ]
2014-05-20 20:51:54 +00:00
and history [ ' season ' ] == sql_result [ ' season ' ]
and history [ ' episode ' ] == sql_result [ ' episode ' ]
and history [ ' quality ' ] == sql_result [ ' quality ' ] )
2014-03-25 05:57:24 +00:00
for history in compact ) :
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
history = { }
2014-03-10 05:18:05 +00:00
history [ ' show_id ' ] = sql_result [ ' showid ' ]
history [ ' season ' ] = sql_result [ ' season ' ]
history [ ' episode ' ] = sql_result [ ' episode ' ]
history [ ' quality ' ] = sql_result [ ' quality ' ]
history [ ' show_name ' ] = sql_result [ ' show_name ' ]
history [ ' resource ' ] = sql_result [ ' resource ' ]
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
action = { }
history [ ' actions ' ] = [ ]
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
action [ ' time ' ] = sql_result [ ' date ' ]
action [ ' action ' ] = sql_result [ ' action ' ]
action [ ' provider ' ] = sql_result [ ' provider ' ]
action [ ' resource ' ] = sql_result [ ' resource ' ]
history [ ' actions ' ] . append ( action )
history [ ' actions ' ] . sort ( key = lambda x : x [ ' time ' ] )
compact . append ( history )
else :
index = [ i for i , dict in enumerate ( compact ) \
2014-03-25 05:57:24 +00:00
if dict [ ' show_id ' ] == sql_result [ ' showid ' ] \
2014-06-07 12:36:50 +00:00
and dict [ ' season ' ] == sql_result [ ' season ' ] \
and dict [ ' episode ' ] == sql_result [ ' episode ' ]
and dict [ ' quality ' ] == sql_result [ ' quality ' ] ] [ 0 ]
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
action = { }
history = compact [ index ]
action [ ' time ' ] = sql_result [ ' date ' ]
action [ ' action ' ] = sql_result [ ' action ' ]
action [ ' provider ' ] = sql_result [ ' provider ' ]
action [ ' resource ' ] = sql_result [ ' resource ' ]
history [ ' actions ' ] . append ( action )
history [ ' actions ' ] . sort ( key = lambda x : x [ ' time ' ] , reverse = True )
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " history.tmpl " )
2014-03-10 05:18:05 +00:00
t . historyResults = sqlResults
t . compactResults = compact
t . limit = limit
t . submenu = [
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Clear History ' , ' path ' : ' history/clearHistory ' } ,
{ ' title ' : ' Trim History ' , ' path ' : ' history/trimHistory ' } ,
2014-03-10 05:18:05 +00:00
]
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def clearHistory ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
myDB . action ( " DELETE FROM history WHERE 1=1 " )
2014-06-07 21:32:38 +00:00
2014-03-10 05:18:05 +00:00
ui . notifications . message ( ' History cleared ' )
2014-06-30 01:54:41 +00:00
redirect ( " /history/ " )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def trimHistory ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
myDB . action ( " DELETE FROM history WHERE date < " + str (
( datetime . datetime . today ( ) - datetime . timedelta ( days = 30 ) ) . strftime ( history . dateFormat ) ) )
2014-06-07 21:32:38 +00:00
2014-03-10 05:18:05 +00:00
ui . notifications . message ( ' Removed history entries greater than 30 days old ' )
2014-06-30 01:54:41 +00:00
redirect ( " /history/ " )
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
ConfigMenu = [
2014-03-25 05:57:24 +00:00
{ ' title ' : ' General ' , ' path ' : ' config/general/ ' } ,
2014-06-19 14:31:44 +00:00
{ ' title ' : ' Backup/Restore ' , ' path ' : ' config/backuprestore/ ' } ,
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Search Settings ' , ' path ' : ' config/search/ ' } ,
{ ' title ' : ' Search Providers ' , ' path ' : ' config/providers/ ' } ,
{ ' title ' : ' Subtitles Settings ' , ' path ' : ' config/subtitles/ ' } ,
{ ' title ' : ' Post Processing ' , ' path ' : ' config/postProcessing/ ' } ,
{ ' title ' : ' Notifications ' , ' path ' : ' config/notifications/ ' } ,
2014-05-26 06:29:22 +00:00
{ ' title ' : ' Anime ' , ' path ' : ' config/anime/ ' } ,
2014-03-10 05:18:05 +00:00
]
2014-06-16 05:45:52 +00:00
2014-06-19 08:37:44 +00:00
class ConfigGeneral ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_general.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def saveRootDirs ( self , rootDirString = None ) :
sickbeard . ROOT_DIRS = rootDirString
2014-10-24 15:31:11 +00:00
2014-06-11 08:34:28 +00:00
2014-06-02 03:43:37 +00:00
def saveAddShowDefaults ( self , defaultStatus , anyQualities , bestQualities , defaultFlattenFolders , subtitles = False ,
anime = False , scene = False ) :
2014-03-10 05:18:05 +00:00
if anyQualities :
anyQualities = anyQualities . split ( ' , ' )
else :
anyQualities = [ ]
if bestQualities :
bestQualities = bestQualities . split ( ' , ' )
else :
bestQualities = [ ]
newQuality = Quality . combineQualities ( map ( int , anyQualities ) , map ( int , bestQualities ) )
sickbeard . STATUS_DEFAULT = int ( defaultStatus )
sickbeard . QUALITY_DEFAULT = int ( newQuality )
sickbeard . FLATTEN_FOLDERS_DEFAULT = config . checkbox_to_value ( defaultFlattenFolders )
sickbeard . SUBTITLES_DEFAULT = config . checkbox_to_value ( subtitles )
2014-06-02 03:43:37 +00:00
sickbeard . ANIME_DEFAULT = config . checkbox_to_value ( anime )
sickbeard . SCENE_DEFAULT = config . checkbox_to_value ( scene )
2014-05-26 06:29:22 +00:00
2014-04-03 00:04:40 +00:00
sickbeard . save_config ( )
2014-05-13 09:58:27 +00:00
2014-06-11 08:34:28 +00:00
def generateKey ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
""" Return a new randomized API_KEY
"""
try :
from hashlib import md5
except ImportError :
from md5 import md5
# Create some values to seed md5
t = str ( time . time ( ) )
r = str ( random . random ( ) )
# Create the md5 instance and give it the current time
m = md5 ( t )
# Update the md5 instance with the random variable
m . update ( r )
# Return a hex digest of the md5, eg 49f68a5c8493ec2c0bf489821c21fc3b
logger . log ( u " New API generated " )
return m . hexdigest ( )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def saveGeneral ( self , log_dir = None , web_port = None , web_log = None , encryption_version = None , web_ipv6 = None ,
2014-05-20 16:06:11 +00:00
update_shows_on_start = None , update_frequency = None , launch_browser = None , web_username = None ,
2014-05-20 20:51:54 +00:00
use_api = None , api_key = None , indexer_default = None , timezone_display = None , cpu_preset = None ,
2014-03-25 05:57:24 +00:00
web_password = None , version_notify = None , enable_https = None , https_cert = None , https_key = None ,
2014-07-06 14:45:01 +00:00
handle_reverse_proxy = None , sort_article = None , auto_update = None , notify_on_update = None ,
2014-10-27 00:29:12 +00:00
proxy_setting = None , proxy_indexers = None , anon_redirect = None , git_path = None , git_remote = None , calendar_unprotected = None ,
2014-06-03 17:43:37 +00:00
fuzzy_dating = None , trim_zero = None , date_preset = None , date_preset_na = None , time_preset = None ,
2014-10-24 15:31:11 +00:00
indexer_timeout = None , play_videos = None , rootDir = None , theme_name = None ) :
2014-03-10 05:18:05 +00:00
results = [ ]
# Misc
2014-07-11 11:05:33 +00:00
sickbeard . PLAY_VIDEOS = config . checkbox_to_value ( play_videos )
2014-03-10 05:18:05 +00:00
sickbeard . LAUNCH_BROWSER = config . checkbox_to_value ( launch_browser )
config . change_VERSION_NOTIFY ( config . checkbox_to_value ( version_notify ) )
2014-04-23 07:12:51 +00:00
sickbeard . AUTO_UPDATE = config . checkbox_to_value ( auto_update )
2014-07-03 07:16:15 +00:00
sickbeard . NOTIFY_ON_UPDATE = config . checkbox_to_value ( notify_on_update )
2014-03-10 05:18:05 +00:00
# sickbeard.LOG_DIR is set in config.change_LOG_DIR()
sickbeard . UPDATE_SHOWS_ON_START = config . checkbox_to_value ( update_shows_on_start )
2014-04-27 15:02:34 +00:00
config . change_UPDATE_FREQUENCY ( update_frequency )
2014-03-10 05:18:05 +00:00
sickbeard . LAUNCH_BROWSER = config . checkbox_to_value ( launch_browser )
sickbeard . SORT_ARTICLE = config . checkbox_to_value ( sort_article )
2014-05-17 11:40:26 +00:00
sickbeard . CPU_PRESET = cpu_preset
2014-03-10 05:18:05 +00:00
sickbeard . ANON_REDIRECT = anon_redirect
2014-04-26 21:35:36 +00:00
sickbeard . PROXY_SETTING = proxy_setting
2014-10-07 12:55:17 +00:00
sickbeard . PROXY_INDEXERS = config . checkbox_to_value ( proxy_indexers )
2014-03-10 05:18:05 +00:00
sickbeard . GIT_PATH = git_path
2014-10-27 00:29:12 +00:00
sickbeard . GIT_REMOTE = git_remote
2014-03-10 05:18:05 +00:00
sickbeard . CALENDAR_UNPROTECTED = config . checkbox_to_value ( calendar_unprotected )
# sickbeard.LOG_DIR is set in config.change_LOG_DIR()
sickbeard . WEB_PORT = config . to_int ( web_port )
sickbeard . WEB_IPV6 = config . checkbox_to_value ( web_ipv6 )
# sickbeard.WEB_LOG is set in config.change_LOG_DIR()
sickbeard . ENCRYPTION_VERSION = config . checkbox_to_value ( encryption_version )
sickbeard . WEB_USERNAME = web_username
sickbeard . WEB_PASSWORD = web_password
2014-05-23 15:20:44 +00:00
sickbeard . FUZZY_DATING = config . checkbox_to_value ( fuzzy_dating )
sickbeard . TRIM_ZERO = config . checkbox_to_value ( trim_zero )
2014-03-10 05:18:05 +00:00
if date_preset :
sickbeard . DATE_PRESET = date_preset
2014-06-03 17:43:37 +00:00
discarded_na_data = date_preset_na
2014-03-25 05:57:24 +00:00
2014-04-27 08:17:28 +00:00
if indexer_default :
2014-05-02 00:57:51 +00:00
sickbeard . INDEXER_DEFAULT = config . to_int ( indexer_default )
2014-04-27 08:17:28 +00:00
2014-05-21 18:17:52 +00:00
if indexer_timeout :
sickbeard . INDEXER_TIMEOUT = config . to_int ( indexer_timeout )
2014-03-10 05:18:05 +00:00
if time_preset :
sickbeard . TIME_PRESET_W_SECONDS = time_preset
2014-03-25 05:57:24 +00:00
sickbeard . TIME_PRESET = sickbeard . TIME_PRESET_W_SECONDS . replace ( u " : % S " , u " " )
2014-03-10 05:18:05 +00:00
2014-05-17 07:30:21 +00:00
sickbeard . TIMEZONE_DISPLAY = timezone_display
2014-03-10 05:18:05 +00:00
if not config . change_LOG_DIR ( log_dir , web_log ) :
results + = [ " Unable to create directory " + os . path . normpath ( log_dir ) + " , log directory not changed. " ]
sickbeard . USE_API = config . checkbox_to_value ( use_api )
sickbeard . API_KEY = api_key
sickbeard . ENABLE_HTTPS = config . checkbox_to_value ( enable_https )
if not config . change_HTTPS_CERT ( https_cert ) :
2014-03-25 05:57:24 +00:00
results + = [
" Unable to create directory " + os . path . normpath ( https_cert ) + " , https cert directory not changed. " ]
2014-03-10 05:18:05 +00:00
if not config . change_HTTPS_KEY ( https_key ) :
2014-03-25 05:57:24 +00:00
results + = [
" Unable to create directory " + os . path . normpath ( https_key ) + " , https key directory not changed. " ]
2014-03-10 05:18:05 +00:00
2014-05-04 18:47:09 +00:00
sickbeard . HANDLE_REVERSE_PROXY = config . checkbox_to_value ( handle_reverse_proxy )
2014-10-08 06:00:48 +00:00
sickbeard . THEME_NAME = theme_name
2014-03-10 05:18:05 +00:00
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-03-25 05:57:24 +00:00
' <br /> \n ' . join ( results ) )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-07-24 19:43:01 +00:00
redirect ( " /config/general/ " )
2014-06-18 12:56:26 +00:00
2014-07-27 14:39:33 +00:00
2014-06-19 14:31:44 +00:00
class ConfigBackupRestore ( MainHandler ) :
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_backuprestore.tmpl " )
2014-06-19 14:31:44 +00:00
t . submenu = ConfigMenu
return _munge ( t )
def backup ( self , backupDir = None ) :
finalResult = ' '
if backupDir :
2014-06-24 23:47:52 +00:00
source = [ os . path . join ( sickbeard . DATA_DIR , ' sickbeard.db ' ) , sickbeard . CONFIG_FILE ]
2014-06-19 14:31:44 +00:00
target = os . path . join ( backupDir , ' sickrage- ' + time . strftime ( ' % Y % m %d % H % M % S ' ) + ' .zip ' )
if helpers . makeZip ( source , target ) :
finalResult + = " Successful backup to " + target
else :
finalResult + = " Backup FAILED "
else :
finalResult + = " You need to choose a folder to save your backup to! "
finalResult + = " <br /> \n "
return finalResult
def restore ( self , backupFile = None ) :
2014-06-29 01:11:35 +00:00
2014-06-19 14:31:44 +00:00
finalResult = ' '
if backupFile :
source = backupFile
2014-06-24 23:40:13 +00:00
target_dir = os . path . join ( sickbeard . DATA_DIR , ' restore ' )
2014-06-19 14:31:44 +00:00
if helpers . extractZip ( source , target_dir ) :
finalResult + = " Successfully extracted restore files to " + target_dir
finalResult + = " <br>Restart sickrage to complete the restore. "
else :
finalResult + = " Restore FAILED "
else :
finalResult + = " You need to select a backup file to restore! "
finalResult + = " <br /> \n "
return finalResult
2014-06-19 08:37:44 +00:00
class ConfigSearch ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_search.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def saveSearch ( self , use_nzbs = None , use_torrents = None , nzb_dir = None , sab_username = None , sab_password = None ,
2014-03-25 05:57:24 +00:00
sab_apikey = None , sab_category = None , sab_host = None , nzbget_username = None , nzbget_password = None ,
2014-09-15 09:23:11 +00:00
nzbget_category = None , nzbget_priority = None , nzbget_host = None , nzbget_use_https = None ,
2014-09-15 08:57:50 +00:00
backlog_days = None , backlog_frequency = None , dailysearch_frequency = None ,
nzb_method = None , torrent_method = None , usenet_retention = None ,
2014-05-19 23:43:01 +00:00
download_propers = None , check_propers_interval = None , allow_high_priority = None ,
backlog_startup = None , dailysearch_startup = None ,
2014-05-17 16:18:50 +00:00
torrent_dir = None , torrent_username = None , torrent_password = None , torrent_host = None ,
2014-05-11 07:31:38 +00:00
torrent_label = None , torrent_path = None , torrent_verify_cert = None ,
2014-10-05 15:10:43 +00:00
torrent_seed_time = None , torrent_paused = None , torrent_high_bandwidth = None , ignore_words = None , require_words = None ) :
2014-03-10 05:18:05 +00:00
results = [ ]
if not config . change_NZB_DIR ( nzb_dir ) :
results + = [ " Unable to create directory " + os . path . normpath ( nzb_dir ) + " , dir not changed. " ]
if not config . change_TORRENT_DIR ( torrent_dir ) :
results + = [ " Unable to create directory " + os . path . normpath ( torrent_dir ) + " , dir not changed. " ]
2014-05-15 04:16:46 +00:00
config . change_DAILYSEARCH_FREQUENCY ( dailysearch_frequency )
2014-09-15 09:35:14 +00:00
2014-05-17 16:18:50 +00:00
config . change_BACKLOG_FREQUENCY ( backlog_frequency )
2014-09-15 09:35:14 +00:00
sickbeard . BACKLOG_DAYS = config . to_int ( backlog_days , default = 7 )
2014-03-10 05:18:05 +00:00
sickbeard . USE_NZBS = config . checkbox_to_value ( use_nzbs )
sickbeard . USE_TORRENTS = config . checkbox_to_value ( use_torrents )
sickbeard . NZB_METHOD = nzb_method
sickbeard . TORRENT_METHOD = torrent_method
2014-05-17 11:40:26 +00:00
sickbeard . USENET_RETENTION = config . to_int ( usenet_retention , default = 500 )
2014-03-10 05:18:05 +00:00
2014-04-22 20:24:55 +00:00
sickbeard . IGNORE_WORDS = ignore_words if ignore_words else " "
2014-10-05 15:10:43 +00:00
sickbeard . REQUIRE_WORDS = require_words if require_words else " "
2014-03-10 05:18:05 +00:00
sickbeard . DOWNLOAD_PROPERS = config . checkbox_to_value ( download_propers )
2014-05-14 22:23:59 +00:00
sickbeard . CHECK_PROPERS_INTERVAL = check_propers_interval
2014-03-10 05:18:05 +00:00
sickbeard . ALLOW_HIGH_PRIORITY = config . checkbox_to_value ( allow_high_priority )
2014-05-12 10:34:18 +00:00
2014-05-17 16:18:50 +00:00
sickbeard . DAILYSEARCH_STARTUP = config . checkbox_to_value ( dailysearch_startup )
2014-05-06 22:27:44 +00:00
sickbeard . BACKLOG_STARTUP = config . checkbox_to_value ( backlog_startup )
2014-03-10 05:18:05 +00:00
sickbeard . SAB_USERNAME = sab_username
sickbeard . SAB_PASSWORD = sab_password
sickbeard . SAB_APIKEY = sab_apikey . strip ( )
sickbeard . SAB_CATEGORY = sab_category
sickbeard . SAB_HOST = config . clean_url ( sab_host )
sickbeard . NZBGET_USERNAME = nzbget_username
sickbeard . NZBGET_PASSWORD = nzbget_password
sickbeard . NZBGET_CATEGORY = nzbget_category
sickbeard . NZBGET_HOST = config . clean_host ( nzbget_host )
2014-05-05 22:48:28 +00:00
sickbeard . NZBGET_USE_HTTPS = config . checkbox_to_value ( nzbget_use_https )
2014-09-15 09:23:11 +00:00
sickbeard . NZBGET_PRIORITY = config . to_int ( nzbget_priority , default = 100 )
2014-03-10 05:18:05 +00:00
sickbeard . TORRENT_USERNAME = torrent_username
sickbeard . TORRENT_PASSWORD = torrent_password
sickbeard . TORRENT_LABEL = torrent_label
2014-05-11 07:31:38 +00:00
sickbeard . TORRENT_VERIFY_CERT = config . checkbox_to_value ( torrent_verify_cert )
2014-03-10 05:18:05 +00:00
sickbeard . TORRENT_PATH = torrent_path
2014-04-28 14:34:27 +00:00
sickbeard . TORRENT_SEED_TIME = torrent_seed_time
2014-03-10 05:18:05 +00:00
sickbeard . TORRENT_PAUSED = config . checkbox_to_value ( torrent_paused )
sickbeard . TORRENT_HIGH_BANDWIDTH = config . checkbox_to_value ( torrent_high_bandwidth )
sickbeard . TORRENT_HOST = config . clean_url ( torrent_host )
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-03-25 05:57:24 +00:00
' <br /> \n ' . join ( results ) )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-07-24 19:43:01 +00:00
redirect ( " /config/search/ " )
2014-03-10 05:18:05 +00:00
2014-07-27 14:39:33 +00:00
2014-06-19 08:37:44 +00:00
class ConfigPostProcessing ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_postProcessing.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def savePostProcessing ( self , naming_pattern = None , naming_multi_ep = None ,
2014-03-25 05:57:24 +00:00
xbmc_data = None , xbmc_12plus_data = None , mediabrowser_data = None , sony_ps3_data = None ,
2014-05-11 23:15:24 +00:00
wdtv_data = None , tivo_data = None , mede8er_data = None ,
2014-03-25 05:57:24 +00:00
keep_processed_dir = None , process_method = None , process_automatically = None ,
2014-05-14 12:33:36 +00:00
rename_episodes = None , airdate_episodes = None , unpack = None ,
2014-09-07 10:45:19 +00:00
move_associated_files = None , postpone_if_sync_files = None , nfo_rename = None , tv_download_dir = None , naming_custom_abd = None ,
2014-06-27 11:00:16 +00:00
naming_anime = None ,
2014-03-25 05:57:24 +00:00
naming_abd_pattern = None , naming_strip_year = None , use_failed_downloads = None ,
2014-05-17 22:14:31 +00:00
delete_failed = None , extra_scripts = None , skip_removed_files = None ,
2014-09-28 09:20:42 +00:00
naming_custom_sports = None , naming_sports_pattern = None ,
naming_custom_anime = None , naming_anime_pattern = None , naming_anime_multi_ep = None ,
autopostprocesser_frequency = None ) :
2014-03-10 05:18:05 +00:00
results = [ ]
if not config . change_TV_DOWNLOAD_DIR ( tv_download_dir ) :
results + = [ " Unable to create directory " + os . path . normpath ( tv_download_dir ) + " , dir not changed. " ]
sickbeard . PROCESS_AUTOMATICALLY = config . checkbox_to_value ( process_automatically )
2014-05-21 20:26:24 +00:00
config . change_AUTOPOSTPROCESSER_FREQUENCY ( autopostprocesser_frequency )
2014-03-10 05:18:05 +00:00
if sickbeard . PROCESS_AUTOMATICALLY :
2014-06-15 07:16:55 +00:00
sickbeard . autoPostProcesserScheduler . silent = False
2014-03-10 05:18:05 +00:00
else :
2014-06-15 07:16:55 +00:00
sickbeard . autoPostProcesserScheduler . silent = True
2014-03-10 05:18:05 +00:00
if unpack :
if self . isRarSupported ( ) != ' not supported ' :
sickbeard . UNPACK = config . checkbox_to_value ( unpack )
else :
sickbeard . UNPACK = 0
results . append ( " Unpacking Not Supported, disabling unpack setting " )
else :
sickbeard . UNPACK = config . checkbox_to_value ( unpack )
sickbeard . KEEP_PROCESSED_DIR = config . checkbox_to_value ( keep_processed_dir )
sickbeard . PROCESS_METHOD = process_method
sickbeard . EXTRA_SCRIPTS = [ x . strip ( ) for x in extra_scripts . split ( ' | ' ) if x . strip ( ) ]
sickbeard . RENAME_EPISODES = config . checkbox_to_value ( rename_episodes )
2014-05-14 12:33:36 +00:00
sickbeard . AIRDATE_EPISODES = config . checkbox_to_value ( airdate_episodes )
2014-03-10 05:18:05 +00:00
sickbeard . MOVE_ASSOCIATED_FILES = config . checkbox_to_value ( move_associated_files )
2014-09-07 10:45:19 +00:00
sickbeard . POSTPONE_IF_SYNC_FILES = config . checkbox_to_value ( postpone_if_sync_files )
2014-03-10 05:18:05 +00:00
sickbeard . NAMING_CUSTOM_ABD = config . checkbox_to_value ( naming_custom_abd )
2014-04-28 09:15:29 +00:00
sickbeard . NAMING_CUSTOM_SPORTS = config . checkbox_to_value ( naming_custom_sports )
2014-09-28 09:20:42 +00:00
sickbeard . NAMING_CUSTOM_ANIME = config . checkbox_to_value ( naming_custom_anime )
2014-03-10 05:18:05 +00:00
sickbeard . NAMING_STRIP_YEAR = config . checkbox_to_value ( naming_strip_year )
sickbeard . USE_FAILED_DOWNLOADS = config . checkbox_to_value ( use_failed_downloads )
sickbeard . DELETE_FAILED = config . checkbox_to_value ( delete_failed )
2014-05-19 23:43:01 +00:00
sickbeard . SKIP_REMOVED_FILES = config . checkbox_to_value ( skip_removed_files )
2014-04-06 16:25:46 +00:00
sickbeard . NFO_RENAME = config . checkbox_to_value ( nfo_rename )
2014-05-20 20:51:54 +00:00
2014-05-01 01:29:13 +00:00
sickbeard . METADATA_XBMC = xbmc_data
sickbeard . METADATA_XBMC_12PLUS = xbmc_12plus_data
sickbeard . METADATA_MEDIABROWSER = mediabrowser_data
sickbeard . METADATA_PS3 = sony_ps3_data
sickbeard . METADATA_WDTV = wdtv_data
sickbeard . METADATA_TIVO = tivo_data
2014-05-11 23:15:24 +00:00
sickbeard . METADATA_MEDE8ER = mede8er_data
2014-05-01 01:29:13 +00:00
2014-03-10 05:18:05 +00:00
sickbeard . metadata_provider_dict [ ' XBMC ' ] . set_config ( sickbeard . METADATA_XBMC )
sickbeard . metadata_provider_dict [ ' XBMC 12+ ' ] . set_config ( sickbeard . METADATA_XBMC_12PLUS )
sickbeard . metadata_provider_dict [ ' MediaBrowser ' ] . set_config ( sickbeard . METADATA_MEDIABROWSER )
sickbeard . metadata_provider_dict [ ' Sony PS3 ' ] . set_config ( sickbeard . METADATA_PS3 )
sickbeard . metadata_provider_dict [ ' WDTV ' ] . set_config ( sickbeard . METADATA_WDTV )
sickbeard . metadata_provider_dict [ ' TIVO ' ] . set_config ( sickbeard . METADATA_TIVO )
2014-05-11 23:15:24 +00:00
sickbeard . metadata_provider_dict [ ' Mede8er ' ] . set_config ( sickbeard . METADATA_MEDE8ER )
2014-03-10 05:18:05 +00:00
2014-06-07 08:17:12 +00:00
if self . isNamingValid ( naming_pattern , naming_multi_ep , anime_type = naming_anime ) != " invalid " :
2014-03-10 05:18:05 +00:00
sickbeard . NAMING_PATTERN = naming_pattern
sickbeard . NAMING_MULTI_EP = int ( naming_multi_ep )
2014-06-07 08:17:12 +00:00
sickbeard . NAMING_ANIME = int ( naming_anime )
2014-03-10 05:18:05 +00:00
sickbeard . NAMING_FORCE_FOLDERS = naming . check_force_season_folders ( )
else :
2014-06-07 08:17:12 +00:00
if int ( naming_anime ) in [ 1 , 2 ] :
results . append ( " You tried saving an invalid anime naming config, not saving your naming settings " )
else :
results . append ( " You tried saving an invalid naming config, not saving your naming settings " )
2014-03-10 05:18:05 +00:00
2014-09-28 09:20:42 +00:00
if self . isNamingValid ( naming_anime_pattern , naming_anime_multi_ep , anime_type = naming_anime ) != " invalid " :
sickbeard . NAMING_ANIME_PATTERN = naming_anime_pattern
sickbeard . NAMING_ANIME_MULTI_EP = int ( naming_anime_multi_ep )
sickbeard . NAMING_ANIME = int ( naming_anime )
sickbeard . NAMING_FORCE_FOLDERS = naming . check_force_season_folders ( )
else :
if int ( naming_anime ) in [ 1 , 2 ] :
results . append ( " You tried saving an invalid anime naming config, not saving your naming settings " )
else :
results . append ( " You tried saving an invalid naming config, not saving your naming settings " )
2014-04-28 09:15:29 +00:00
if self . isNamingValid ( naming_abd_pattern , None , abd = True ) != " invalid " :
2014-03-10 05:18:05 +00:00
sickbeard . NAMING_ABD_PATTERN = naming_abd_pattern
else :
2014-03-25 05:57:24 +00:00
results . append (
" You tried saving an invalid air-by-date naming config, not saving your air-by-date settings " )
2014-03-10 05:18:05 +00:00
2014-04-28 09:15:29 +00:00
if self . isNamingValid ( naming_sports_pattern , None , sports = True ) != " invalid " :
sickbeard . NAMING_SPORTS_PATTERN = naming_sports_pattern
else :
results . append (
" You tried saving an invalid sports naming config, not saving your sports settings " )
2014-03-10 05:18:05 +00:00
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-03-25 05:57:24 +00:00
' <br /> \n ' . join ( results ) )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-07-24 19:43:01 +00:00
redirect ( " /config/postProcessing/ " )
2014-03-10 05:18:05 +00:00
2014-06-07 08:17:12 +00:00
def testNaming ( self , pattern = None , multi = None , abd = False , sports = False , anime_type = None ) :
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if multi is not None :
2014-03-10 05:18:05 +00:00
multi = int ( multi )
2014-06-07 08:17:12 +00:00
if anime_type is not None :
anime_type = int ( anime_type )
result = naming . test_name ( pattern , multi , abd , sports , anime_type )
2014-03-10 05:18:05 +00:00
result = ek . ek ( os . path . join , result [ ' dir ' ] , result [ ' name ' ] )
return result
2014-06-11 08:34:28 +00:00
2014-06-07 08:17:12 +00:00
def isNamingValid ( self , pattern = None , multi = None , abd = False , sports = False , anime_type = None ) :
2014-03-25 05:57:24 +00:00
if pattern is None :
2014-03-10 05:18:05 +00:00
return " invalid "
2014-06-07 08:17:12 +00:00
if multi is not None :
multi = int ( multi )
if anime_type is not None :
anime_type = int ( anime_type )
2014-03-10 05:18:05 +00:00
# air by date shows just need one check, we don't need to worry about season folders
if abd :
is_valid = naming . check_valid_abd_naming ( pattern )
require_season_folders = False
2014-04-28 09:15:29 +00:00
# sport shows just need one check, we don't need to worry about season folders
elif sports :
is_valid = naming . check_valid_sports_naming ( pattern )
require_season_folders = False
2014-03-10 05:18:05 +00:00
else :
# check validity of single and multi ep cases for the whole path
2014-06-07 08:17:12 +00:00
is_valid = naming . check_valid_naming ( pattern , multi , anime_type )
2014-03-10 05:18:05 +00:00
# check validity of single and multi ep cases for only the file name
2014-06-07 08:17:12 +00:00
require_season_folders = naming . check_force_season_folders ( pattern , multi , anime_type )
2014-03-10 05:18:05 +00:00
if is_valid and not require_season_folders :
return " valid "
elif is_valid and require_season_folders :
return " seasonfolders "
else :
return " invalid "
2014-06-11 08:34:28 +00:00
def isRarSupported ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
"""
Test Packing Support :
- Simulating in memory rar extraction on test . rar file
"""
try :
rar_path = os . path . join ( sickbeard . PROG_DIR , ' lib ' , ' unrar2 ' , ' test.rar ' )
testing = RarFile ( rar_path ) . read_files ( ' *test.txt ' )
2014-03-25 05:57:24 +00:00
if testing [ 0 ] [ 1 ] == ' This is only a test. ' :
2014-03-10 05:18:05 +00:00
return ' supported '
logger . log ( u ' Rar Not Supported: Can not read the content of test file ' , logger . ERROR )
return ' not supported '
except Exception , e :
logger . log ( u ' Rar Not Supported: ' + ex ( e ) , logger . ERROR )
return ' not supported '
2014-06-19 08:37:44 +00:00
class ConfigProviders ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_providers.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def canAddNewznabProvider ( self , name ) :
if not name :
return json . dumps ( { ' error ' : ' No Provider Name specified ' } )
providerDict = dict ( zip ( [ x . getID ( ) for x in sickbeard . newznabProviderList ] , sickbeard . newznabProviderList ) )
tempProvider = newznab . NewznabProvider ( name , ' ' )
if tempProvider . getID ( ) in providerDict :
return json . dumps ( { ' error ' : ' Provider Name already exists as ' + providerDict [ tempProvider . getID ( ) ] . name } )
else :
return json . dumps ( { ' success ' : tempProvider . getID ( ) } )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def saveNewznabProvider ( self , name , url , key = ' ' ) :
if not name or not url :
return ' 0 '
providerDict = dict ( zip ( [ x . name for x in sickbeard . newznabProviderList ] , sickbeard . newznabProviderList ) )
if name in providerDict :
if not providerDict [ name ] . default :
providerDict [ name ] . name = name
providerDict [ name ] . url = config . clean_url ( url )
providerDict [ name ] . key = key
# a 0 in the key spot indicates that no key is needed
if key == ' 0 ' :
providerDict [ name ] . needs_auth = False
else :
providerDict [ name ] . needs_auth = True
return providerDict [ name ] . getID ( ) + ' | ' + providerDict [ name ] . configStr ( )
else :
newProvider = newznab . NewznabProvider ( name , url , key = key )
sickbeard . newznabProviderList . append ( newProvider )
return newProvider . getID ( ) + ' | ' + newProvider . configStr ( )
2014-09-01 15:57:52 +00:00
def getNewznabCategories ( self , name , url , key ) :
'''
Retrieves a list of possible categories with category id ' s
Using the default url / api ? cat
http : / / yournewznaburl . com / api ? t = caps & apikey = yourapikey
'''
error = " "
success = False
if not name :
error + = " \n No Provider Name specified "
if not url :
error + = " \n No Provider Url specified "
if not key :
error + = " \n No Provider Api key specified "
if error < > " " :
return json . dumps ( { ' success ' : False , ' error ' : error } )
#Get list with Newznabproviders
#providerDict = dict(zip([x.getID() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
#Get newznabprovider obj with provided name
tempProvider = newznab . NewznabProvider ( name , url , key )
success , tv_categories , error = tempProvider . get_newznab_categories ( )
return json . dumps ( { ' success ' : success , ' tv_categories ' : tv_categories , ' error ' : error } )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def deleteNewznabProvider ( self , nnid ) :
providerDict = dict ( zip ( [ x . getID ( ) for x in sickbeard . newznabProviderList ] , sickbeard . newznabProviderList ) )
if nnid not in providerDict or providerDict [ nnid ] . default :
return ' 0 '
# delete it from the list
sickbeard . newznabProviderList . remove ( providerDict [ nnid ] )
if nnid in sickbeard . PROVIDER_ORDER :
sickbeard . PROVIDER_ORDER . remove ( nnid )
return ' 1 '
2014-06-11 08:34:28 +00:00
2014-05-25 07:28:13 +00:00
def canAddTorrentRssProvider ( self , name , url , cookies ) :
2014-03-10 05:18:05 +00:00
if not name :
return json . dumps ( { ' error ' : ' Invalid name specified ' } )
2014-03-25 05:57:24 +00:00
providerDict = dict (
zip ( [ x . getID ( ) for x in sickbeard . torrentRssProviderList ] , sickbeard . torrentRssProviderList ) )
2014-03-10 05:18:05 +00:00
2014-05-25 07:28:13 +00:00
tempProvider = rsstorrent . TorrentRssProvider ( name , url , cookies )
2014-03-10 05:18:05 +00:00
if tempProvider . getID ( ) in providerDict :
return json . dumps ( { ' error ' : ' Exists as ' + providerDict [ tempProvider . getID ( ) ] . name } )
else :
( succ , errMsg ) = tempProvider . validateRSS ( )
if succ :
return json . dumps ( { ' success ' : tempProvider . getID ( ) } )
else :
2014-03-25 05:57:24 +00:00
return json . dumps ( { ' error ' : errMsg } )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
2014-05-25 07:28:13 +00:00
def saveTorrentRssProvider ( self , name , url , cookies ) :
2014-03-10 05:18:05 +00:00
if not name or not url :
return ' 0 '
providerDict = dict ( zip ( [ x . name for x in sickbeard . torrentRssProviderList ] , sickbeard . torrentRssProviderList ) )
if name in providerDict :
providerDict [ name ] . name = name
providerDict [ name ] . url = config . clean_url ( url )
2014-05-25 07:28:13 +00:00
providerDict [ name ] . cookies = cookies
2014-03-10 05:18:05 +00:00
return providerDict [ name ] . getID ( ) + ' | ' + providerDict [ name ] . configStr ( )
else :
2014-05-25 07:28:13 +00:00
newProvider = rsstorrent . TorrentRssProvider ( name , url , cookies )
2014-04-22 10:13:44 +00:00
sickbeard . torrentRssProviderList . append ( newProvider )
2014-03-10 05:18:05 +00:00
return newProvider . getID ( ) + ' | ' + newProvider . configStr ( )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def deleteTorrentRssProvider ( self , id ) :
2014-03-25 05:57:24 +00:00
providerDict = dict (
zip ( [ x . getID ( ) for x in sickbeard . torrentRssProviderList ] , sickbeard . torrentRssProviderList ) )
2014-03-10 05:18:05 +00:00
if id not in providerDict :
return ' 0 '
# delete it from the list
sickbeard . torrentRssProviderList . remove ( providerDict [ id ] )
if id in sickbeard . PROVIDER_ORDER :
sickbeard . PROVIDER_ORDER . remove ( id )
return ' 1 '
2014-06-11 08:34:28 +00:00
2014-05-17 05:23:11 +00:00
def saveProviders ( self , newznab_string = ' ' , torrentrss_string = ' ' , provider_order = None , * * kwargs ) :
2014-03-10 05:18:05 +00:00
results = [ ]
provider_str_list = provider_order . split ( )
provider_list = [ ]
2014-03-25 05:57:24 +00:00
newznabProviderDict = dict (
zip ( [ x . getID ( ) for x in sickbeard . newznabProviderList ] , sickbeard . newznabProviderList ) )
2014-03-10 05:18:05 +00:00
finishedNames = [ ]
# add all the newznab info we got into our list
if newznab_string :
for curNewznabProviderStr in newznab_string . split ( ' !!! ' ) :
if not curNewznabProviderStr :
continue
2014-09-01 15:57:52 +00:00
cur_name , cur_url , cur_key , cur_cat = curNewznabProviderStr . split ( ' | ' )
2014-03-10 05:18:05 +00:00
cur_url = config . clean_url ( cur_url )
2014-05-23 16:35:01 +00:00
2014-03-10 05:18:05 +00:00
newProvider = newznab . NewznabProvider ( cur_name , cur_url , key = cur_key )
2014-09-01 15:57:52 +00:00
2014-03-10 05:18:05 +00:00
cur_id = newProvider . getID ( )
# if it already exists then update it
if cur_id in newznabProviderDict :
newznabProviderDict [ cur_id ] . name = cur_name
newznabProviderDict [ cur_id ] . url = cur_url
newznabProviderDict [ cur_id ] . key = cur_key
2014-09-01 15:57:52 +00:00
newznabProviderDict [ cur_id ] . catIDs = cur_cat
2014-03-10 05:18:05 +00:00
# a 0 in the key spot indicates that no key is needed
if cur_key == ' 0 ' :
newznabProviderDict [ cur_id ] . needs_auth = False
else :
newznabProviderDict [ cur_id ] . needs_auth = True
2014-09-01 16:29:52 +00:00
2014-08-29 10:29:56 +00:00
try :
newznabProviderDict [ cur_id ] . search_mode = str ( kwargs [ cur_id + ' _search_mode ' ] ) . strip ( )
except :
pass
try :
newznabProviderDict [ cur_id ] . search_fallback = config . checkbox_to_value (
kwargs [ cur_id + ' _search_fallback ' ] )
except :
2014-09-03 23:52:39 +00:00
newznabProviderDict [ cur_id ] . search_fallback = 0
2014-08-29 10:29:56 +00:00
try :
newznabProviderDict [ cur_id ] . enable_daily = config . checkbox_to_value (
kwargs [ cur_id + ' _enable_daily ' ] )
except :
2014-09-03 23:52:39 +00:00
newznabProviderDict [ cur_id ] . enable_daily = 0
2014-08-29 10:29:56 +00:00
try :
newznabProviderDict [ cur_id ] . enable_backlog = config . checkbox_to_value (
kwargs [ cur_id + ' _enable_backlog ' ] )
except :
2014-09-03 23:52:39 +00:00
newznabProviderDict [ cur_id ] . enable_backlog = 0
2014-03-10 05:18:05 +00:00
else :
sickbeard . newznabProviderList . append ( newProvider )
finishedNames . append ( cur_id )
# delete anything that is missing
for curProvider in sickbeard . newznabProviderList :
if curProvider . getID ( ) not in finishedNames :
sickbeard . newznabProviderList . remove ( curProvider )
2014-03-25 05:57:24 +00:00
torrentRssProviderDict = dict (
zip ( [ x . getID ( ) for x in sickbeard . torrentRssProviderList ] , sickbeard . torrentRssProviderList ) )
2014-03-10 05:18:05 +00:00
finishedNames = [ ]
if torrentrss_string :
for curTorrentRssProviderStr in torrentrss_string . split ( ' !!! ' ) :
if not curTorrentRssProviderStr :
continue
2014-05-25 07:28:13 +00:00
curName , curURL , curCookies = curTorrentRssProviderStr . split ( ' | ' )
2014-03-10 05:18:05 +00:00
curURL = config . clean_url ( curURL )
2014-03-25 05:57:24 +00:00
2014-05-25 07:28:13 +00:00
newProvider = rsstorrent . TorrentRssProvider ( curName , curURL , curCookies )
2014-03-10 05:18:05 +00:00
curID = newProvider . getID ( )
# if it already exists then update it
if curID in torrentRssProviderDict :
torrentRssProviderDict [ curID ] . name = curName
torrentRssProviderDict [ curID ] . url = curURL
2014-05-25 07:28:13 +00:00
torrentRssProviderDict [ curID ] . cookies = curCookies
2014-03-10 05:18:05 +00:00
else :
sickbeard . torrentRssProviderList . append ( newProvider )
finishedNames . append ( curID )
# delete anything that is missing
for curProvider in sickbeard . torrentRssProviderList :
if curProvider . getID ( ) not in finishedNames :
sickbeard . torrentRssProviderList . remove ( curProvider )
# do the enable/disable
for curProviderStr in provider_str_list :
curProvider , curEnabled = curProviderStr . split ( ' : ' )
curEnabled = config . to_int ( curEnabled )
2014-06-07 12:36:50 +00:00
curProvObj = [ x for x in sickbeard . providers . sortedProviderList ( ) if
x . getID ( ) == curProvider and hasattr ( x , ' enabled ' ) ]
2014-05-23 16:35:01 +00:00
if curProvObj :
curProvObj [ 0 ] . enabled = bool ( curEnabled )
2014-03-10 05:18:05 +00:00
2014-05-23 16:35:01 +00:00
provider_list . append ( curProvider )
if curProvider in newznabProviderDict :
newznabProviderDict [ curProvider ] . enabled = bool ( curEnabled )
elif curProvider in torrentRssProviderDict :
torrentRssProviderDict [ curProvider ] . enabled = bool ( curEnabled )
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
# dynamically load provider settings
for curTorrentProvider in [ curProvider for curProvider in sickbeard . providers . sortedProviderList ( ) if
curProvider . providerType == sickbeard . GenericProvider . TORRENT ] :
2014-03-10 05:18:05 +00:00
2014-05-20 16:06:11 +00:00
if hasattr ( curTorrentProvider , ' minseed ' ) :
try :
curTorrentProvider . minseed = int ( str ( kwargs [ curTorrentProvider . getID ( ) + ' _minseed ' ] ) . strip ( ) )
except :
curTorrentProvider . minseed = 0
if hasattr ( curTorrentProvider , ' minleech ' ) :
try :
curTorrentProvider . minleech = int ( str ( kwargs [ curTorrentProvider . getID ( ) + ' _minleech ' ] ) . strip ( ) )
except :
curTorrentProvider . minleech = 0
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' ratio ' ) :
try :
2014-05-23 06:42:11 +00:00
curTorrentProvider . ratio = str ( kwargs [ curTorrentProvider . getID ( ) + ' _ratio ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
2014-05-23 06:42:11 +00:00
curTorrentProvider . ratio = None
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' digest ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . digest = str ( kwargs [ curTorrentProvider . getID ( ) + ' _digest ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . digest = None
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' hash ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . hash = str ( kwargs [ curTorrentProvider . getID ( ) + ' _hash ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . hash = None
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' api_key ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . api_key = str ( kwargs [ curTorrentProvider . getID ( ) + ' _api_key ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . api_key = None
2014-05-13 09:58:27 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' username ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . username = str ( kwargs [ curTorrentProvider . getID ( ) + ' _username ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . username = None
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' password ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . password = str ( kwargs [ curTorrentProvider . getID ( ) + ' _password ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . password = None
2014-03-10 05:18:05 +00:00
2014-05-19 20:06:32 +00:00
if hasattr ( curTorrentProvider , ' passkey ' ) :
try :
curTorrentProvider . passkey = str ( kwargs [ curTorrentProvider . getID ( ) + ' _passkey ' ] ) . strip ( )
except :
curTorrentProvider . passkey = None
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' confirmed ' ) :
try :
2014-05-20 20:51:54 +00:00
curTorrentProvider . confirmed = config . checkbox_to_value (
kwargs [ curTorrentProvider . getID ( ) + ' _confirmed ' ] )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . confirmed = 0
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' proxy ' ) :
try :
2014-05-20 20:51:54 +00:00
curTorrentProvider . proxy . enabled = config . checkbox_to_value (
kwargs [ curTorrentProvider . getID ( ) + ' _proxy ' ] )
2014-05-17 05:23:11 +00:00
except :
2014-05-17 06:38:00 +00:00
curTorrentProvider . proxy . enabled = 0
2014-03-10 05:18:05 +00:00
2014-05-17 06:38:00 +00:00
if hasattr ( curTorrentProvider . proxy , ' url ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . proxy . url = str ( kwargs [ curTorrentProvider . getID ( ) + ' _proxy_url ' ] ) . strip ( )
2014-05-17 06:38:00 +00:00
except :
curTorrentProvider . proxy . url = None
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' freeleech ' ) :
try :
2014-05-20 20:51:54 +00:00
curTorrentProvider . freeleech = config . checkbox_to_value (
kwargs [ curTorrentProvider . getID ( ) + ' _freeleech ' ] )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . freeleech = 0
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' search_mode ' ) :
try :
2014-05-17 13:10:52 +00:00
curTorrentProvider . search_mode = str ( kwargs [ curTorrentProvider . getID ( ) + ' _search_mode ' ] ) . strip ( )
2014-05-17 05:23:11 +00:00
except :
curTorrentProvider . search_mode = ' eponly '
2014-03-10 05:18:05 +00:00
2014-05-17 05:23:11 +00:00
if hasattr ( curTorrentProvider , ' search_fallback ' ) :
try :
2014-05-20 20:51:54 +00:00
curTorrentProvider . search_fallback = config . checkbox_to_value (
kwargs [ curTorrentProvider . getID ( ) + ' _search_fallback ' ] )
2014-05-17 05:23:11 +00:00
except :
2014-09-03 10:33:26 +00:00
curTorrentProvider . search_fallback = 0 # these exceptions are catching unselected checkboxes
2014-03-25 05:57:24 +00:00
2014-08-29 05:16:25 +00:00
if hasattr ( curTorrentProvider , ' enable_daily ' ) :
2014-05-18 16:39:30 +00:00
try :
2014-08-29 05:16:25 +00:00
curTorrentProvider . enable_daily = config . checkbox_to_value (
kwargs [ curTorrentProvider . getID ( ) + ' _enable_daily ' ] )
2014-05-18 16:39:30 +00:00
except :
2014-09-03 10:33:26 +00:00
curTorrentProvider . enable_daily = 0 # these exceptions are actually catching unselected checkboxes
2014-08-29 05:16:25 +00:00
if hasattr ( curTorrentProvider , ' enable_backlog ' ) :
try :
curTorrentProvider . enable_backlog = config . checkbox_to_value (
kwargs [ curTorrentProvider . getID ( ) + ' _enable_backlog ' ] )
except :
2014-09-03 10:33:26 +00:00
curTorrentProvider . enable_backlog = 0 # these exceptions are actually catching unselected checkboxes
2014-05-18 16:39:30 +00:00
2014-05-20 02:14:06 +00:00
for curNzbProvider in [ curProvider for curProvider in sickbeard . providers . sortedProviderList ( ) if
2014-05-20 20:51:54 +00:00
curProvider . providerType == sickbeard . GenericProvider . NZB ] :
2014-05-20 02:14:06 +00:00
if hasattr ( curNzbProvider , ' api_key ' ) :
try :
curNzbProvider . api_key = str ( kwargs [ curNzbProvider . getID ( ) + ' _api_key ' ] ) . strip ( )
except :
curNzbProvider . api_key = None
if hasattr ( curNzbProvider , ' username ' ) :
2014-05-20 20:51:54 +00:00
try :
2014-05-20 02:14:06 +00:00
curNzbProvider . username = str ( kwargs [ curNzbProvider . getID ( ) + ' _username ' ] ) . strip ( )
except :
curNzbProvider . username = None
2014-04-26 13:35:37 +00:00
2014-05-20 02:29:51 +00:00
if hasattr ( curNzbProvider , ' search_mode ' ) :
try :
curNzbProvider . search_mode = str ( kwargs [ curNzbProvider . getID ( ) + ' _search_mode ' ] ) . strip ( )
except :
curNzbProvider . search_mode = ' eponly '
2014-05-20 20:51:54 +00:00
2014-05-20 02:29:51 +00:00
if hasattr ( curNzbProvider , ' search_fallback ' ) :
try :
curNzbProvider . search_fallback = config . checkbox_to_value (
kwargs [ curNzbProvider . getID ( ) + ' _search_fallback ' ] )
except :
2014-09-03 10:33:26 +00:00
curNzbProvider . search_fallback = 0 # these exceptions are actually catching unselected checkboxes
2014-05-20 20:51:54 +00:00
2014-08-29 05:16:25 +00:00
if hasattr ( curNzbProvider , ' enable_daily ' ) :
try :
curNzbProvider . enable_daily = config . checkbox_to_value (
kwargs [ curNzbProvider . getID ( ) + ' _enable_daily ' ] )
except :
2014-09-03 10:33:26 +00:00
curNzbProvider . enable_daily = 0 # these exceptions are actually catching unselected checkboxes
2014-08-29 05:16:25 +00:00
if hasattr ( curNzbProvider , ' enable_backlog ' ) :
2014-05-20 02:29:51 +00:00
try :
2014-08-29 05:16:25 +00:00
curNzbProvider . enable_backlog = config . checkbox_to_value (
kwargs [ curNzbProvider . getID ( ) + ' _enable_backlog ' ] )
2014-05-20 02:29:51 +00:00
except :
2014-09-03 10:33:26 +00:00
curNzbProvider . enable_backlog = 0 # these exceptions are actually catching unselected checkboxes
2014-05-20 02:29:51 +00:00
2014-03-10 05:18:05 +00:00
sickbeard . NEWZNAB_DATA = ' !!! ' . join ( [ x . configStr ( ) for x in sickbeard . newznabProviderList ] )
sickbeard . PROVIDER_ORDER = provider_list
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-03-25 05:57:24 +00:00
' <br /> \n ' . join ( results ) )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-07-24 19:43:01 +00:00
redirect ( " /config/providers/ " )
2014-03-10 05:18:05 +00:00
2014-07-27 14:39:33 +00:00
2014-06-19 08:37:44 +00:00
class ConfigNotifications ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_notifications.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
2014-05-20 20:51:54 +00:00
def saveNotifications ( self , use_xbmc = None , xbmc_always_on = None , xbmc_notify_onsnatch = None ,
xbmc_notify_ondownload = None ,
2014-03-25 05:57:24 +00:00
xbmc_notify_onsubtitledownload = None , xbmc_update_onlyfirst = None ,
xbmc_update_library = None , xbmc_update_full = None , xbmc_host = None , xbmc_username = None ,
xbmc_password = None ,
use_plex = None , plex_notify_onsnatch = None , plex_notify_ondownload = None ,
plex_notify_onsubtitledownload = None , plex_update_library = None ,
2014-03-10 05:18:05 +00:00
plex_server_host = None , plex_host = None , plex_username = None , plex_password = None ,
2014-03-25 05:57:24 +00:00
use_growl = None , growl_notify_onsnatch = None , growl_notify_ondownload = None ,
growl_notify_onsubtitledownload = None , growl_host = None , growl_password = None ,
use_prowl = None , prowl_notify_onsnatch = None , prowl_notify_ondownload = None ,
prowl_notify_onsubtitledownload = None , prowl_api = None , prowl_priority = 0 ,
use_twitter = None , twitter_notify_onsnatch = None , twitter_notify_ondownload = None ,
twitter_notify_onsubtitledownload = None ,
use_boxcar = None , boxcar_notify_onsnatch = None , boxcar_notify_ondownload = None ,
boxcar_notify_onsubtitledownload = None , boxcar_username = None ,
2014-05-07 14:23:06 +00:00
use_boxcar2 = None , boxcar2_notify_onsnatch = None , boxcar2_notify_ondownload = None ,
boxcar2_notify_onsubtitledownload = None , boxcar2_accesstoken = None ,
2014-03-25 05:57:24 +00:00
use_pushover = None , pushover_notify_onsnatch = None , pushover_notify_ondownload = None ,
2014-06-17 20:37:09 +00:00
pushover_notify_onsubtitledownload = None , pushover_userkey = None , pushover_apikey = None ,
2014-03-25 05:57:24 +00:00
use_libnotify = None , libnotify_notify_onsnatch = None , libnotify_notify_ondownload = None ,
libnotify_notify_onsubtitledownload = None ,
2014-03-10 05:18:05 +00:00
use_nmj = None , nmj_host = None , nmj_database = None , nmj_mount = None , use_synoindex = None ,
use_nmjv2 = None , nmjv2_host = None , nmjv2_dbloc = None , nmjv2_database = None ,
2014-03-25 05:57:24 +00:00
use_trakt = None , trakt_username = None , trakt_password = None , trakt_api = None ,
trakt_remove_watchlist = None , trakt_use_watchlist = None , trakt_method_add = None ,
2014-07-27 14:39:33 +00:00
trakt_start_paused = None , trakt_use_recommended = None , trakt_sync = None ,
2014-08-08 23:07:17 +00:00
trakt_default_indexer = None , trakt_remove_serieslist = None ,
2014-03-25 05:57:24 +00:00
use_synologynotifier = None , synologynotifier_notify_onsnatch = None ,
synologynotifier_notify_ondownload = None , synologynotifier_notify_onsubtitledownload = None ,
use_pytivo = None , pytivo_notify_onsnatch = None , pytivo_notify_ondownload = None ,
pytivo_notify_onsubtitledownload = None , pytivo_update_library = None ,
2014-03-10 05:18:05 +00:00
pytivo_host = None , pytivo_share_name = None , pytivo_tivo_name = None ,
2014-03-25 05:57:24 +00:00
use_nma = None , nma_notify_onsnatch = None , nma_notify_ondownload = None ,
nma_notify_onsubtitledownload = None , nma_api = None , nma_priority = 0 ,
use_pushalot = None , pushalot_notify_onsnatch = None , pushalot_notify_ondownload = None ,
pushalot_notify_onsubtitledownload = None , pushalot_authorizationtoken = None ,
use_pushbullet = None , pushbullet_notify_onsnatch = None , pushbullet_notify_ondownload = None ,
pushbullet_notify_onsubtitledownload = None , pushbullet_api = None , pushbullet_device = None ,
pushbullet_device_list = None ,
use_email = None , email_notify_onsnatch = None , email_notify_ondownload = None ,
email_notify_onsubtitledownload = None , email_host = None , email_port = 25 , email_from = None ,
email_tls = None , email_user = None , email_password = None , email_list = None , email_show_list = None ,
email_show = None ) :
2014-03-10 05:18:05 +00:00
results = [ ]
sickbeard . USE_XBMC = config . checkbox_to_value ( use_xbmc )
2014-05-08 15:54:43 +00:00
sickbeard . XBMC_ALWAYS_ON = config . checkbox_to_value ( xbmc_always_on )
2014-03-10 05:18:05 +00:00
sickbeard . XBMC_NOTIFY_ONSNATCH = config . checkbox_to_value ( xbmc_notify_onsnatch )
sickbeard . XBMC_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( xbmc_notify_ondownload )
sickbeard . XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( xbmc_notify_onsubtitledownload )
sickbeard . XBMC_UPDATE_LIBRARY = config . checkbox_to_value ( xbmc_update_library )
sickbeard . XBMC_UPDATE_FULL = config . checkbox_to_value ( xbmc_update_full )
sickbeard . XBMC_UPDATE_ONLYFIRST = config . checkbox_to_value ( xbmc_update_onlyfirst )
sickbeard . XBMC_HOST = config . clean_hosts ( xbmc_host )
sickbeard . XBMC_USERNAME = xbmc_username
sickbeard . XBMC_PASSWORD = xbmc_password
sickbeard . USE_PLEX = config . checkbox_to_value ( use_plex )
sickbeard . PLEX_NOTIFY_ONSNATCH = config . checkbox_to_value ( plex_notify_onsnatch )
sickbeard . PLEX_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( plex_notify_ondownload )
sickbeard . PLEX_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( plex_notify_onsubtitledownload )
sickbeard . PLEX_UPDATE_LIBRARY = config . checkbox_to_value ( plex_update_library )
sickbeard . PLEX_HOST = config . clean_hosts ( plex_host )
sickbeard . PLEX_SERVER_HOST = config . clean_host ( plex_server_host )
sickbeard . PLEX_USERNAME = plex_username
sickbeard . PLEX_PASSWORD = plex_password
sickbeard . USE_GROWL = config . checkbox_to_value ( use_growl )
sickbeard . GROWL_NOTIFY_ONSNATCH = config . checkbox_to_value ( growl_notify_onsnatch )
sickbeard . GROWL_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( growl_notify_ondownload )
sickbeard . GROWL_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( growl_notify_onsubtitledownload )
sickbeard . GROWL_HOST = config . clean_host ( growl_host , default_port = 23053 )
sickbeard . GROWL_PASSWORD = growl_password
sickbeard . USE_PROWL = config . checkbox_to_value ( use_prowl )
sickbeard . PROWL_NOTIFY_ONSNATCH = config . checkbox_to_value ( prowl_notify_onsnatch )
sickbeard . PROWL_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( prowl_notify_ondownload )
sickbeard . PROWL_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( prowl_notify_onsubtitledownload )
sickbeard . PROWL_API = prowl_api
sickbeard . PROWL_PRIORITY = prowl_priority
sickbeard . USE_TWITTER = config . checkbox_to_value ( use_twitter )
sickbeard . TWITTER_NOTIFY_ONSNATCH = config . checkbox_to_value ( twitter_notify_onsnatch )
sickbeard . TWITTER_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( twitter_notify_ondownload )
sickbeard . TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( twitter_notify_onsubtitledownload )
sickbeard . USE_BOXCAR = config . checkbox_to_value ( use_boxcar )
sickbeard . BOXCAR_NOTIFY_ONSNATCH = config . checkbox_to_value ( boxcar_notify_onsnatch )
sickbeard . BOXCAR_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( boxcar_notify_ondownload )
sickbeard . BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( boxcar_notify_onsubtitledownload )
sickbeard . BOXCAR_USERNAME = boxcar_username
2014-05-07 14:23:06 +00:00
sickbeard . USE_BOXCAR2 = config . checkbox_to_value ( use_boxcar2 )
sickbeard . BOXCAR2_NOTIFY_ONSNATCH = config . checkbox_to_value ( boxcar2_notify_onsnatch )
sickbeard . BOXCAR2_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( boxcar2_notify_ondownload )
sickbeard . BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( boxcar2_notify_onsubtitledownload )
sickbeard . BOXCAR2_ACCESSTOKEN = boxcar2_accesstoken
2014-03-10 05:18:05 +00:00
sickbeard . USE_PUSHOVER = config . checkbox_to_value ( use_pushover )
sickbeard . PUSHOVER_NOTIFY_ONSNATCH = config . checkbox_to_value ( pushover_notify_onsnatch )
sickbeard . PUSHOVER_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( pushover_notify_ondownload )
sickbeard . PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( pushover_notify_onsubtitledownload )
sickbeard . PUSHOVER_USERKEY = pushover_userkey
2014-06-17 20:37:09 +00:00
sickbeard . PUSHOVER_APIKEY = pushover_apikey
2014-03-10 05:18:05 +00:00
sickbeard . USE_LIBNOTIFY = config . checkbox_to_value ( use_libnotify )
sickbeard . LIBNOTIFY_NOTIFY_ONSNATCH = config . checkbox_to_value ( libnotify_notify_onsnatch )
sickbeard . LIBNOTIFY_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( libnotify_notify_ondownload )
sickbeard . LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( libnotify_notify_onsubtitledownload )
sickbeard . USE_NMJ = config . checkbox_to_value ( use_nmj )
sickbeard . NMJ_HOST = config . clean_host ( nmj_host )
sickbeard . NMJ_DATABASE = nmj_database
sickbeard . NMJ_MOUNT = nmj_mount
sickbeard . USE_NMJv2 = config . checkbox_to_value ( use_nmjv2 )
sickbeard . NMJv2_HOST = config . clean_host ( nmjv2_host )
sickbeard . NMJv2_DATABASE = nmjv2_database
sickbeard . NMJv2_DBLOC = nmjv2_dbloc
sickbeard . USE_SYNOINDEX = config . checkbox_to_value ( use_synoindex )
sickbeard . USE_SYNOLOGYNOTIFIER = config . checkbox_to_value ( use_synologynotifier )
sickbeard . SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH = config . checkbox_to_value ( synologynotifier_notify_onsnatch )
sickbeard . SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( synologynotifier_notify_ondownload )
2014-03-25 05:57:24 +00:00
sickbeard . SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value (
synologynotifier_notify_onsubtitledownload )
2014-03-10 05:18:05 +00:00
sickbeard . USE_TRAKT = config . checkbox_to_value ( use_trakt )
sickbeard . TRAKT_USERNAME = trakt_username
sickbeard . TRAKT_PASSWORD = trakt_password
sickbeard . TRAKT_API = trakt_api
sickbeard . TRAKT_REMOVE_WATCHLIST = config . checkbox_to_value ( trakt_remove_watchlist )
2014-08-08 23:07:17 +00:00
sickbeard . TRAKT_REMOVE_SERIESLIST = config . checkbox_to_value ( trakt_remove_serieslist )
2014-03-10 05:18:05 +00:00
sickbeard . TRAKT_USE_WATCHLIST = config . checkbox_to_value ( trakt_use_watchlist )
2014-08-11 11:29:35 +00:00
sickbeard . TRAKT_METHOD_ADD = int ( trakt_method_add )
2014-03-10 05:18:05 +00:00
sickbeard . TRAKT_START_PAUSED = config . checkbox_to_value ( trakt_start_paused )
2014-06-29 03:28:00 +00:00
sickbeard . TRAKT_USE_RECOMMENDED = config . checkbox_to_value ( trakt_use_recommended )
2014-06-29 05:54:29 +00:00
sickbeard . TRAKT_SYNC = config . checkbox_to_value ( trakt_sync )
2014-07-24 04:44:11 +00:00
sickbeard . TRAKT_DEFAULT_INDEXER = int ( trakt_default_indexer )
2014-03-10 05:18:05 +00:00
if sickbeard . USE_TRAKT :
2014-06-29 03:28:00 +00:00
sickbeard . traktCheckerScheduler . silent = False
2014-03-10 05:18:05 +00:00
else :
2014-06-29 03:28:00 +00:00
sickbeard . traktCheckerScheduler . silent = True
2014-03-10 05:18:05 +00:00
sickbeard . USE_EMAIL = config . checkbox_to_value ( use_email )
sickbeard . EMAIL_NOTIFY_ONSNATCH = config . checkbox_to_value ( email_notify_onsnatch )
sickbeard . EMAIL_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( email_notify_ondownload )
sickbeard . EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( email_notify_onsubtitledownload )
sickbeard . EMAIL_HOST = config . clean_host ( email_host )
sickbeard . EMAIL_PORT = config . to_int ( email_port , default = 25 )
sickbeard . EMAIL_FROM = email_from
sickbeard . EMAIL_TLS = config . checkbox_to_value ( email_tls )
sickbeard . EMAIL_USER = email_user
sickbeard . EMAIL_PASSWORD = email_password
sickbeard . EMAIL_LIST = email_list
sickbeard . USE_PYTIVO = config . checkbox_to_value ( use_pytivo )
sickbeard . PYTIVO_NOTIFY_ONSNATCH = config . checkbox_to_value ( pytivo_notify_onsnatch )
sickbeard . PYTIVO_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( pytivo_notify_ondownload )
sickbeard . PYTIVO_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( pytivo_notify_onsubtitledownload )
sickbeard . PYTIVO_UPDATE_LIBRARY = config . checkbox_to_value ( pytivo_update_library )
sickbeard . PYTIVO_HOST = config . clean_host ( pytivo_host )
sickbeard . PYTIVO_SHARE_NAME = pytivo_share_name
sickbeard . PYTIVO_TIVO_NAME = pytivo_tivo_name
sickbeard . USE_NMA = config . checkbox_to_value ( use_nma )
sickbeard . NMA_NOTIFY_ONSNATCH = config . checkbox_to_value ( nma_notify_onsnatch )
sickbeard . NMA_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( nma_notify_ondownload )
sickbeard . NMA_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( nma_notify_onsubtitledownload )
sickbeard . NMA_API = nma_api
sickbeard . NMA_PRIORITY = nma_priority
sickbeard . USE_PUSHALOT = config . checkbox_to_value ( use_pushalot )
sickbeard . PUSHALOT_NOTIFY_ONSNATCH = config . checkbox_to_value ( pushalot_notify_onsnatch )
sickbeard . PUSHALOT_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( pushalot_notify_ondownload )
sickbeard . PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( pushalot_notify_onsubtitledownload )
sickbeard . PUSHALOT_AUTHORIZATIONTOKEN = pushalot_authorizationtoken
sickbeard . USE_PUSHBULLET = config . checkbox_to_value ( use_pushbullet )
sickbeard . PUSHBULLET_NOTIFY_ONSNATCH = config . checkbox_to_value ( pushbullet_notify_onsnatch )
sickbeard . PUSHBULLET_NOTIFY_ONDOWNLOAD = config . checkbox_to_value ( pushbullet_notify_ondownload )
sickbeard . PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD = config . checkbox_to_value ( pushbullet_notify_onsubtitledownload )
sickbeard . PUSHBULLET_API = pushbullet_api
sickbeard . PUSHBULLET_DEVICE = pushbullet_device_list
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-03-25 05:57:24 +00:00
' <br /> \n ' . join ( results ) )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-07-24 19:43:01 +00:00
redirect ( " /config/notifications/ " )
2014-03-10 05:18:05 +00:00
2014-07-27 14:39:33 +00:00
2014-06-19 08:37:44 +00:00
class ConfigSubtitles ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_subtitles.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
def saveSubtitles ( self , use_subtitles = None , subtitles_plugins = None , subtitles_languages = None , subtitles_dir = None ,
service_order = None , subtitles_history = None , subtitles_finder_frequency = None ) :
2014-03-10 05:18:05 +00:00
results = [ ]
if subtitles_finder_frequency == ' ' or subtitles_finder_frequency is None :
subtitles_finder_frequency = 1
2014-07-20 00:03:23 +00:00
if use_subtitles == " on " and not sickbeard . subtitlesFinderScheduler . isAlive ( ) :
sickbeard . subtitlesFinderScheduler . silent = False
sickbeard . subtitlesFinderScheduler . start ( )
2014-03-10 05:18:05 +00:00
else :
2014-07-19 22:32:28 +00:00
sickbeard . subtitlesFinderScheduler . stop . set ( )
2014-03-10 05:18:05 +00:00
sickbeard . subtitlesFinderScheduler . silent = True
logger . log ( u " Waiting for the SUBTITLESFINDER thread to exit " )
try :
2014-07-20 00:03:23 +00:00
sickbeard . subtitlesFinderScheduler . join ( 5 )
2014-03-10 05:18:05 +00:00
except :
pass
sickbeard . USE_SUBTITLES = config . checkbox_to_value ( use_subtitles )
2014-03-25 05:57:24 +00:00
sickbeard . SUBTITLES_LANGUAGES = [ lang . alpha2 for lang in subtitles . isValidLanguage (
2014-07-20 00:03:23 +00:00
subtitles_languages . replace ( ' ' , ' ' ) . split ( ' , ' ) ) ] if subtitles_languages != ' ' else ' '
2014-03-10 05:18:05 +00:00
sickbeard . SUBTITLES_DIR = subtitles_dir
sickbeard . SUBTITLES_HISTORY = config . checkbox_to_value ( subtitles_history )
sickbeard . SUBTITLES_FINDER_FREQUENCY = config . to_int ( subtitles_finder_frequency , default = 1 )
# Subtitles services
services_str_list = service_order . split ( )
subtitles_services_list = [ ]
subtitles_services_enabled = [ ]
for curServiceStr in services_str_list :
curService , curEnabled = curServiceStr . split ( ' : ' )
subtitles_services_list . append ( curService )
subtitles_services_enabled . append ( int ( curEnabled ) )
sickbeard . SUBTITLES_SERVICES_LIST = subtitles_services_list
sickbeard . SUBTITLES_SERVICES_ENABLED = subtitles_services_enabled
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-03-25 05:57:24 +00:00
' <br /> \n ' . join ( results ) )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-07-24 19:43:01 +00:00
redirect ( " /config/subtitles/ " )
2014-05-26 06:29:22 +00:00
2014-07-27 14:39:33 +00:00
2014-06-19 08:37:44 +00:00
class ConfigAnime ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-05-26 06:29:22 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config_anime.tmpl " )
2014-05-26 06:29:22 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-05-26 06:29:22 +00:00
2014-06-07 12:36:50 +00:00
def saveAnime ( self , use_anidb = None , anidb_username = None , anidb_password = None , anidb_use_mylist = None ,
split_home = None ) :
2014-05-26 06:29:22 +00:00
results = [ ]
2014-07-27 10:59:21 +00:00
sickbeard . USE_ANIDB = config . checkbox_to_value ( use_anidb )
2014-05-26 06:29:22 +00:00
sickbeard . ANIDB_USERNAME = anidb_username
sickbeard . ANIDB_PASSWORD = anidb_password
2014-07-27 10:59:21 +00:00
sickbeard . ANIDB_USE_MYLIST = config . checkbox_to_value ( anidb_use_mylist )
sickbeard . ANIME_SPLIT_HOME = config . checkbox_to_value ( split_home )
2014-05-26 06:29:22 +00:00
sickbeard . save_config ( )
if len ( results ) > 0 :
for x in results :
logger . log ( x , logger . ERROR )
ui . notifications . error ( ' Error(s) Saving Configuration ' ,
2014-06-07 12:36:50 +00:00
' <br /> \n ' . join ( results ) )
2014-05-26 06:29:22 +00:00
else :
2014-06-07 12:36:50 +00:00
ui . notifications . message ( ' Configuration Saved ' , ek . ek ( os . path . join , sickbeard . CONFIG_FILE ) )
2014-05-26 06:29:22 +00:00
2014-07-24 19:43:01 +00:00
redirect ( " /config/anime/ " )
2014-06-07 12:36:50 +00:00
2014-07-27 14:39:33 +00:00
2014-06-19 08:37:44 +00:00
class Config ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " config.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ConfigMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-25 05:57:24 +00:00
2014-06-11 08:34:28 +00:00
# map class names to urls
general = ConfigGeneral
2014-06-19 14:31:44 +00:00
backuprestore = ConfigBackupRestore
2014-06-11 08:34:28 +00:00
search = ConfigSearch
providers = ConfigProviders
subtitles = ConfigSubtitles
postProcessing = ConfigPostProcessing
notifications = ConfigNotifications
anime = ConfigAnime
2014-06-07 12:36:50 +00:00
2014-06-16 05:45:52 +00:00
2014-03-10 05:18:05 +00:00
def haveXBMC ( ) :
return sickbeard . USE_XBMC and sickbeard . XBMC_UPDATE_LIBRARY
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
def havePLEX ( ) :
return sickbeard . USE_PLEX and sickbeard . PLEX_UPDATE_LIBRARY
2014-03-25 05:57:24 +00:00
2014-05-08 15:09:12 +00:00
def haveTORRENT ( ) :
2014-05-08 15:23:26 +00:00
if sickbeard . USE_TORRENTS and sickbeard . TORRENT_METHOD != ' blackhole ' \
and ( sickbeard . ENABLE_HTTPS and sickbeard . TORRENT_HOST [ : 5 ] == ' https '
or not sickbeard . ENABLE_HTTPS and sickbeard . TORRENT_HOST [ : 5 ] == ' http: ' ) :
return True
else :
return False
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
def HomeMenu ( ) :
return [
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Add Shows ' , ' path ' : ' home/addShows/ ' , } ,
{ ' title ' : ' Manual Post-Processing ' , ' path ' : ' home/postprocess/ ' } ,
{ ' title ' : ' Update XBMC ' , ' path ' : ' home/updateXBMC/ ' , ' requires ' : haveXBMC } ,
{ ' title ' : ' Update Plex ' , ' path ' : ' home/updatePLEX/ ' , ' requires ' : havePLEX } ,
2014-05-08 15:23:26 +00:00
{ ' title ' : ' Manage Torrents ' , ' path ' : ' manage/manageTorrents ' , ' requires ' : haveTORRENT } ,
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Restart ' , ' path ' : ' home/restart/?pid= ' + str ( sickbeard . PID ) , ' confirm ' : True } ,
{ ' title ' : ' Shutdown ' , ' path ' : ' home/shutdown/?pid= ' + str ( sickbeard . PID ) , ' confirm ' : True } ,
]
2014-03-10 05:18:05 +00:00
2014-06-19 08:37:44 +00:00
class HomePostProcess ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home_postprocess.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-07-27 14:39:33 +00:00
def processEpisode ( self , dir = None , nzbName = None , jobName = None , quiet = None , process_method = None , force = None ,
is_priority = None , failed = " 0 " , type = " auto " , * args , * * kwargs ) :
2014-03-16 22:57:38 +00:00
2014-03-10 05:18:05 +00:00
if failed == " 0 " :
failed = False
else :
failed = True
2014-07-15 17:26:01 +00:00
if force in [ " on " , " 1 " ] :
2014-03-25 05:57:24 +00:00
force = True
2014-03-10 05:18:05 +00:00
else :
2014-03-25 05:57:24 +00:00
force = False
2014-03-10 05:18:05 +00:00
2014-07-15 17:26:01 +00:00
if is_priority in [ " on " , " 1 " ] :
2014-03-10 05:18:05 +00:00
is_priority = True
else :
is_priority = False
2014-03-31 01:17:05 +00:00
if not dir :
2014-06-30 01:54:41 +00:00
redirect ( " /home/postprocess/ " )
2014-03-31 01:17:05 +00:00
else :
2014-05-20 20:51:54 +00:00
result = processTV . processDir ( dir , nzbName , process_method = process_method , force = force ,
is_priority = is_priority , failed = failed , type = type )
2014-03-31 01:17:05 +00:00
if quiet is not None and int ( quiet ) == 1 :
return result
2014-03-10 05:18:05 +00:00
2014-03-31 01:17:05 +00:00
result = result . replace ( " \n " , " <br /> \n " )
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Postprocessing results " , result )
2014-03-10 05:18:05 +00:00
2014-06-19 08:37:44 +00:00
class NewHomeAddShows ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home_addShows.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def getIndexerLanguages ( self , * args , * * kwargs ) :
2014-03-25 05:57:24 +00:00
result = sickbeard . indexerApi ( ) . config [ ' valid_languages ' ]
2014-03-10 05:18:05 +00:00
# Make sure list is sorted alphabetically but 'en' is in front
if ' en ' in result :
del result [ result . index ( ' en ' ) ]
result . sort ( )
result . insert ( 0 , ' en ' )
return json . dumps ( { ' results ' : result } )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def sanitizeFileName ( self , name ) :
return helpers . sanitizeFileName ( name )
2014-06-11 08:34:28 +00:00
2014-04-24 11:52:44 +00:00
def searchIndexersForShowName ( self , search_term , lang = " en " , indexer = None ) :
2014-03-10 05:18:05 +00:00
if not lang or lang == ' null ' :
lang = " en "
2014-06-07 11:06:21 +00:00
search_term = search_term . encode ( ' utf-8 ' )
2014-06-07 12:36:50 +00:00
2014-04-24 11:52:44 +00:00
results = { }
2014-04-22 14:14:11 +00:00
final_results = [ ]
2014-03-25 05:57:24 +00:00
# Query Indexers for each search term and build the list of results
2014-04-24 11:52:44 +00:00
for indexer in sickbeard . indexerApi ( ) . indexers if not int ( indexer ) else [ int ( indexer ) ] :
2014-03-26 19:28:46 +00:00
lINDEXER_API_PARMS = sickbeard . indexerApi ( indexer ) . api_params . copy ( )
2014-04-24 11:52:44 +00:00
lINDEXER_API_PARMS [ ' language ' ] = lang
2014-03-26 19:28:46 +00:00
lINDEXER_API_PARMS [ ' custom_ui ' ] = classes . AllShowsListUI
t = sickbeard . indexerApi ( indexer ) . indexer ( * * lINDEXER_API_PARMS )
2014-03-10 05:18:05 +00:00
2014-05-20 20:51:54 +00:00
logger . log ( " Searching for Show with searchterm: %s on Indexer: %s " % (
2014-06-07 12:36:50 +00:00
search_term , sickbeard . indexerApi ( indexer ) . name ) , logger . DEBUG )
2014-04-24 11:52:44 +00:00
try :
# add search results
results . setdefault ( indexer , [ ] ) . extend ( t [ search_term ] )
2014-04-25 21:22:31 +00:00
except Exception , e :
continue
2014-03-10 05:18:05 +00:00
2014-04-24 11:52:44 +00:00
map ( final_results . extend ,
( [ [ sickbeard . indexerApi ( id ) . name , id , sickbeard . indexerApi ( id ) . config [ " show_url " ] , int ( show [ ' id ' ] ) ,
2014-06-07 12:36:50 +00:00
show [ ' seriesname ' ] , show [ ' firstaired ' ] ] for show in shows ] for id , shows in results . items ( ) ) )
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
lang_id = sickbeard . indexerApi ( ) . config [ ' langabbv_to_id ' ] [ lang ]
2014-04-22 14:14:11 +00:00
return json . dumps ( { ' results ' : final_results , ' langid ' : lang_id } )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def massAddTable ( self , rootDir = None ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home_massAddTable.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
if not rootDir :
return " No folders selected. "
elif type ( rootDir ) != list :
root_dirs = [ rootDir ]
else :
root_dirs = rootDir
root_dirs = [ urllib . unquote_plus ( x ) for x in root_dirs ]
if sickbeard . ROOT_DIRS :
default_index = int ( sickbeard . ROOT_DIRS . split ( ' | ' ) [ 0 ] )
else :
default_index = 0
if len ( root_dirs ) > default_index :
tmp = root_dirs [ default_index ]
if tmp in root_dirs :
root_dirs . remove ( tmp )
root_dirs = [ tmp ] + root_dirs
dir_list = [ ]
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
for root_dir in root_dirs :
try :
file_list = ek . ek ( os . listdir , root_dir )
except :
continue
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
for cur_file in file_list :
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
cur_path = ek . ek ( os . path . normpath , ek . ek ( os . path . join , root_dir , cur_file ) )
if not ek . ek ( os . path . isdir , cur_path ) :
continue
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
cur_dir = {
' dir ' : cur_path ,
' display_dir ' : ' <b> ' + ek . ek ( os . path . dirname , cur_path ) + os . sep + ' </b> ' + ek . ek (
os . path . basename ,
cur_path ) ,
2014-07-06 14:45:01 +00:00
}
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
# see if the folder is in XBMC already
dirResults = myDB . select ( " SELECT * FROM tv_shows WHERE location = ? " , [ cur_path ] )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
if dirResults :
cur_dir [ ' added_already ' ] = True
else :
cur_dir [ ' added_already ' ] = False
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
dir_list . append ( cur_dir )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
indexer_id = show_name = indexer = None
for cur_provider in sickbeard . metadata_provider_dict . values ( ) :
( indexer_id , show_name , indexer ) = cur_provider . retrieveShowMetadata ( cur_path )
2014-03-10 05:18:05 +00:00
2014-07-24 16:12:29 +00:00
# default to TVDB if indexer was not detected
if show_name and not ( indexer or indexer_id ) :
( sn , idx , id ) = helpers . searchIndexerForShowID ( show_name , indexer , indexer_id )
2014-05-01 10:00:05 +00:00
2014-07-24 16:12:29 +00:00
# set indexer and indexer_id from found info
if not indexer and idx :
indexer = idx
2014-05-01 10:00:05 +00:00
2014-07-24 16:12:29 +00:00
if not indexer_id and id :
indexer_id = id
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
cur_dir [ ' existing_info ' ] = ( indexer_id , show_name , indexer )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
if indexer_id and helpers . findCertainShow ( sickbeard . showList , indexer_id ) :
cur_dir [ ' added_already ' ] = True
2014-03-10 05:18:05 +00:00
t . dirList = dir_list
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def newShow ( self , show_to_add = None , other_shows = None ) :
"""
Display the new show page which collects a tvdb id , folder , and extra options and
posts them to addNewShow
"""
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home_newShow.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
indexer , show_dir , indexer_id , show_name = self . split_extra_show ( show_to_add )
if indexer_id and indexer and show_name :
use_provided_info = True
else :
use_provided_info = False
2014-03-16 06:28:11 +00:00
# tell the template whether we're giving it show name & Indexer ID
2014-03-10 05:18:05 +00:00
t . use_provided_info = use_provided_info
2014-03-16 06:28:11 +00:00
# use the given show_dir for the indexer search if available
2014-03-10 05:18:05 +00:00
if not show_dir :
t . default_show_name = ' '
elif not show_name :
2014-03-25 05:57:24 +00:00
t . default_show_name = ek . ek ( os . path . basename , ek . ek ( os . path . normpath , show_dir ) ) . replace ( ' . ' , ' ' )
2014-03-10 05:18:05 +00:00
else :
t . default_show_name = show_name
# carry a list of other dirs if given
if not other_shows :
other_shows = [ ]
elif type ( other_shows ) != list :
other_shows = [ other_shows ]
if use_provided_info :
2014-03-25 05:57:24 +00:00
t . provided_indexer_id = int ( indexer_id or 0 )
2014-03-10 05:18:05 +00:00
t . provided_indexer_name = show_name
t . provided_show_dir = show_dir
t . other_shows = other_shows
2014-05-02 00:57:51 +00:00
t . provided_indexer = int ( indexer or sickbeard . INDEXER_DEFAULT )
2014-04-22 22:58:43 +00:00
t . indexers = sickbeard . indexerApi ( ) . indexers
2014-03-10 05:18:05 +00:00
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-06-27 11:00:16 +00:00
def recommendedShows ( self , * args , * * kwargs ) :
"""
Display the new show page which collects a tvdb id , folder , and extra options and
posts them to addNewShow
"""
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home_recommendedShows.tmpl " )
2014-06-27 11:00:16 +00:00
t . submenu = HomeMenu ( )
return _munge ( t )
def getRecommendedShows ( self , * args , * * kwargs ) :
final_results = [ ]
2014-06-27 11:04:54 +00:00
2014-06-29 03:28:00 +00:00
logger . log ( u " Getting recommended shows from Trakt.tv " , logger . DEBUG )
2014-08-29 10:29:56 +00:00
recommendedlist = TraktCall ( " recommendations/shows.json/ % API % " , sickbeard . TRAKT_API , sickbeard . TRAKT_USERNAME ,
sickbeard . TRAKT_PASSWORD )
2014-08-08 23:07:17 +00:00
if recommendedlist == ' NULL ' :
logger . log ( u " No shows found in your recommendedlist, aborting recommendedlist update " , logger . DEBUG )
return
2014-06-29 03:28:00 +00:00
if recommendedlist is None :
logger . log ( u " Could not connect to trakt service, aborting recommended list update " , logger . ERROR )
return
2014-07-01 08:49:12 +00:00
map ( final_results . append ,
2014-08-29 10:29:56 +00:00
( [ int ( show [ ' tvdb_id ' ] or 0 ) if sickbeard . TRAKT_DEFAULT_INDEXER == 1 else int ( show [ ' tvdb_id ' ] or 0 ) ,
show [ ' url ' ] , show [ ' title ' ] , show [ ' overview ' ] ,
2014-07-01 08:49:12 +00:00
datetime . date . fromtimestamp ( int ( show [ ' first_aired ' ] ) / 1000.0 ) . strftime ( ' % Y % m %d ' ) ] for show in
recommendedlist if not helpers . findCertainShow ( sickbeard . showList , indexerid = int ( show [ ' tvdb_id ' ] ) ) ) )
2014-06-27 11:00:16 +00:00
2014-06-27 11:04:54 +00:00
return json . dumps ( { ' results ' : final_results } )
2014-06-27 11:00:16 +00:00
def addRecommendedShow ( self , whichSeries = None , indexerLang = " en " , rootDir = None , defaultStatus = None ,
anyQualities = None , bestQualities = None , flatten_folders = None , subtitles = None ,
fullShowPath = None , other_shows = None , skipShow = None , providedIndexer = None , anime = None ,
scene = None ) :
indexer = 1
indexer_name = sickbeard . indexerApi ( int ( indexer ) ) . name
show_url = whichSeries . split ( ' | ' ) [ 1 ]
indexer_id = whichSeries . split ( ' | ' ) [ 0 ]
show_name = whichSeries . split ( ' | ' ) [ 2 ]
2014-06-29 05:54:29 +00:00
return self . addNewShow ( ' | ' . join ( [ indexer_name , str ( indexer ) , show_url , indexer_id , show_name , " " ] ) ,
2014-07-01 08:49:12 +00:00
indexerLang , rootDir ,
defaultStatus ,
anyQualities , bestQualities , flatten_folders , subtitles , fullShowPath , other_shows ,
skipShow , providedIndexer , anime , scene )
def trendingShows ( self , * args , * * kwargs ) :
"""
Display the new show page which collects a tvdb id , folder , and extra options and
posts them to addNewShow
"""
t = PageTemplate ( headers = self . request . headers , file = " home_trendingShows.tmpl " )
t . submenu = HomeMenu ( )
2014-07-27 14:49:13 +00:00
t . trending_shows = TraktCall ( " shows/trending.json/ % API % " , sickbeard . TRAKT_API_KEY )
2014-07-01 08:49:12 +00:00
return _munge ( t )
2014-06-27 11:00:16 +00:00
2014-06-11 08:34:28 +00:00
def existingShows ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
"""
Prints out the page to add existing shows from a root dir
"""
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home_addExistingShow.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-07-01 08:49:12 +00:00
def addTraktShow ( self , indexer_id , showName ) :
if helpers . findCertainShow ( sickbeard . showList , int ( indexer_id ) ) :
return
2014-07-11 00:20:31 +00:00
if sickbeard . ROOT_DIRS :
root_dirs = sickbeard . ROOT_DIRS . split ( ' | ' )
2014-07-09 18:41:04 +00:00
location = root_dirs [ int ( root_dirs [ 0 ] ) + 1 ]
2014-07-11 00:20:31 +00:00
else :
location = None
2014-07-09 18:41:04 +00:00
2014-07-11 00:20:31 +00:00
if location :
2014-07-09 18:41:04 +00:00
show_dir = ek . ek ( os . path . join , location , helpers . sanitizeFileName ( showName ) )
dir_exists = helpers . makeDir ( show_dir )
if not dir_exists :
logger . log ( u " Unable to create the folder " + show_dir + " , can ' t add the show " , logger . ERROR )
return
else :
helpers . chmodAsParent ( show_dir )
2014-07-01 08:49:12 +00:00
2014-07-09 18:41:04 +00:00
sickbeard . showQueueScheduler . action . addShow ( 1 , int ( indexer_id ) , show_dir ,
default_status = sickbeard . STATUS_DEFAULT ,
quality = sickbeard . QUALITY_DEFAULT ,
flatten_folders = sickbeard . FLATTEN_FOLDERS_DEFAULT ,
subtitles = sickbeard . SUBTITLES_DEFAULT ,
anime = sickbeard . ANIME_DEFAULT ,
scene = sickbeard . SCENE_DEFAULT )
2014-07-01 08:49:12 +00:00
2014-07-09 18:41:04 +00:00
ui . notifications . message ( ' Show added ' , ' Adding the specified show into ' + show_dir )
else :
logger . log ( u " There was an error creating the show, no root directory setting found " , logger . ERROR )
return
2014-07-01 08:49:12 +00:00
# done adding show
redirect ( ' /home/ ' )
2014-03-10 05:18:05 +00:00
2014-03-11 02:32:02 +00:00
def addNewShow ( self , whichSeries = None , indexerLang = " en " , rootDir = None , defaultStatus = None ,
2014-03-10 05:18:05 +00:00
anyQualities = None , bestQualities = None , flatten_folders = None , subtitles = None ,
2014-06-02 03:43:37 +00:00
fullShowPath = None , other_shows = None , skipShow = None , providedIndexer = None , anime = None ,
scene = None ) :
2014-03-10 05:18:05 +00:00
"""
Receive tvdb id , dir , and other options and create a show from them . If extra show dirs are
provided then it forwards back to newShow , if not it goes to / home .
"""
# grab our list of other dirs if given
if not other_shows :
other_shows = [ ]
elif type ( other_shows ) != list :
other_shows = [ other_shows ]
def finishAddShow ( ) :
# if there are no extra shows then go home
if not other_shows :
2014-06-30 01:54:41 +00:00
redirect ( ' /home/ ' )
2014-03-10 05:18:05 +00:00
# peel off the next one
next_show_dir = other_shows [ 0 ]
rest_of_show_dirs = other_shows [ 1 : ]
# go to add the next show
return self . newShow ( next_show_dir , rest_of_show_dirs )
# if we're skipping then behave accordingly
if skipShow :
return finishAddShow ( )
# sanity check on our inputs
if ( not rootDir and not fullShowPath ) or not whichSeries :
2014-04-27 10:58:49 +00:00
return " Missing params, no Indexer ID or folder: " + repr ( whichSeries ) + " and " + repr (
2014-03-25 05:57:24 +00:00
rootDir ) + " / " + repr ( fullShowPath )
2014-03-10 05:18:05 +00:00
# figure out what show we're adding and where
series_pieces = whichSeries . split ( ' | ' )
2014-05-09 01:51:58 +00:00
if ( whichSeries and rootDir ) or ( whichSeries and fullShowPath and len ( series_pieces ) > 1 ) :
if len ( series_pieces ) < 6 :
2014-05-20 20:51:54 +00:00
logger . log ( " Unable to add show due to show selection. Not anough arguments: %s " % ( repr ( series_pieces ) ) ,
logger . ERROR )
2014-05-09 01:51:58 +00:00
ui . notifications . error ( " Unknown error. Unable to add show due to problem with show selection. " )
2014-06-30 01:54:41 +00:00
redirect ( ' /home/addShows/existingShows/ ' )
2014-05-09 01:51:58 +00:00
indexer = int ( series_pieces [ 1 ] )
indexer_id = int ( series_pieces [ 3 ] )
show_name = series_pieces [ 4 ]
else :
2014-06-02 03:43:37 +00:00
# if no indexer was provided use the default indexer set in General settings
if not providedIndexer :
providedIndexer = sickbeard . INDEXER_DEFAULT
2014-05-26 06:29:22 +00:00
indexer = int ( providedIndexer )
2014-05-09 01:51:58 +00:00
indexer_id = int ( whichSeries )
show_name = os . path . basename ( os . path . normpath ( fullShowPath ) )
2014-03-10 05:18:05 +00:00
# use the whole path if it's given, or else append the show name to the root dir to get the full show path
if fullShowPath :
show_dir = ek . ek ( os . path . normpath , fullShowPath )
else :
show_dir = ek . ek ( os . path . join , rootDir , helpers . sanitizeFileName ( show_name ) )
# blanket policy - if the dir exists you should have used "add existing show" numbnuts
if ek . ek ( os . path . isdir , show_dir ) and not fullShowPath :
ui . notifications . error ( " Unable to add show " , " Folder " + show_dir + " exists already " )
2014-06-30 01:54:41 +00:00
redirect ( ' /home/addShows/existingShows/ ' )
2014-03-10 05:18:05 +00:00
# don't create show dir if config says not to
if sickbeard . ADD_SHOWS_WO_DIR :
logger . log ( u " Skipping initial creation of " + show_dir + " due to config.ini setting " )
else :
dir_exists = helpers . makeDir ( show_dir )
if not dir_exists :
logger . log ( u " Unable to create the folder " + show_dir + " , can ' t add the show " , logger . ERROR )
2014-03-25 05:57:24 +00:00
ui . notifications . error ( " Unable to add show " ,
" Unable to create the folder " + show_dir + " , can ' t add the show " )
2014-06-30 01:54:41 +00:00
redirect ( " /home/ " )
2014-03-10 05:18:05 +00:00
else :
helpers . chmodAsParent ( show_dir )
# prepare the inputs for passing along
2014-06-02 03:43:37 +00:00
scene = config . checkbox_to_value ( scene )
2014-05-26 06:29:22 +00:00
anime = config . checkbox_to_value ( anime )
2014-03-10 05:18:05 +00:00
flatten_folders = config . checkbox_to_value ( flatten_folders )
subtitles = config . checkbox_to_value ( subtitles )
if not anyQualities :
anyQualities = [ ]
if not bestQualities :
bestQualities = [ ]
if type ( anyQualities ) != list :
anyQualities = [ anyQualities ]
if type ( bestQualities ) != list :
bestQualities = [ bestQualities ]
newQuality = Quality . combineQualities ( map ( int , anyQualities ) , map ( int , bestQualities ) )
# add the show
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . addShow ( indexer , indexer_id , show_dir , int ( defaultStatus ) , newQuality ,
2014-06-12 20:38:59 +00:00
flatten_folders , indexerLang , subtitles , anime ,
2014-06-07 12:36:50 +00:00
scene ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
ui . notifications . message ( ' Show added ' , ' Adding the specified show into ' + show_dir )
return finishAddShow ( )
def split_extra_show ( self , extra_show ) :
if not extra_show :
return ( None , None , None , None )
split_vals = extra_show . split ( ' | ' )
if len ( split_vals ) < 4 :
indexer = split_vals [ 0 ]
show_dir = split_vals [ 1 ]
return ( indexer , show_dir , None , None )
indexer = split_vals [ 0 ]
show_dir = split_vals [ 1 ]
indexer_id = split_vals [ 2 ]
show_name = ' | ' . join ( split_vals [ 3 : ] )
return ( indexer , show_dir , indexer_id , show_name )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def addExistingShows ( self , shows_to_add = None , promptForSettings = None ) :
"""
Receives a dir list and add them . Adds the ones with given TVDB IDs first , then forwards
along to the newShow page .
"""
# grab a list of other shows to add, if provided
if not shows_to_add :
shows_to_add = [ ]
elif type ( shows_to_add ) != list :
shows_to_add = [ shows_to_add ]
shows_to_add = [ urllib . unquote_plus ( x ) for x in shows_to_add ]
promptForSettings = config . checkbox_to_value ( promptForSettings )
indexer_id_given = [ ]
dirs_only = [ ]
# separate all the ones with Indexer IDs
for cur_dir in shows_to_add :
if ' | ' in cur_dir :
split_vals = cur_dir . split ( ' | ' )
if len ( split_vals ) < 3 :
dirs_only . append ( cur_dir )
if not ' | ' in cur_dir :
dirs_only . append ( cur_dir )
else :
indexer , show_dir , indexer_id , show_name = self . split_extra_show ( cur_dir )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
if not show_dir or not indexer_id or not show_name :
continue
2014-03-25 05:57:24 +00:00
indexer_id_given . append ( ( int ( indexer ) , show_dir , int ( indexer_id ) , show_name ) )
2014-03-10 05:18:05 +00:00
# if they want me to prompt for settings then I will just carry on to the newShow page
if promptForSettings and shows_to_add :
return self . newShow ( shows_to_add [ 0 ] , shows_to_add [ 1 : ] )
# if they don't want me to prompt for settings then I can just add all the nfo shows now
num_added = 0
for cur_show in indexer_id_given :
indexer , show_dir , indexer_id , show_name = cur_show
if indexer is not None and indexer_id is not None :
# add the show
2014-05-04 03:52:47 +00:00
sickbeard . showQueueScheduler . action . addShow ( indexer , indexer_id , show_dir ,
2014-06-05 02:47:40 +00:00
default_status = sickbeard . STATUS_DEFAULT ,
quality = sickbeard . QUALITY_DEFAULT ,
flatten_folders = sickbeard . FLATTEN_FOLDERS_DEFAULT ,
subtitles = sickbeard . SUBTITLES_DEFAULT ,
anime = sickbeard . ANIME_DEFAULT ,
scene = sickbeard . SCENE_DEFAULT )
2014-03-10 05:18:05 +00:00
num_added + = 1
if num_added :
2014-03-25 05:57:24 +00:00
ui . notifications . message ( " Shows Added " ,
" Automatically added " + str ( num_added ) + " from their existing metadata files " )
2014-03-10 05:18:05 +00:00
# if we're done then go home
if not dirs_only :
2014-06-30 01:54:41 +00:00
redirect ( ' /home/ ' )
2014-03-10 05:18:05 +00:00
# for the remaining shows we need to prompt for each one, so forward this on to the newShow page
return self . newShow ( dirs_only [ 0 ] , dirs_only [ 1 : ] )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
ErrorLogsMenu = [
2014-03-25 05:57:24 +00:00
{ ' title ' : ' Clear Errors ' , ' path ' : ' errorlogs/clearerrors/ ' } ,
2014-06-07 12:36:50 +00:00
# { 'title': 'View Log', 'path': 'errorlogs/viewlog' },
2014-03-10 05:18:05 +00:00
]
2014-06-19 08:37:44 +00:00
class ErrorLogs ( MainHandler ) :
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " errorlogs.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ErrorLogsMenu
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def clearerrors ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
classes . ErrorViewer . clear ( )
2014-06-30 01:54:41 +00:00
redirect ( " /errorlogs/ " )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def viewlog ( self , minLevel = logger . MESSAGE , maxLines = 500 ) :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " viewlogs.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = ErrorLogsMenu
minLevel = int ( minLevel )
data = [ ]
if os . path . isfile ( logger . sb_log_instance . log_file_path ) :
with ek . ek ( open , logger . sb_log_instance . log_file_path ) as f :
data = f . readlines ( )
regex = " ^( \ d \ d \ d \ d) \ -( \ d \ d) \ -( \ d \ d) \ s*( \ d \ d) \ :( \ d \ d):( \ d \ d) \ s*([A-Z]+) \ s*(.+?) \ s* \ : \ : \ s*(.*)$ "
finalData = [ ]
numLines = 0
lastLine = False
numToShow = min ( maxLines , len ( data ) )
for x in reversed ( data ) :
x = x . decode ( ' utf-8 ' , ' replace ' )
match = re . match ( regex , x )
if match :
level = match . group ( 7 )
if level not in logger . reverseNames :
lastLine = False
continue
if logger . reverseNames [ level ] > = minLevel :
lastLine = True
finalData . append ( x )
else :
lastLine = False
continue
elif lastLine :
finalData . append ( " AA " + x )
numLines + = 1
if numLines > = numToShow :
break
result = " " . join ( finalData )
t . logLines = result
t . minLevel = minLevel
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-19 08:37:44 +00:00
class Home ( MainHandler ) :
2014-03-10 05:18:05 +00:00
def is_alive ( self , * args , * * kwargs ) :
if ' callback ' in kwargs and ' _ ' in kwargs :
callback , _ = kwargs [ ' callback ' ] , kwargs [ ' _ ' ]
else :
2014-06-07 21:32:38 +00:00
return " Error: Unsupported Request. Send jsonp request with ' callback ' variable in the query string. "
2014-03-10 05:18:05 +00:00
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-06-16 05:45:52 +00:00
self . set_header ( ' Content-Type ' , ' text/javascript ' )
self . set_header ( ' Access-Control-Allow-Origin ' , ' * ' )
self . set_header ( ' Access-Control-Allow-Headers ' , ' x-requested-with ' )
2014-03-10 05:18:05 +00:00
if sickbeard . started :
2014-06-27 11:00:16 +00:00
return callback + ' ( ' + json . dumps (
2014-07-01 13:08:10 +00:00
{ " msg " : str ( sickbeard . PID ) } ) + ' ); '
2014-03-10 05:18:05 +00:00
else :
2014-07-01 13:08:10 +00:00
return callback + ' ( ' + json . dumps ( { " msg " : " nope " } ) + ' ); '
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def index ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " home.tmpl " )
2014-05-26 06:29:22 +00:00
if sickbeard . ANIME_SPLIT_HOME :
shows = [ ]
anime = [ ]
for show in sickbeard . showList :
if show . is_anime :
anime . append ( show )
else :
shows . append ( show )
2014-06-07 12:36:50 +00:00
t . showlists = [ [ " Shows " , shows ] ,
[ " Anime " , anime ] ]
2014-05-26 06:29:22 +00:00
else :
2014-06-07 12:36:50 +00:00
t . showlists = [ [ " Shows " , sickbeard . showList ] ]
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
2014-07-06 14:45:01 +00:00
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
addShows = NewHomeAddShows
postprocess = HomePostProcess
2014-03-10 05:18:05 +00:00
def testSABnzbd ( self , host = None , username = None , password = None , apikey = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
host = config . clean_url ( host )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
connection , accesMsg = sab . getSabAccesMethod ( host , username , password , apikey )
if connection :
2014-06-07 12:36:50 +00:00
authed , authMsg = sab . testAuthentication ( host , username , password , apikey ) # @UnusedVariable
2014-03-10 05:18:05 +00:00
if authed :
return " Success. Connected and authenticated "
else :
return " Authentication failed. SABnzbd expects ' " + accesMsg + " ' as authentication method "
else :
return " Unable to connect to host "
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testTorrent ( self , torrent_method = None , host = None , username = None , password = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
host = config . clean_url ( host )
client = clients . getClientIstance ( torrent_method )
connection , accesMsg = client ( host , username , password ) . testAuthentication ( )
return accesMsg
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testGrowl ( self , host = None , password = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
host = config . clean_host ( host , default_port = 23053 )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
result = notifiers . growl_notifier . test_notify ( host , password )
2014-03-25 05:57:24 +00:00
if password is None or password == ' ' :
2014-03-10 05:18:05 +00:00
pw_append = ' '
else :
pw_append = " with password: " + password
if result :
return " Registered and Tested growl successfully " + urllib . unquote_plus ( host ) + pw_append
else :
return " Registration and Testing of growl failed " + urllib . unquote_plus ( host ) + pw_append
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testProwl ( self , prowl_api = None , prowl_priority = 0 ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . prowl_notifier . test_notify ( prowl_api , prowl_priority )
if result :
return " Test prowl notice sent successfully "
else :
return " Test prowl notice failed "
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testBoxcar ( self , username = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . boxcar_notifier . test_notify ( username )
if result :
return " Boxcar notification succeeded. Check your Boxcar clients to make sure it worked "
else :
return " Error sending Boxcar notification "
2014-06-11 08:34:28 +00:00
2014-05-07 14:23:06 +00:00
def testBoxcar2 ( self , accesstoken = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-05-07 14:23:06 +00:00
result = notifiers . boxcar2_notifier . test_notify ( accesstoken )
if result :
return " Boxcar2 notification succeeded. Check your Boxcar2 clients to make sure it worked "
else :
return " Error sending Boxcar2 notification "
2014-06-11 08:34:28 +00:00
2014-06-17 20:37:09 +00:00
def testPushover ( self , userKey = None , apiKey = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
2014-06-17 20:37:09 +00:00
result = notifiers . pushover_notifier . test_notify ( userKey , apiKey )
2014-03-10 05:18:05 +00:00
if result :
return " Pushover notification succeeded. Check your Pushover clients to make sure it worked "
else :
return " Error sending Pushover notification "
2014-06-11 08:34:28 +00:00
def twitterStep1 ( self , * args , * * kwargs ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
return notifiers . twitter_notifier . _get_authorization ( )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def twitterStep2 ( self , key ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . twitter_notifier . _get_credentials ( key )
logger . log ( u " result: " + str ( result ) )
if result :
return " Key verification successful "
else :
return " Unable to verify key "
2014-06-11 08:34:28 +00:00
def testTwitter ( self , * args , * * kwargs ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . twitter_notifier . test_notify ( )
if result :
return " Tweet successful, check your twitter to make sure it worked "
else :
return " Error sending tweet "
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testXBMC ( self , host = None , username = None , password = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
host = config . clean_hosts ( host )
2014-03-10 05:18:05 +00:00
finalResult = ' '
for curHost in [ x . strip ( ) for x in host . split ( " , " ) ] :
curResult = notifiers . xbmc_notifier . test_notify ( urllib . unquote_plus ( curHost ) , username , password )
if len ( curResult . split ( " : " ) ) > 2 and ' OK ' in curResult . split ( " : " ) [ 2 ] :
finalResult + = " Test XBMC notice sent successfully to " + urllib . unquote_plus ( curHost )
else :
finalResult + = " Test XBMC notice failed to " + urllib . unquote_plus ( curHost )
finalResult + = " <br /> \n "
return finalResult
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testPLEX ( self , host = None , username = None , password = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
finalResult = ' '
for curHost in [ x . strip ( ) for x in host . split ( " , " ) ] :
curResult = notifiers . plex_notifier . test_notify ( urllib . unquote_plus ( curHost ) , username , password )
if len ( curResult . split ( " : " ) ) > 2 and ' OK ' in curResult . split ( " : " ) [ 2 ] :
finalResult + = " Test Plex notice sent successfully to " + urllib . unquote_plus ( curHost )
else :
finalResult + = " Test Plex notice failed to " + urllib . unquote_plus ( curHost )
finalResult + = " <br /> \n "
return finalResult
2014-06-11 08:34:28 +00:00
def testLibnotify ( self , * args , * * kwargs ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
if notifiers . libnotify_notifier . test_notify ( ) :
return " Tried sending desktop notification via libnotify "
else :
return notifiers . libnotify . diagnose ( )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testNMJ ( self , host = None , database = None , mount = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
host = config . clean_host ( host )
result = notifiers . nmj_notifier . test_notify ( urllib . unquote_plus ( host ) , database , mount )
if result :
return " Successfully started the scan update "
else :
return " Test failed to start the scan update "
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def settingsNMJ ( self , host = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
host = config . clean_host ( host )
result = notifiers . nmj_notifier . notify_settings ( urllib . unquote_plus ( host ) )
if result :
2014-03-25 05:57:24 +00:00
return ' { " message " : " Got settings from %(host)s " , " database " : " %(database)s " , " mount " : " %(mount)s " } ' % {
2014-03-27 02:01:53 +00:00
" host " : host , " database " : sickbeard . NMJ_DATABASE , " mount " : sickbeard . NMJ_MOUNT }
2014-03-10 05:18:05 +00:00
else :
return ' { " message " : " Failed! Make sure your Popcorn is on and NMJ is running. (see Log & Errors -> Debug for detailed info) " , " database " : " " , " mount " : " " } '
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testNMJv2 ( self , host = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
host = config . clean_host ( host )
result = notifiers . nmjv2_notifier . test_notify ( urllib . unquote_plus ( host ) )
if result :
return " Test notice sent successfully to " + urllib . unquote_plus ( host )
else :
return " Test notice failed to " + urllib . unquote_plus ( host )
2014-06-11 08:34:28 +00:00
2014-03-25 05:57:24 +00:00
def settingsNMJv2 ( self , host = None , dbloc = None , instance = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
host = config . clean_host ( host )
result = notifiers . nmjv2_notifier . notify_settings ( urllib . unquote_plus ( host ) , dbloc , instance )
if result :
2014-03-25 05:57:24 +00:00
return ' { " message " : " NMJ Database found at: %(host)s " , " database " : " %(database)s " } ' % { " host " : host ,
" database " : sickbeard . NMJv2_DATABASE }
2014-03-10 05:18:05 +00:00
else :
2014-03-25 05:57:24 +00:00
return ' { " message " : " Unable to find NMJ Database at location: %(dbloc)s . Is the right location selected and PCH running? " , " database " : " " } ' % {
2014-03-27 02:01:53 +00:00
" dbloc " : dbloc }
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testTrakt ( self , api = None , username = None , password = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . trakt_notifier . test_notify ( api , username , password )
if result :
return " Test notice sent successfully to Trakt "
else :
return " Test notice failed to Trakt "
2014-06-11 08:34:28 +00:00
def loadShowNotifyLists ( self , * args , * * kwargs ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
rows = myDB . select ( " SELECT show_id, show_name, notify_list FROM tv_shows ORDER BY show_name ASC " )
2014-06-07 21:32:38 +00:00
2014-03-10 05:18:05 +00:00
data = { }
size = 0
for r in rows :
data [ r [ ' show_id ' ] ] = { ' id ' : r [ ' show_id ' ] , ' name ' : r [ ' show_name ' ] , ' list ' : r [ ' notify_list ' ] }
size + = 1
data [ ' _size ' ] = size
return json . dumps ( data )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testEmail ( self , host = None , port = None , smtp_from = None , use_tls = None , user = None , pwd = None , to = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
host = config . clean_host ( host )
if notifiers . email_notifier . test_notify ( host , port , smtp_from , use_tls , user , pwd , to ) :
return ' Test email sent successfully! Check inbox. '
else :
return ' ERROR: %s ' % notifiers . email_notifier . last_err
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testNMA ( self , nma_api = None , nma_priority = 0 ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . nma_notifier . test_notify ( nma_api , nma_priority )
if result :
return " Test NMA notice sent successfully "
else :
return " Test NMA notice failed "
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testPushalot ( self , authorizationToken = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . pushalot_notifier . test_notify ( authorizationToken )
if result :
return " Pushalot notification succeeded. Check your Pushalot clients to make sure it worked "
else :
return " Error sending Pushalot notification "
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testPushbullet ( self , api = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . pushbullet_notifier . test_notify ( api )
if result :
return " Pushbullet notification succeeded. Check your device to make sure it worked "
else :
return " Error sending Pushbullet notification "
def getPushbulletDevices ( self , api = None ) :
2014-06-30 02:39:29 +00:00
self . set_header ( ' Cache-Control ' , ' max-age=0,no-cache,no-store ' )
2014-03-10 05:18:05 +00:00
result = notifiers . pushbullet_notifier . get_devices ( api )
if result :
return result
else :
return " Error sending Pushbullet notification "
def shutdown ( self , pid = None ) :
if str ( pid ) != str ( sickbeard . PID ) :
2014-06-30 01:54:41 +00:00
redirect ( " /home/ " )
2014-03-10 05:18:05 +00:00
2014-07-08 22:17:34 +00:00
sickbeard . events . put ( sickbeard . events . SystemEvent . SHUTDOWN )
2014-03-10 05:18:05 +00:00
title = " Shutting down "
2014-05-23 12:37:22 +00:00
message = " SickRage is shutting down... "
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( title , message )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def restart ( self , pid = None ) :
if str ( pid ) != str ( sickbeard . PID ) :
2014-06-30 01:54:41 +00:00
redirect ( " /home/ " )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " restart.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
2014-06-23 15:18:01 +00:00
# restart
2014-07-08 22:17:34 +00:00
sickbeard . events . put ( sickbeard . events . SystemEvent . RESTART )
2014-03-10 05:18:05 +00:00
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-07-29 00:11:16 +00:00
def update ( self , pid = None ) :
2014-03-10 05:18:05 +00:00
if str ( pid ) != str ( sickbeard . PID ) :
2014-06-30 01:54:41 +00:00
redirect ( " /home/ " )
2014-03-10 05:18:05 +00:00
2014-07-29 00:11:16 +00:00
updated = sickbeard . versionCheckScheduler . action . update ( ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
if updated :
# do a hard restart
2014-07-08 22:17:34 +00:00
sickbeard . events . put ( sickbeard . events . SystemEvent . RESTART )
2014-06-18 09:13:22 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " restart_bare.tmpl " )
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
else :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Update Failed " ,
2014-07-01 08:49:12 +00:00
" Update wasn ' t successful, not restarting. Check your log for more information. " )
2014-03-10 05:18:05 +00:00
2014-07-27 23:22:57 +00:00
def branchCheckout ( self , branch ) :
2014-07-29 00:11:16 +00:00
sickbeard . BRANCH = branch
ui . notifications . message ( ' Checking out branch: ' , branch )
return self . update ( sickbeard . PID )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def displayShow ( self , show = None ) :
2014-03-25 05:57:24 +00:00
if show is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Invalid show ID " )
2014-03-10 05:18:05 +00:00
else :
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Show not in show list " )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
seasonResults = myDB . select (
" SELECT DISTINCT season FROM tv_episodes WHERE showid = ? ORDER BY season desc " ,
[ showObj . indexerid ]
)
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
sqlResults = myDB . select (
" SELECT * FROM tv_episodes WHERE showid = ? ORDER BY season DESC, episode DESC " ,
[ showObj . indexerid ]
)
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " displayShow.tmpl " )
2014-03-25 05:57:24 +00:00
t . submenu = [ { ' title ' : ' Edit ' , ' path ' : ' home/editShow?show= %d ' % showObj . indexerid } ]
2014-03-10 05:18:05 +00:00
try :
t . showLoc = ( showObj . location , True )
except sickbeard . exceptions . ShowDirNotFoundException :
t . showLoc = ( showObj . _location , False )
show_message = ' '
2014-03-25 05:57:24 +00:00
if sickbeard . showQueueScheduler . action . isBeingAdded ( showObj ) : # @UndefinedVariable
2014-03-10 05:18:05 +00:00
show_message = ' This show is in the process of being downloaded - the info below is incomplete. '
2014-03-25 05:57:24 +00:00
elif sickbeard . showQueueScheduler . action . isBeingUpdated ( showObj ) : # @UndefinedVariable
2014-09-15 01:24:08 +00:00
show_message = ' The information on this page is in the process of being updated. '
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
elif sickbeard . showQueueScheduler . action . isBeingRefreshed ( showObj ) : # @UndefinedVariable
2014-03-10 05:18:05 +00:00
show_message = ' The episodes below are currently being refreshed from disk '
2014-03-25 05:57:24 +00:00
elif sickbeard . showQueueScheduler . action . isBeingSubtitled ( showObj ) : # @UndefinedVariable
2014-03-10 05:18:05 +00:00
show_message = ' Currently downloading subtitles for this show '
2014-03-25 05:57:24 +00:00
elif sickbeard . showQueueScheduler . action . isInRefreshQueue ( showObj ) : # @UndefinedVariable
2014-03-10 05:18:05 +00:00
show_message = ' This show is queued to be refreshed. '
2014-03-25 05:57:24 +00:00
elif sickbeard . showQueueScheduler . action . isInUpdateQueue ( showObj ) : # @UndefinedVariable
2014-03-10 05:18:05 +00:00
show_message = ' This show is queued and awaiting an update. '
2014-03-25 05:57:24 +00:00
elif sickbeard . showQueueScheduler . action . isInSubtitleQueue ( showObj ) : # @UndefinedVariable
2014-03-10 05:18:05 +00:00
show_message = ' This show is queued and awaiting subtitles download. '
2014-03-25 05:57:24 +00:00
if not sickbeard . showQueueScheduler . action . isBeingAdded ( showObj ) : # @UndefinedVariable
if not sickbeard . showQueueScheduler . action . isBeingUpdated ( showObj ) : # @UndefinedVariable
2014-08-29 10:29:56 +00:00
t . submenu . append (
{ ' title ' : ' Remove ' , ' path ' : ' home/deleteShow?show= %d ' % showObj . indexerid , ' confirm ' : True } )
2014-03-25 05:57:24 +00:00
t . submenu . append ( { ' title ' : ' Re-scan files ' , ' path ' : ' home/refreshShow?show= %d ' % showObj . indexerid } )
t . submenu . append (
{ ' title ' : ' Force Full Update ' , ' path ' : ' home/updateShow?show= %d &force=1 ' % showObj . indexerid } )
t . submenu . append ( { ' title ' : ' Update show in XBMC ' ,
' path ' : ' home/updateXBMC?showName= %s ' % urllib . quote_plus (
showObj . name . encode ( ' utf-8 ' ) ) , ' requires ' : haveXBMC } )
t . submenu . append ( { ' title ' : ' Preview Rename ' , ' path ' : ' home/testRename?show= %d ' % showObj . indexerid } )
if sickbeard . USE_SUBTITLES and not sickbeard . showQueueScheduler . action . isBeingSubtitled (
showObj ) and showObj . subtitles :
t . submenu . append (
{ ' title ' : ' Download Subtitles ' , ' path ' : ' home/subtitleShow?show= %d ' % showObj . indexerid } )
2014-03-10 05:18:05 +00:00
t . show = showObj
t . sqlResults = sqlResults
t . seasonResults = seasonResults
t . show_message = show_message
epCounts = { }
epCats = { }
epCounts [ Overview . SKIPPED ] = 0
epCounts [ Overview . WANTED ] = 0
epCounts [ Overview . QUAL ] = 0
epCounts [ Overview . GOOD ] = 0
epCounts [ Overview . UNAIRED ] = 0
epCounts [ Overview . SNATCHED ] = 0
for curResult in sqlResults :
curEpCat = showObj . getOverview ( int ( curResult [ " status " ] ) )
2014-06-22 05:03:59 +00:00
if curEpCat :
epCats [ str ( curResult [ " season " ] ) + " x " + str ( curResult [ " episode " ] ) ] = curEpCat
epCounts [ curEpCat ] + = 1
2014-03-10 05:18:05 +00:00
def titler ( x ) :
2014-03-25 05:57:24 +00:00
if not x or sickbeard . SORT_ARTICLE :
2014-03-10 05:18:05 +00:00
return x
if x . lower ( ) . startswith ( ' a ' ) :
x = x [ 2 : ]
if x . lower ( ) . startswith ( ' an ' ) :
x = x [ 3 : ]
elif x . lower ( ) . startswith ( ' the ' ) :
x = x [ 4 : ]
return x
2014-03-25 05:57:24 +00:00
2014-05-26 06:29:22 +00:00
if sickbeard . ANIME_SPLIT_HOME :
shows = [ ]
anime = [ ]
for show in sickbeard . showList :
if show . is_anime :
anime . append ( show )
else :
shows . append ( show )
2014-06-07 12:36:50 +00:00
t . sortedShowLists = [ [ " Shows " , sorted ( shows , lambda x , y : cmp ( titler ( x . name ) , titler ( y . name ) ) ) ] ,
[ " Anime " , sorted ( anime , lambda x , y : cmp ( titler ( x . name ) , titler ( y . name ) ) ) ] ]
2014-05-26 06:29:22 +00:00
else :
2014-06-07 12:36:50 +00:00
t . sortedShowLists = [
[ " Shows " , sorted ( sickbeard . showList , lambda x , y : cmp ( titler ( x . name ) , titler ( y . name ) ) ) ] ]
2014-03-10 05:18:05 +00:00
2014-07-15 02:00:53 +00:00
t . bwl = None
if showObj . is_anime :
t . bwl = BlackAndWhiteList ( showObj . indexerid )
2014-05-27 07:44:23 +00:00
2014-03-10 05:18:05 +00:00
t . epCounts = epCounts
t . epCats = epCats
2014-03-25 05:57:24 +00:00
2014-06-20 23:49:57 +00:00
showObj . exceptions = scene_exceptions . get_scene_exceptions ( showObj . indexerid )
2014-05-03 09:58:04 +00:00
indexerid = int ( showObj . indexerid )
indexer = int ( showObj . indexer )
2014-06-20 23:49:57 +00:00
t . all_scene_exceptions = showObj . exceptions
2014-05-03 09:58:04 +00:00
t . scene_numbering = get_scene_numbering_for_show ( indexerid , indexer )
t . xem_numbering = get_xem_numbering_for_show ( indexerid , indexer )
2014-05-30 05:48:02 +00:00
t . scene_absolute_numbering = get_scene_absolute_numbering_for_show ( indexerid , indexer )
t . xem_absolute_numbering = get_xem_absolute_numbering_for_show ( indexerid , indexer )
2014-03-10 05:18:05 +00:00
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def plotDetails ( self , show , season , episode ) :
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
2014-06-23 01:52:46 +00:00
result = myDB . selectOne (
2014-06-21 22:46:59 +00:00
" SELECT description FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ? " ,
2014-06-23 01:52:46 +00:00
( int ( show ) , int ( season ) , int ( episode ) ) )
2014-03-10 05:18:05 +00:00
return result [ ' description ' ] if result else ' Episode not found. '
2014-06-11 08:34:28 +00:00
2014-05-26 06:29:22 +00:00
def sceneExceptions ( self , show ) :
exceptionsList = sickbeard . scene_exceptions . get_all_scene_exceptions ( show )
if not exceptionsList :
return " No scene exceptions "
out = [ ]
for season , names in iter ( sorted ( exceptionsList . iteritems ( ) ) ) :
if season == - 1 :
season = " * "
out . append ( " S " + str ( season ) + " : " + " , " . join ( names ) )
return " <br/> " . join ( out )
2014-06-11 08:34:28 +00:00
2014-03-25 05:57:24 +00:00
def editShow ( self , show = None , location = None , anyQualities = [ ] , bestQualities = [ ] , exceptions_list = [ ] ,
2014-04-28 09:15:29 +00:00
flatten_folders = None , paused = None , directCall = False , air_by_date = None , sports = None , dvdorder = None ,
2014-05-20 20:51:54 +00:00
indexerLang = None , subtitles = None , archive_firstmatch = None , rls_ignore_words = None ,
2014-05-30 05:48:02 +00:00
rls_require_words = None , anime = None , blackWords = None , whiteWords = None , blacklist = None , whitelist = None ,
scene = None ) :
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if show is None :
2014-03-10 05:18:05 +00:00
errString = " Invalid show ID: " + str ( show )
if directCall :
return [ errString ]
else :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errString )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-07-28 01:46:15 +00:00
2014-07-27 14:14:41 +00:00
if not showObj :
2014-03-10 05:18:05 +00:00
errString = " Unable to find the specified show: " + str ( show )
if directCall :
return [ errString ]
else :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errString )
2014-03-10 05:18:05 +00:00
2014-07-27 14:14:41 +00:00
showObj . exceptions = scene_exceptions . get_scene_exceptions ( showObj . indexerid )
2014-03-10 05:18:05 +00:00
if not location and not anyQualities and not bestQualities and not flatten_folders :
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " editShow.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = HomeMenu ( )
2014-05-26 06:29:22 +00:00
2014-07-18 05:57:35 +00:00
if showObj . is_anime :
bwl = BlackAndWhiteList ( showObj . indexerid )
2014-07-15 02:00:53 +00:00
2014-07-18 05:57:35 +00:00
t . whiteWords = " "
if " global " in bwl . whiteDict :
t . whiteWords = " , " . join ( bwl . whiteDict [ " global " ] )
2014-07-15 02:00:53 +00:00
2014-07-18 05:57:35 +00:00
t . blackWords = " "
if " global " in bwl . blackDict :
t . blackWords = " , " . join ( bwl . blackDict [ " global " ] )
2014-05-26 06:29:22 +00:00
2014-07-18 05:57:35 +00:00
t . whitelist = [ ]
if bwl . whiteDict . has_key ( " release_group " ) :
t . whitelist = bwl . whiteDict [ " release_group " ]
2014-07-18 00:43:36 +00:00
2014-07-18 05:57:35 +00:00
t . blacklist = [ ]
if bwl . blackDict . has_key ( " release_group " ) :
t . blacklist = bwl . blackDict [ " release_group " ]
2014-07-18 00:43:36 +00:00
2014-07-18 05:57:35 +00:00
t . groups = [ ]
if helpers . set_up_anidb_connection ( ) :
anime = adba . Anime ( sickbeard . ADBA_CONNECTION , name = showObj . name )
t . groups = anime . get_groups ( )
2014-07-18 00:43:36 +00:00
2014-07-18 05:57:35 +00:00
with showObj . lock :
t . show = showObj
2014-07-28 01:46:15 +00:00
t . scene_exceptions = get_scene_exceptions ( showObj . indexerid )
2014-03-10 05:18:05 +00:00
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-03-10 05:18:05 +00:00
flatten_folders = config . checkbox_to_value ( flatten_folders )
dvdorder = config . checkbox_to_value ( dvdorder )
2014-03-18 13:50:13 +00:00
archive_firstmatch = config . checkbox_to_value ( archive_firstmatch )
2014-03-10 05:18:05 +00:00
paused = config . checkbox_to_value ( paused )
air_by_date = config . checkbox_to_value ( air_by_date )
2014-05-30 05:48:02 +00:00
scene = config . checkbox_to_value ( scene )
2014-04-28 09:15:29 +00:00
sports = config . checkbox_to_value ( sports )
2014-05-26 06:29:22 +00:00
anime = config . checkbox_to_value ( anime )
2014-03-10 05:18:05 +00:00
subtitles = config . checkbox_to_value ( subtitles )
2014-04-24 03:22:21 +00:00
indexer_lang = indexerLang
2014-03-10 05:18:05 +00:00
# if we changed the language then kick off an update
if indexer_lang == showObj . lang :
do_update = False
else :
do_update = True
2014-07-28 01:46:15 +00:00
if scene == showObj . scene and anime == showObj . anime :
2014-05-30 06:22:01 +00:00
do_update_scene_numbering = False
else :
do_update_scene_numbering = True
2014-03-10 05:18:05 +00:00
if type ( anyQualities ) != list :
anyQualities = [ anyQualities ]
if type ( bestQualities ) != list :
bestQualities = [ bestQualities ]
if type ( exceptions_list ) != list :
exceptions_list = [ exceptions_list ]
2014-07-28 01:46:15 +00:00
# If directCall from mass_edit_update no scene exceptions handling or blackandwhite list handling
2014-03-10 05:18:05 +00:00
if directCall :
do_update_exceptions = False
else :
2014-06-04 07:11:56 +00:00
if set ( exceptions_list ) == set ( showObj . exceptions ) :
2014-03-10 05:18:05 +00:00
do_update_exceptions = False
else :
do_update_exceptions = True
2014-07-15 02:00:53 +00:00
if showObj . is_anime :
bwl = BlackAndWhiteList ( showObj . indexerid )
if whitelist :
whitelist = whitelist . split ( " , " )
shortWhiteList = [ ]
if helpers . set_up_anidb_connection ( ) :
for groupName in whitelist :
group = sickbeard . ADBA_CONNECTION . group ( gname = groupName )
for line in group . datalines :
if line [ " shortname " ] :
shortWhiteList . append ( line [ " shortname " ] )
else :
if not groupName in shortWhiteList :
shortWhiteList . append ( groupName )
else :
shortWhiteList = whitelist
bwl . set_white_keywords_for ( " release_group " , shortWhiteList )
2014-07-08 03:27:24 +00:00
else :
2014-07-15 02:00:53 +00:00
bwl . set_white_keywords_for ( " release_group " , [ ] )
if blacklist :
blacklist = blacklist . split ( " , " )
shortBlacklist = [ ]
if helpers . set_up_anidb_connection ( ) :
for groupName in blacklist :
group = sickbeard . ADBA_CONNECTION . group ( gname = groupName )
for line in group . datalines :
if line [ " shortname " ] :
shortBlacklist . append ( line [ " shortname " ] )
else :
if not groupName in shortBlacklist :
shortBlacklist . append ( groupName )
else :
shortBlacklist = blacklist
bwl . set_black_keywords_for ( " release_group " , shortBlacklist )
2014-07-08 03:27:24 +00:00
else :
2014-07-15 02:00:53 +00:00
bwl . set_black_keywords_for ( " release_group " , [ ] )
2014-05-27 07:44:23 +00:00
2014-07-15 02:00:53 +00:00
if whiteWords :
whiteWords = [ x . strip ( ) for x in whiteWords . split ( " , " ) ]
bwl . set_white_keywords_for ( " global " , whiteWords )
else :
bwl . set_white_keywords_for ( " global " , [ ] )
2014-05-27 07:44:23 +00:00
2014-07-15 02:00:53 +00:00
if blackWords :
blackWords = [ x . strip ( ) for x in blackWords . split ( " , " ) ]
bwl . set_black_keywords_for ( " global " , blackWords )
else :
bwl . set_black_keywords_for ( " global " , [ ] )
2014-05-27 07:44:23 +00:00
2014-03-10 05:18:05 +00:00
errors = [ ]
with showObj . lock :
newQuality = Quality . combineQualities ( map ( int , anyQualities ) , map ( int , bestQualities ) )
showObj . quality = newQuality
2014-10-16 20:45:07 +00:00
showObj . archive_firstmatch = archive_firstmatch
2014-03-10 05:18:05 +00:00
# reversed for now
if bool ( showObj . flatten_folders ) != bool ( flatten_folders ) :
showObj . flatten_folders = flatten_folders
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . refreshShow ( showObj ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
except exceptions . CantRefreshException , e :
errors . append ( " Unable to refresh this show: " + ex ( e ) )
2014-07-28 01:46:15 +00:00
showObj . paused = paused
2014-07-31 02:32:12 +00:00
showObj . scene = scene
showObj . anime = anime
showObj . sports = sports
showObj . subtitles = subtitles
showObj . air_by_date = air_by_date
2014-06-04 07:21:21 +00:00
2014-07-28 01:46:15 +00:00
if not directCall :
2014-06-04 07:21:21 +00:00
showObj . lang = indexer_lang
showObj . dvdorder = dvdorder
2014-05-23 05:02:49 +00:00
showObj . rls_ignore_words = rls_ignore_words . strip ( )
showObj . rls_require_words = rls_require_words . strip ( )
2014-04-24 05:18:16 +00:00
2014-03-10 05:18:05 +00:00
# if we change location clear the db of episodes, change it, write to db, and rescan
if os . path . normpath ( showObj . _location ) != os . path . normpath ( location ) :
logger . log ( os . path . normpath ( showObj . _location ) + " != " + os . path . normpath ( location ) , logger . DEBUG )
2014-07-08 03:27:24 +00:00
if not ek . ek ( os . path . isdir , location ) and not sickbeard . CREATE_MISSING_SHOW_DIRS :
2014-03-10 05:18:05 +00:00
errors . append ( " New location <tt> %s </tt> does not exist " % location )
# don't bother if we're going to update anyway
elif not do_update :
# change it
try :
2014-07-28 01:46:15 +00:00
showObj . location = location
2014-03-10 05:18:05 +00:00
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . refreshShow ( showObj ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
except exceptions . CantRefreshException , e :
errors . append ( " Unable to refresh this show: " + ex ( e ) )
2014-03-25 05:57:24 +00:00
# grab updated info from TVDB
2014-06-07 12:36:50 +00:00
# showObj.loadEpisodesFromIndexer()
2014-03-25 05:57:24 +00:00
# rescan the episodes in the new folder
2014-03-10 05:18:05 +00:00
except exceptions . NoNFOException :
2014-03-25 05:57:24 +00:00
errors . append (
2014-05-23 12:37:22 +00:00
" The folder at <tt> %s </tt> doesn ' t contain a tvshow.nfo - copy your files to that folder before you change the directory in SickRage. " % location )
2014-03-10 05:18:05 +00:00
# save it to the DB
showObj . saveToDB ( )
# force the update
if do_update :
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . updateShow ( showObj , True ) # @UndefinedVariable
2014-05-20 18:01:51 +00:00
time . sleep ( cpu_presets [ sickbeard . CPU_PRESET ] )
2014-03-10 05:18:05 +00:00
except exceptions . CantUpdateException , e :
errors . append ( " Unable to force an update on the show. " )
if do_update_exceptions :
try :
2014-07-27 14:14:41 +00:00
scene_exceptions . update_scene_exceptions ( showObj . indexerid , exceptions_list ) # @UndefinedVdexerid)
2014-05-20 18:01:51 +00:00
time . sleep ( cpu_presets [ sickbeard . CPU_PRESET ] )
2014-03-10 05:18:05 +00:00
except exceptions . CantUpdateException , e :
errors . append ( " Unable to force an update on scene exceptions of the show. " )
2014-07-28 01:46:15 +00:00
if do_update_scene_numbering :
2014-05-30 06:22:01 +00:00
try :
2014-06-01 06:54:57 +00:00
sickbeard . scene_numbering . xem_refresh ( showObj . indexerid , showObj . indexer ) # @UndefinedVariable
2014-05-30 06:22:01 +00:00
time . sleep ( cpu_presets [ sickbeard . CPU_PRESET ] )
except exceptions . CantUpdateException , e :
errors . append ( " Unable to force an update on scene numbering of the show. " )
2014-03-10 05:18:05 +00:00
if directCall :
return errors
if len ( errors ) > 0 :
ui . notifications . error ( ' %d error %s while saving changes: ' % ( len ( errors ) , " " if len ( errors ) == 1 else " s " ) ,
2014-03-25 05:57:24 +00:00
' <ul> ' + ' \n ' . join ( [ ' <li> %s </li> ' % error for error in errors ] ) + " </ul> " )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + show )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
2014-08-29 10:29:56 +00:00
def deleteShow ( self , show = None , full = 0 ) :
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if show is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Invalid show ID " )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Unable to find the specified show " )
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if sickbeard . showQueueScheduler . action . isBeingAdded (
showObj ) or sickbeard . showQueueScheduler . action . isBeingUpdated ( showObj ) : # @UndefinedVariable
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Shows can ' t be deleted while they ' re being added or updated. " )
2014-03-10 05:18:05 +00:00
2014-06-29 05:54:29 +00:00
if sickbeard . USE_TRAKT and sickbeard . TRAKT_SYNC :
2014-06-29 03:28:00 +00:00
# remove show from trakt.tv library
sickbeard . traktCheckerScheduler . action . removeShowFromTraktLibrary ( showObj )
2014-08-29 10:29:56 +00:00
showObj . deleteShow ( bool ( full ) )
2014-03-10 05:18:05 +00:00
ui . notifications . message ( ' <b> %s </b> has been deleted ' % showObj . name )
2014-06-30 01:54:41 +00:00
redirect ( " /home/ " )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def refreshShow ( self , show = None ) :
2014-03-25 05:57:24 +00:00
if show is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Invalid show ID " )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Unable to find the specified show " )
2014-03-10 05:18:05 +00:00
# force the update from the DB
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . refreshShow ( showObj ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
except exceptions . CantRefreshException , e :
ui . notifications . error ( " Unable to refresh this show. " ,
2014-03-25 05:57:24 +00:00
ex ( e ) )
2014-03-10 05:18:05 +00:00
2014-05-20 01:04:23 +00:00
time . sleep ( cpu_presets [ sickbeard . CPU_PRESET ] )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + str ( showObj . indexerid ) )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def updateShow ( self , show = None , force = 0 ) :
2014-03-25 05:57:24 +00:00
if show is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Invalid show ID " )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Unable to find the specified show " )
2014-03-10 05:18:05 +00:00
# force the update
try :
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . updateShow ( showObj , bool ( force ) ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
except exceptions . CantUpdateException , e :
ui . notifications . error ( " Unable to update this show. " ,
2014-03-25 05:57:24 +00:00
ex ( e ) )
2014-03-10 05:18:05 +00:00
# just give it some time
2014-05-20 01:04:23 +00:00
time . sleep ( cpu_presets [ sickbeard . CPU_PRESET ] )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + str ( showObj . indexerid ) )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def subtitleShow ( self , show = None , force = 0 ) :
2014-03-25 05:57:24 +00:00
if show is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Invalid show ID " )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Unable to find the specified show " )
2014-03-10 05:18:05 +00:00
# search and download subtitles
2014-03-25 05:57:24 +00:00
sickbeard . showQueueScheduler . action . downloadSubtitles ( showObj , bool ( force ) ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
2014-05-20 01:04:23 +00:00
time . sleep ( cpu_presets [ sickbeard . CPU_PRESET ] )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + str ( showObj . indexerid ) )
2014-03-10 05:18:05 +00:00
def updateXBMC ( self , showName = None ) :
# only send update to first host in the list -- workaround for xbmc sql backend users
if sickbeard . XBMC_UPDATE_ONLYFIRST :
# only send update to first host in the list -- workaround for xbmc sql backend users
host = sickbeard . XBMC_HOST . split ( " , " ) [ 0 ] . strip ( )
else :
host = sickbeard . XBMC_HOST
if notifiers . xbmc_notifier . update_library ( showName = showName ) :
ui . notifications . message ( " Library update command sent to XBMC host(s): " + host )
else :
ui . notifications . error ( " Unable to contact one or more XBMC host(s): " + host )
2014-06-30 01:54:41 +00:00
redirect ( ' /home/ ' )
2014-03-10 05:18:05 +00:00
2014-06-11 08:34:28 +00:00
def updatePLEX ( self , * args , * * kwargs ) :
2014-03-10 05:18:05 +00:00
if notifiers . plex_notifier . update_library ( ) :
2014-03-25 05:57:24 +00:00
ui . notifications . message (
" Library update command sent to Plex Media Server host: " + sickbeard . PLEX_SERVER_HOST )
2014-03-10 05:18:05 +00:00
else :
ui . notifications . error ( " Unable to contact Plex Media Server host: " + sickbeard . PLEX_SERVER_HOST )
2014-06-30 01:54:41 +00:00
redirect ( ' /home/ ' )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def setStatus ( self , show = None , eps = None , status = None , direct = False ) :
2014-03-25 05:57:24 +00:00
if show is None or eps is None or status is None :
2014-03-10 05:18:05 +00:00
errMsg = " You must specify a show and at least one episode "
if direct :
ui . notifications . error ( ' Error ' , errMsg )
return json . dumps ( { ' result ' : ' error ' } )
else :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errMsg )
2014-03-10 05:18:05 +00:00
if not statusStrings . has_key ( int ( status ) ) :
errMsg = " Invalid status "
if direct :
ui . notifications . error ( ' Error ' , errMsg )
return json . dumps ( { ' result ' : ' error ' } )
else :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errMsg )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-03-10 05:18:05 +00:00
errMsg = " Error " , " Show not in show list "
if direct :
ui . notifications . error ( ' Error ' , errMsg )
return json . dumps ( { ' result ' : ' error ' } )
else :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errMsg )
2014-03-10 05:18:05 +00:00
2014-09-07 04:36:23 +00:00
segments = { }
2014-03-25 05:57:24 +00:00
if eps is not None :
2014-03-10 05:18:05 +00:00
2014-03-20 10:24:58 +00:00
sql_l = [ ]
2014-03-10 05:18:05 +00:00
for curEp in eps . split ( ' | ' ) :
logger . log ( u " Attempting to set status on episode " + curEp + " to " + status , logger . DEBUG )
epInfo = curEp . split ( ' x ' )
epObj = showObj . getEpisode ( int ( epInfo [ 0 ] ) , int ( epInfo [ 1 ] ) )
2014-03-25 05:57:24 +00:00
if epObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Episode couldn ' t be retrieved " )
2014-03-10 05:18:05 +00:00
2014-05-16 03:39:46 +00:00
if int ( status ) in [ WANTED , FAILED ] :
2014-03-19 14:59:34 +00:00
# figure out what episodes are wanted so we can backlog them
2014-09-07 04:36:23 +00:00
if epObj . season in segments :
segments [ epObj . season ] . append ( epObj )
2014-03-10 05:18:05 +00:00
else :
2014-09-07 04:36:23 +00:00
segments [ epObj . season ] = [ epObj ]
2014-03-10 05:18:05 +00:00
with epObj . lock :
# don't let them mess up UNAIRED episodes
if epObj . status == UNAIRED :
logger . log ( u " Refusing to change status of " + curEp + " because it is UNAIRED " , logger . ERROR )
continue
2014-03-25 05:57:24 +00:00
if int (
status ) in Quality . DOWNLOADED and epObj . status not in Quality . SNATCHED + Quality . SNATCHED_PROPER + Quality . DOWNLOADED + [
IGNORED ] and not ek . ek ( os . path . isfile , epObj . location ) :
logger . log (
u " Refusing to change status of " + curEp + " to DOWNLOADED because it ' s not SNATCHED/DOWNLOADED " ,
logger . ERROR )
2014-03-10 05:18:05 +00:00
continue
2014-03-25 05:57:24 +00:00
if int (
status ) == FAILED and epObj . status not in Quality . SNATCHED + Quality . SNATCHED_PROPER + Quality . DOWNLOADED :
logger . log (
u " Refusing to change status of " + curEp + " to FAILED because it ' s not SNATCHED/DOWNLOADED " ,
logger . ERROR )
2014-03-10 05:18:05 +00:00
continue
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
epObj . status = int ( status )
2014-04-27 13:46:08 +00:00
# mass add to database
2014-05-30 10:01:49 +00:00
sql_l . append ( epObj . get_sql ( ) )
2014-03-20 10:24:58 +00:00
2014-07-15 02:00:53 +00:00
if len ( sql_l ) > 0 :
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
myDB . mass_action ( sql_l )
2014-06-30 15:57:32 +00:00
2014-03-25 05:57:24 +00:00
if int ( status ) == WANTED :
2014-04-25 07:47:17 +00:00
msg = " Backlog was automatically started for the following seasons of <b> " + showObj . name + " </b>:<br /> "
2014-09-07 04:36:23 +00:00
for season , segment in segments . items ( ) :
cur_backlog_queue_item = search_queue . BacklogQueueItem ( showObj , segment )
sickbeard . searchQueueScheduler . action . add_item ( cur_backlog_queue_item ) # @UndefinedVariable
2014-05-16 04:55:56 +00:00
msg + = " <li>Season " + str ( season ) + " </li> "
2014-03-25 05:57:24 +00:00
logger . log ( u " Sending backlog for " + showObj . name + " season " + str (
2014-05-16 04:55:56 +00:00
season ) + " because some eps were set to wanted " )
2014-03-10 05:18:05 +00:00
2014-09-07 04:36:23 +00:00
msg + = " </ul> "
2014-05-16 04:55:56 +00:00
2014-09-07 04:36:23 +00:00
if segments :
2014-03-10 05:18:05 +00:00
ui . notifications . message ( " Backlog started " , msg )
if int ( status ) == FAILED :
msg = " Retrying Search was automatically started for the following season of <b> " + showObj . name + " </b>:<br /> "
2014-09-07 04:36:23 +00:00
for season , segment in segments . items ( ) :
2014-09-17 10:24:54 +00:00
cur_failed_queue_item = search_queue . FailedQueueItem ( showObj , [ segment ] )
2014-09-07 04:36:23 +00:00
sickbeard . searchQueueScheduler . action . add_item ( cur_failed_queue_item ) # @UndefinedVariable
2014-05-16 04:55:56 +00:00
msg + = " <li>Season " + str ( season ) + " </li> "
2014-03-25 05:57:24 +00:00
logger . log ( u " Retrying Search for " + showObj . name + " season " + str (
2014-05-16 04:55:56 +00:00
season ) + " because some eps were set to failed " )
2014-03-10 05:18:05 +00:00
2014-09-07 04:36:23 +00:00
msg + = " </ul> "
2014-05-16 04:55:56 +00:00
2014-09-07 04:36:23 +00:00
if segments :
2014-03-10 05:18:05 +00:00
ui . notifications . message ( " Retry Search started " , msg )
2014-03-25 05:57:24 +00:00
2014-03-10 05:18:05 +00:00
if direct :
return json . dumps ( { ' result ' : ' success ' } )
else :
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + show )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def testRename ( self , show = None ) :
2014-03-25 05:57:24 +00:00
if show is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " You must specify a show " )
2014-03-10 05:18:05 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if showObj is None :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Show not in show list " )
2014-03-10 05:18:05 +00:00
try :
2014-06-07 12:36:50 +00:00
show_loc = showObj . location # @UnusedVariable
2014-03-10 05:18:05 +00:00
except exceptions . ShowDirNotFoundException :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Can ' t rename episodes when the show dir is missing. " )
2014-03-10 05:18:05 +00:00
ep_obj_rename_list = [ ]
ep_obj_list = showObj . getAllEpisodes ( has_location = True )
for cur_ep_obj in ep_obj_list :
# Only want to rename if we have a location
if cur_ep_obj . location :
if cur_ep_obj . relatedEps :
# do we have one of multi-episodes in the rename list already
have_already = False
for cur_related_ep in cur_ep_obj . relatedEps + [ cur_ep_obj ] :
if cur_related_ep in ep_obj_rename_list :
have_already = True
break
if not have_already :
ep_obj_rename_list . append ( cur_ep_obj )
else :
ep_obj_rename_list . append ( cur_ep_obj )
if ep_obj_rename_list :
# present season DESC episode DESC on screen
ep_obj_rename_list . reverse ( )
2014-06-30 01:54:41 +00:00
t = PageTemplate ( headers = self . request . headers , file = " testRename.tmpl " )
2014-03-10 05:18:05 +00:00
t . submenu = [ { ' title ' : ' Edit ' , ' path ' : ' home/editShow?show= %d ' % showObj . indexerid } ]
t . ep_obj_list = ep_obj_rename_list
t . show = showObj
2014-06-15 11:08:41 +00:00
return _munge ( t )
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def doRename ( self , show = None , eps = None ) :
2014-03-25 05:57:24 +00:00
if show is None or eps is None :
2014-03-10 05:18:05 +00:00
errMsg = " You must specify a show and at least one episode "
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errMsg )
2014-03-10 05:18:05 +00:00
show_obj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
2014-03-25 05:57:24 +00:00
if show_obj is None :
2014-03-10 05:18:05 +00:00
errMsg = " Error " , " Show not in show list "
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , errMsg )
2014-03-10 05:18:05 +00:00
try :
2014-06-07 12:36:50 +00:00
show_loc = show_obj . location # @UnusedVariable
2014-03-10 05:18:05 +00:00
except exceptions . ShowDirNotFoundException :
2014-06-30 01:54:41 +00:00
return self . _genericMessage ( " Error " , " Can ' t rename episodes when the show dir is missing. " )
2014-03-10 05:18:05 +00:00
2014-03-25 05:57:24 +00:00
if eps is None :
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + show )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
myDB = db . DBConnection ( )
for curEp in eps . split ( ' | ' ) :
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
epInfo = curEp . split ( ' x ' )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
# this is probably the worst possible way to deal with double eps but I've kinda painted myself into a corner here with this stupid database
ep_result = myDB . select (
" SELECT * FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ? AND 5=5 " ,
[ show , epInfo [ 0 ] , epInfo [ 1 ] ] )
if not ep_result :
logger . log ( u " Unable to find an episode for " + curEp + " , skipping " , logger . WARNING )
continue
related_eps_result = myDB . select ( " SELECT * FROM tv_episodes WHERE location = ? AND episode != ? " ,
[ ep_result [ 0 ] [ " location " ] , epInfo [ 1 ] ] )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
root_ep_obj = show_obj . getEpisode ( int ( epInfo [ 0 ] ) , int ( epInfo [ 1 ] ) )
root_ep_obj . relatedEps = [ ]
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
for cur_related_ep in related_eps_result :
related_ep_obj = show_obj . getEpisode ( int ( cur_related_ep [ " season " ] ) , int ( cur_related_ep [ " episode " ] ) )
if related_ep_obj not in root_ep_obj . relatedEps :
root_ep_obj . relatedEps . append ( related_ep_obj )
2014-03-10 05:18:05 +00:00
2014-06-21 22:46:59 +00:00
root_ep_obj . rename ( )
2014-03-10 05:18:05 +00:00
2014-06-30 01:54:41 +00:00
redirect ( " /home/displayShow?show= " + show )
2014-09-15 07:23:55 +00:00
2014-03-10 05:18:05 +00:00
def searchEpisode ( self , show = None , season = None , episode = None ) :
2014-09-15 07:23:55 +00:00
2014-03-10 05:18:05 +00:00
# retrieve the episode object and fail if we can't get one
ep_obj = _getEpisode ( show , season , episode )
if isinstance ( ep_obj , str ) :
return json . dumps ( { ' result ' : ' failure ' } )
# make a queue item for it and put it on the queue
2014-05-16 03:39:46 +00:00
ep_queue_item = search_queue . ManualSearchQueueItem ( ep_obj . show , ep_obj )
2014-03-10 05:18:05 +00:00
2014-09-15 07:23:55 +00:00
sickbeard . searchQueueScheduler . action . add_item ( ep_queue_item ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
if ep_queue_item . success :
2014-09-15 07:23:55 +00:00
return returnManualSearchResult ( ep_queue_item )
if not ep_queue_item . started and ep_queue_item . success is None :
return json . dumps ( { ' result ' : ' success ' } ) #I Actually want to call it queued, because the search hasnt been started yet!
if ep_queue_item . started and ep_queue_item . success is None :
return json . dumps ( { ' result ' : ' success ' } )
else :
return json . dumps ( { ' result ' : ' failure ' } )
2014-03-10 05:18:05 +00:00
2014-09-15 07:23:55 +00:00
### Returns the current ep_queue_item status for the current viewed show.
# Possible status: Downloaded, Snatched, etc...
# Returns {'show': 279530, 'episodes' : ['episode' : 6, 'season' : 1, 'searchstatus' : 'queued', 'status' : 'running', 'quality': '4013']
def getManualSearchStatus ( self , show = None , season = None ) :
2014-03-10 05:18:05 +00:00
2014-09-15 07:23:55 +00:00
episodes = [ ]
currentManualSearchThreadsQueued = [ ]
currentManualSearchThreadActive = [ ]
finishedManualSearchThreadItems = [ ]
# Queued Searches
currentManualSearchThreadsQueued = sickbeard . searchQueueScheduler . action . get_all_ep_from_queue ( show )
# Running Searches
if ( sickbeard . searchQueueScheduler . action . is_manualsearch_in_progress ( ) ) :
currentManualSearchThreadActive = sickbeard . searchQueueScheduler . action . currentItem
# Finished Searches
finishedManualSearchThreadItems = sickbeard . search_queue . MANUAL_SEARCH_HISTORY
if currentManualSearchThreadsQueued :
for searchThread in currentManualSearchThreadsQueued :
searchstatus = ' queued '
2014-09-17 10:24:54 +00:00
if isinstance ( searchThread , sickbeard . search_queue . ManualSearchQueueItem ) :
episodes . append ( { ' episode ' : searchThread . segment . episode ,
' episodeindexid ' : searchThread . segment . indexerid ,
' season ' : searchThread . segment . season ,
' searchstatus ' : searchstatus ,
' status ' : statusStrings [ searchThread . segment . status ] ,
' quality ' : self . getQualityClass ( searchThread . segment ) } )
else :
for epObj in searchThread . segment :
episodes . append ( { ' episode ' : epObj . episode ,
' episodeindexid ' : epObj . indexerid ,
' season ' : epObj . season ,
' searchstatus ' : searchstatus ,
' status ' : statusStrings [ epObj . status ] ,
' quality ' : self . getQualityClass ( epObj ) } )
2014-09-15 07:23:55 +00:00
if currentManualSearchThreadActive :
searchThread = currentManualSearchThreadActive
searchstatus = ' searching '
if searchThread . success :
searchstatus = ' finished '
2014-09-19 11:56:49 +00:00
else :
searchstatus = ' searching '
episodes . append ( { ' episode ' : searchThread . segment . episode ,
2014-09-15 07:23:55 +00:00
' episodeindexid ' : searchThread . segment . indexerid ,
2014-09-19 11:56:49 +00:00
' season ' : searchThread . segment . season ,
' searchstatus ' : searchstatus ,
' status ' : statusStrings [ searchThread . segment . status ] ,
' quality ' : self . getQualityClass ( searchThread . segment ) } )
2014-09-15 07:23:55 +00:00
if finishedManualSearchThreadItems :
for searchThread in finishedManualSearchThreadItems :
2014-09-17 10:24:54 +00:00
if isinstance ( searchThread , sickbeard . search_queue . ManualSearchQueueItem ) :
if str ( searchThread . show . indexerid ) == show and not [ x for x in episodes if x [ ' episodeindexid ' ] == searchThread . segment . indexerid ] :
searchstatus = ' finished '
episodes . append ( { ' episode ' : searchThread . segment . episode ,
' episodeindexid ' : searchThread . segment . indexerid ,
' season ' : searchThread . segment . season ,
' searchstatus ' : searchstatus ,
' status ' : statusStrings [ searchThread . segment . status ] ,
' quality ' : self . getQualityClass ( searchThread . segment ) } )
else :
### These are only Failed Downloads/Retry SearchThreadItems.. lets loop through the segement/episodes
if str ( searchThread . show . indexerid ) == show :
for epObj in searchThread . segment :
if not [ x for x in episodes if x [ ' episodeindexid ' ] == epObj . indexerid ] :
searchstatus = ' finished '
episodes . append ( { ' episode ' : epObj . episode ,
' episodeindexid ' : epObj . indexerid ,
' season ' : epObj . season ,
' searchstatus ' : searchstatus ,
' status ' : statusStrings [ epObj . status ] ,
' quality ' : self . getQualityClass ( epObj ) } )
2014-09-15 07:23:55 +00:00
return json . dumps ( { ' show ' : show , ' episodes ' : episodes } )
#return json.dumps()
def getQualityClass ( self , ep_obj ) :
# return the correct json value
# Find the quality class for the episode
quality_class = Quality . qualityStrings [ Quality . UNKNOWN ]
ep_status , ep_quality = Quality . splitCompositeStatus ( ep_obj . status )
for x in ( SD , HD720p , HD1080p ) :
if ep_quality in Quality . splitQuality ( x ) [ 0 ] :
quality_class = qualityPresetStrings [ x ]
break
2014-03-10 05:18:05 +00:00
2014-09-15 07:23:55 +00:00
return quality_class
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def searchEpisodeSubtitles ( self , show = None , season = None , episode = None ) :
# retrieve the episode object and fail if we can't get one
ep_obj = _getEpisode ( show , season , episode )
if isinstance ( ep_obj , str ) :
return json . dumps ( { ' result ' : ' failure ' } )
# try do download subtitles for that episode
2014-10-12 21:25:06 +00:00
previous_subtitles = set ( subliminal . language . Language ( x ) for x in ep_obj . subtitles )
2014-03-10 05:18:05 +00:00
try :
2014-10-12 21:25:06 +00:00
ep_obj . subtitles = set ( x . language for x in ep_obj . downloadSubtitles ( ) . values ( ) [ 0 ] )
2014-03-10 05:18:05 +00:00
except :
return json . dumps ( { ' result ' : ' failure ' } )
# return the correct json value
if previous_subtitles != ep_obj . subtitles :
2014-03-25 05:57:24 +00:00
status = ' New subtitles downloaded: %s ' % ' ' . join ( [
2014-10-12 21:25:06 +00:00
" <img src= ' " + sickbeard . WEB_ROOT + " /images/flags/ " + x . alpha2 +
" .png ' alt= ' " + x . name + " ' /> " for x in
sorted ( list ( ep_obj . subtitles . difference ( previous_subtitles ) ) ) ] )
2014-03-10 05:18:05 +00:00
else :
status = ' No subtitles downloaded '
ui . notifications . message ( ' Subtitles Search ' , status )
2014-10-13 09:49:05 +00:00
return json . dumps ( { ' result ' : status , ' subtitles ' : ' , ' . join ( sorted ( [ x . alpha2 for x in
ep_obj . subtitles . union ( previous_subtitles ) ] ) ) } )
2014-06-11 08:34:28 +00:00
2014-06-07 12:36:50 +00:00
def setSceneNumbering ( self , show , indexer , forSeason = None , forEpisode = None , forAbsolute = None , sceneSeason = None ,
sceneEpisode = None , sceneAbsolute = None ) :
2014-03-10 05:18:05 +00:00
# sanitize:
2014-05-30 05:48:02 +00:00
if forSeason in [ ' null ' , ' ' ] : forSeason = None
if forEpisode in [ ' null ' , ' ' ] : forEpisode = None
if forAbsolute in [ ' null ' , ' ' ] : forAbsolute = None
2014-03-10 05:18:05 +00:00
if sceneSeason in [ ' null ' , ' ' ] : sceneSeason = None
if sceneEpisode in [ ' null ' , ' ' ] : sceneEpisode = None
2014-05-30 05:48:02 +00:00
if sceneAbsolute in [ ' null ' , ' ' ] : sceneAbsolute = None
2014-03-25 05:57:24 +00:00
2014-05-30 05:48:02 +00:00
showObj = sickbeard . helpers . findCertainShow ( sickbeard . showList , int ( show ) )
if showObj . is_anime :
result = {
' success ' : True ,
' forAbsolute ' : forAbsolute ,
}
else :
result = {
' success ' : True ,
' forSeason ' : forSeason ,
' forEpisode ' : forEpisode ,
}
2014-03-25 05:57:24 +00:00
# retrieve the episode object and fail if we can't get one
2014-05-30 05:48:02 +00:00
if showObj . is_anime :
ep_obj = _getEpisode ( show , absolute = forAbsolute )
else :
ep_obj = _getEpisode ( show , forSeason , forEpisode )
2014-03-10 05:18:05 +00:00
if isinstance ( ep_obj , str ) :
result [ ' success ' ] = False
result [ ' errorMessage ' ] = ep_obj
2014-05-30 05:48:02 +00:00
elif showObj . is_anime :
logger . log ( u " setAbsoluteSceneNumbering for %s from %s to %s " %
( show , forAbsolute , sceneAbsolute ) , logger . DEBUG )
show = int ( show )
indexer = int ( indexer )
forAbsolute = int ( forAbsolute )
if sceneAbsolute is not None : sceneAbsolute = int ( sceneAbsolute )
set_scene_numbering ( show , indexer , absolute_number = forAbsolute , sceneAbsolute = sceneAbsolute )
2014-03-10 05:18:05 +00:00
else :
2014-03-25 05:57:24 +00:00
logger . log ( u " setEpisodeSceneNumbering for %s from %s x %s to %s x %s " %
2014-03-10 05:18:05 +00:00
( show , forSeason , forEpisode , sceneSeason , sceneEpisode ) , logger . DEBUG )
2014-03-25 05:57:24 +00:00
2014-04-23 01:58:35 +00:00
show = int ( show )
2014-05-03 10:09:46 +00:00
indexer = int ( indexer )
2014-03-10 05:18:05 +00:00
forSeason = int ( forSeason )
forEpisode = int ( forEpisode )
if sceneSeason is not None : sceneSeason = int ( sceneSeason )
if sceneEpisode is not None : sceneEpisode = int ( sceneEpisode )
2014-03-25 05:57:24 +00:00
2014-06-07 12:36:50 +00:00
set_scene_numbering ( show , indexer , season = forSeason , episode = forEpisode , sceneSeason = sceneSeason ,
sceneEpisode = sceneEpisode )
2014-05-03 10:09:46 +00:00
2014-05-30 05:48:02 +00:00
if showObj . is_anime :
sn = get_scene_absolute_numbering ( show , indexer , forAbsolute )
if sn :
result [ ' sceneAbsolute ' ] = sn
else :
result [ ' sceneAbsolute ' ] = None
2014-03-10 05:18:05 +00:00
else :
2014-05-30 05:48:02 +00:00
sn = get_scene_numbering ( show , indexer , forSeason , forEpisode )
if sn :
( result [ ' sceneSeason ' ] , result [ ' sceneEpisode ' ] ) = sn
else :
( result [ ' sceneSeason ' ] , result [ ' sceneEpisode ' ] ) = ( None , None )
2014-03-10 05:18:05 +00:00
return json . dumps ( result )
2014-03-25 05:57:24 +00:00
2014-06-11 08:34:28 +00:00
2014-03-10 05:18:05 +00:00
def retryEpisode ( self , show , season , episode ) :
# retrieve the episode object and fail if we can't get one
ep_obj = _getEpisode ( show , season , episode )
if isinstance ( ep_obj , str ) :
return json . dumps ( { ' result ' : ' failure ' } )
# make a queue item for it and put it on the queue
2014-09-17 10:24:54 +00:00
ep_queue_item = search_queue . FailedQueueItem ( ep_obj . show , [ ep_obj ] )
2014-03-25 05:57:24 +00:00
sickbeard . searchQueueScheduler . action . add_item ( ep_queue_item ) # @UndefinedVariable
2014-03-10 05:18:05 +00:00
if ep_queue_item . success :
2014-09-15 13:01:18 +00:00
return returnManualSearchResult ( ep_queue_item )
if not ep_queue_item . started and ep_queue_item . success is None :
return json . dumps ( { ' result ' : ' success ' } ) #I Actually want to call it queued, because the search hasnt been started yet!
if ep_queue_item . started and ep_queue_item . success is None :
return json . dumps ( { ' result ' : ' success ' } )
else :
return json . dumps ( { ' result ' : ' failure ' } )
2014-07-01 08:49:12 +00:00
2014-06-19 08:37:44 +00:00
class UI ( MainHandler ) :
2014-06-29 10:05:33 +00:00
def add_message ( self ) :
2014-03-10 05:18:05 +00:00
ui . notifications . message ( ' Test 1 ' , ' This is test number 1 ' )
ui . notifications . error ( ' Test 2 ' , ' This is test number 2 ' )
2014-06-16 12:19:07 +00:00
return " ok "
2014-06-11 08:34:28 +00:00
2014-06-29 10:05:33 +00:00
def get_messages ( self ) :
2014-03-10 05:18:05 +00:00
messages = { }
cur_notification_num = 1
2014-06-30 03:58:34 +00:00
for cur_notification in ui . notifications . get_notifications ( self . request . remote_ip ) :
2014-03-10 05:18:05 +00:00
messages [ ' notification- ' + str ( cur_notification_num ) ] = { ' title ' : cur_notification . title ,
2014-07-01 08:49:12 +00:00
' message ' : cur_notification . message ,
' type ' : cur_notification . type }
2014-03-10 05:18:05 +00:00
cur_notification_num + = 1
2014-08-08 07:18:03 +00:00
return json . dumps ( messages )