2017-12-20 11:25:10 +08:00
bazarr_version = ' 0.2.1 '
2017-11-16 10:25:14 +08:00
2017-09-16 08:49:46 +08:00
from bottle import route , run , template , static_file , request , redirect
import bottle
2017-11-21 05:25:34 +08:00
bottle . debug ( True )
bottle . TEMPLATES . clear ( )
2017-10-22 09:09:04 +08:00
import os
2017-10-22 08:43:32 +08:00
bottle . TEMPLATE_PATH . insert ( 0 , os . path . join ( os . path . dirname ( __file__ ) , ' views/ ' ) )
2017-09-16 08:49:46 +08:00
import sqlite3
import itertools
import operator
import requests
2017-09-17 21:02:16 +08:00
import pycountry
2017-10-23 11:00:11 +08:00
import pretty
import datetime
2017-09-16 08:49:46 +08:00
from PIL import Image
from io import BytesIO
from fdsend import send_file
import urllib
from init_db import *
2017-12-08 09:03:32 +08:00
import update_db
2017-09-16 08:49:46 +08:00
from get_languages import *
2017-09-19 18:43:14 +08:00
from get_providers import *
2017-10-03 10:59:45 +08:00
from get_series import *
from get_episodes import *
2017-09-16 08:49:46 +08:00
from get_general_settings import *
from get_sonarr_settings import *
2017-11-10 05:13:14 +08:00
from check_update import *
2017-09-16 08:49:46 +08:00
from list_subtitles import *
2017-09-17 08:11:47 +08:00
from get_subtitle import *
2017-09-17 21:02:16 +08:00
from utils import *
2017-10-23 11:00:11 +08:00
from scheduler import *
2017-09-16 08:49:46 +08:00
2017-10-17 07:27:19 +08:00
import logging
from logging . handlers import TimedRotatingFileHandler
2017-11-16 10:17:51 +08:00
2017-10-17 07:27:19 +08:00
logger = logging . getLogger ( ' waitress ' )
2017-12-05 08:01:10 +08:00
db = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-10-17 07:27:19 +08:00
c = db . cursor ( )
c . execute ( " SELECT log_level FROM table_settings_general " )
log_level = c . fetchone ( )
2017-12-01 03:35:03 +08:00
c . close ( )
2017-10-17 07:27:19 +08:00
log_level = log_level [ 0 ]
if log_level is None :
2017-11-16 10:07:21 +08:00
log_level = " INFO "
2017-10-17 07:27:19 +08:00
log_level = getattr ( logging , log_level )
2017-12-01 03:31:31 +08:00
2017-10-17 07:27:19 +08:00
class OneLineExceptionFormatter ( logging . Formatter ) :
def formatException ( self , exc_info ) :
"""
Format an exception so that it prints on a single line .
"""
result = super ( OneLineExceptionFormatter , self ) . formatException ( exc_info )
return repr ( result ) # or format into one line however you want to
def format ( self , record ) :
s = super ( OneLineExceptionFormatter , self ) . format ( record )
if record . exc_text :
s = s . replace ( ' \n ' , ' ' ) + ' | '
return s
def configure_logging ( ) :
2017-12-14 01:42:09 +08:00
global fh
2017-10-20 20:59:21 +08:00
fh = TimedRotatingFileHandler ( os . path . join ( os . path . dirname ( __file__ ) , ' data/log/bazarr.log ' ) , when = " midnight " , interval = 1 , backupCount = 7 )
2017-10-17 07:27:19 +08:00
f = OneLineExceptionFormatter ( ' %(asctime)s | %(levelname)s | %(message)s | ' ,
' %d / % m/ % Y % H: % M: % S ' )
fh . setFormatter ( f )
2017-12-05 08:01:10 +08:00
logging . getLogger ( " enzyme " ) . setLevel ( logging . CRITICAL )
2017-11-22 05:03:29 +08:00
logging . getLogger ( " apscheduler " ) . setLevel ( logging . WARNING )
logging . getLogger ( " subliminal " ) . setLevel ( logging . ERROR )
2017-10-17 07:27:19 +08:00
root = logging . getLogger ( )
root . setLevel ( log_level )
root . addHandler ( fh )
configure_logging ( )
2017-12-14 01:42:09 +08:00
2017-11-10 05:13:14 +08:00
@route ( ' / ' )
def redirect_root ( ) :
redirect ( base_url )
@route ( base_url + ' static/:path#.+# ' , name = ' static ' )
2017-09-16 08:49:46 +08:00
def static ( path ) :
2017-10-22 09:25:31 +08:00
return static_file ( path , root = os . path . join ( os . path . dirname ( __file__ ) , ' static ' ) )
2017-09-16 08:49:46 +08:00
2017-12-14 01:42:09 +08:00
@route ( base_url + ' emptylog ' )
def emptylog ( ) :
ref = request . environ [ ' HTTP_REFERER ' ]
fh . doRollover ( )
logging . info ( ' Log file emptied ' )
redirect ( ref )
@route ( base_url + ' bazarr.log ' )
def download_log ( ) :
2017-12-14 01:55:03 +08:00
return static_file ( ' bazarr.log ' , root = os . path . join ( os . path . dirname ( __file__ ) , ' data/log/ ' ) , download = ' bazarr.log ' )
2017-12-14 01:42:09 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' image_proxy/<url:path> ' , method = ' GET ' )
2017-09-16 08:49:46 +08:00
def image_proxy ( url ) :
2017-12-20 11:25:10 +08:00
from get_sonarr_settings import get_sonarr_settings
url_sonarr_short = get_sonarr_settings ( ) [ 1 ]
2017-09-16 08:49:46 +08:00
img_pil = Image . open ( BytesIO ( requests . get ( url_sonarr_short + ' / ' + url ) . content ) )
img_buffer = BytesIO ( )
img_pil . tobytes ( )
img_pil . save ( img_buffer , img_pil . format )
img_buffer . seek ( 0 )
return send_file ( img_buffer , ctype = img_pil . format )
2017-11-10 05:13:14 +08:00
@route ( base_url )
2017-09-16 08:49:46 +08:00
def series ( ) :
2017-12-05 08:01:10 +08:00
db = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-09-16 08:49:46 +08:00
db . create_function ( " path_substitution " , 1 , path_replace )
c = db . cursor ( )
2017-12-06 10:05:49 +08:00
c . execute ( " SELECT COUNT(*) FROM table_shows " )
missing_count = c . fetchone ( )
missing_count = missing_count [ 0 ]
page = request . GET . page
if page == " " :
page = " 1 "
offset = ( int ( page ) - 1 ) * 15
max_page = ( missing_count / 15 ) + 1
2017-12-19 09:24:04 +08:00
c . execute ( " SELECT tvdbId, title, path_substitution(path), languages, hearing_impaired, sonarrSeriesId, poster, audio_language FROM table_shows ORDER BY title ASC LIMIT 15 OFFSET ? " , ( offset , ) )
2017-09-16 08:49:46 +08:00
data = c . fetchall ( )
c . execute ( " SELECT code2, name FROM table_settings_languages WHERE enabled = 1 " )
languages = c . fetchall ( )
c . close ( )
2017-12-06 10:05:49 +08:00
output = template ( ' series ' , rows = data , languages = languages , missing_count = missing_count , page = page , max_page = max_page , base_url = base_url )
2017-09-16 08:49:46 +08:00
return output
2017-11-10 05:13:14 +08:00
@route ( base_url + ' edit_series/<no:int> ' , method = ' POST ' )
2017-09-16 08:49:46 +08:00
def edit_series ( no ) :
2017-10-19 02:54:24 +08:00
ref = request . environ [ ' HTTP_REFERER ' ]
2017-09-16 08:49:46 +08:00
lang = request . forms . getall ( ' languages ' )
if len ( lang ) > 0 :
if lang [ 0 ] == ' ' :
lang = None
else :
pass
else :
lang = None
hi = request . forms . get ( ' hearing_impaired ' )
if hi == " on " :
hi = " True "
else :
hi = " False "
2017-12-05 08:01:10 +08:00
conn = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-09-16 08:49:46 +08:00
c = conn . cursor ( )
c . execute ( " UPDATE table_shows SET languages = ?, hearing_impaired = ? WHERE tvdbId LIKE ? " , ( str ( lang ) , hi , no ) )
conn . commit ( )
c . close ( )
2017-10-17 07:27:19 +08:00
list_missing_subtitles ( no )
2017-10-19 02:54:24 +08:00
redirect ( ref )
2017-09-16 08:49:46 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' episodes/<no:int> ' , method = ' GET ' )
2017-09-16 08:49:46 +08:00
def episodes ( no ) :
2017-12-20 11:25:10 +08:00
from get_sonarr_settings import get_sonarr_settings
url_sonarr_short = get_sonarr_settings ( ) [ 1 ]
2017-12-05 08:01:10 +08:00
conn = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-09-16 08:49:46 +08:00
conn . create_function ( " path_substitution " , 1 , path_replace )
c = conn . cursor ( )
series_details = [ ]
2017-11-16 22:53:12 +08:00
series_details = c . execute ( " SELECT title, overview, poster, fanart, hearing_impaired, tvdbid FROM table_shows WHERE sonarrSeriesId LIKE ? " , ( str ( no ) , ) ) . fetchone ( )
tvdbid = series_details [ 5 ]
2017-09-16 08:49:46 +08:00
2017-10-17 07:27:19 +08:00
episodes = c . execute ( " SELECT title, path_substitution(path), season, episode, subtitles, sonarrSeriesId, missing_subtitles, sonarrEpisodeId FROM table_episodes WHERE sonarrSeriesId LIKE ? ORDER BY episode ASC " , ( str ( no ) , ) ) . fetchall ( )
2017-12-01 03:31:31 +08:00
c . close ( )
2017-09-17 21:02:16 +08:00
episodes = reversed ( sorted ( episodes , key = operator . itemgetter ( 2 ) ) )
2017-09-16 08:49:46 +08:00
seasons_list = [ ]
for key , season in itertools . groupby ( episodes , operator . itemgetter ( 2 ) ) :
seasons_list . append ( list ( season ) )
2017-11-16 22:53:12 +08:00
return template ( ' episodes ' , no = no , details = series_details , seasons = seasons_list , url_sonarr_short = url_sonarr_short , base_url = base_url , tvdbid = tvdbid )
2017-10-17 07:27:19 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' scan_disk/<no:int> ' , method = ' GET ' )
2017-10-17 07:27:19 +08:00
def scan_disk ( no ) :
ref = request . environ [ ' HTTP_REFERER ' ]
series_scan_subtitles ( no )
redirect ( ref )
2017-11-10 05:13:14 +08:00
@route ( base_url + ' search_missing_subtitles/<no:int> ' , method = ' GET ' )
2017-10-17 07:27:19 +08:00
def search_missing_subtitles ( no ) :
ref = request . environ [ ' HTTP_REFERER ' ]
series_download_subtitles ( no )
redirect ( ref )
2017-09-16 08:49:46 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' history ' )
2017-09-16 08:49:46 +08:00
def history ( ) :
2017-12-05 08:01:10 +08:00
db = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-09-16 08:49:46 +08:00
c = db . cursor ( )
2017-10-03 10:59:45 +08:00
c . execute ( " SELECT COUNT(*) FROM table_history " )
row_count = c . fetchone ( )
row_count = row_count [ 0 ]
page = request . GET . page
if page == " " :
page = " 1 "
offset = ( int ( page ) - 1 ) * 15
max_page = ( row_count / 15 ) + 1
c . execute ( " SELECT table_history.action, table_shows.title, table_episodes.season || ' x ' || table_episodes.episode, table_episodes.title, table_history.timestamp, table_history.description, table_history.sonarrSeriesId FROM table_history INNER JOIN table_shows on table_shows.sonarrSeriesId = table_history.sonarrSeriesId INNER JOIN table_episodes on table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId ORDER BY id DESC LIMIT 15 OFFSET ? " , ( offset , ) )
2017-09-16 08:49:46 +08:00
data = c . fetchall ( )
c . close ( )
2017-12-01 03:31:31 +08:00
data = reversed ( sorted ( data , key = operator . itemgetter ( 4 ) ) )
2017-10-19 02:54:24 +08:00
return template ( ' history ' , rows = data , row_count = row_count , page = page , max_page = max_page , base_url = base_url )
2017-10-03 10:59:45 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' wanted ' )
2017-10-03 10:59:45 +08:00
def wanted ( ) :
2017-12-05 08:01:10 +08:00
db = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-10-03 10:59:45 +08:00
db . create_function ( " path_substitution " , 1 , path_replace )
c = db . cursor ( )
c . execute ( " SELECT COUNT(*) FROM table_episodes WHERE missing_subtitles != ' [] ' " )
missing_count = c . fetchone ( )
missing_count = missing_count [ 0 ]
page = request . GET . page
if page == " " :
page = " 1 "
offset = ( int ( page ) - 1 ) * 15
max_page = ( missing_count / 15 ) + 1
2017-10-17 07:27:19 +08:00
c . execute ( " SELECT table_shows.title, table_episodes.season || ' x ' || table_episodes.episode, table_episodes.title, table_episodes.missing_subtitles, table_episodes.sonarrSeriesId, path_substitution(table_episodes.path), table_shows.hearing_impaired, table_episodes.sonarrEpisodeId FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.missing_subtitles != ' [] ' ORDER BY table_episodes._rowid_ DESC LIMIT 15 OFFSET ? " , ( offset , ) )
2017-10-03 10:59:45 +08:00
data = c . fetchall ( )
c . close ( )
2017-10-19 02:54:24 +08:00
return template ( ' wanted ' , rows = data , missing_count = missing_count , page = page , max_page = max_page , base_url = base_url )
2017-09-16 08:49:46 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' wanted_search_missing_subtitles ' )
2017-10-24 05:24:22 +08:00
def wanted_search_missing_subtitles_list ( ) :
2017-10-17 07:27:19 +08:00
ref = request . environ [ ' HTTP_REFERER ' ]
2017-10-23 11:00:11 +08:00
wanted_search_missing_subtitles ( )
2017-10-17 07:27:19 +08:00
redirect ( ref )
2017-11-10 05:13:14 +08:00
@route ( base_url + ' settings ' )
2017-09-16 08:49:46 +08:00
def settings ( ) :
2017-12-05 08:01:10 +08:00
db = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-09-16 08:49:46 +08:00
c = db . cursor ( )
c . execute ( " SELECT * FROM table_settings_general " )
settings_general = c . fetchone ( )
2017-09-19 18:43:14 +08:00
c . execute ( " SELECT * FROM table_settings_languages ORDER BY name " )
2017-09-16 08:49:46 +08:00
settings_languages = c . fetchall ( )
2017-09-19 18:43:14 +08:00
c . execute ( " SELECT * FROM table_settings_providers ORDER BY name " )
2017-09-16 08:49:46 +08:00
settings_providers = c . fetchall ( )
c . execute ( " SELECT * FROM table_settings_sonarr " )
settings_sonarr = c . fetchone ( )
c . close ( )
2017-10-19 02:54:24 +08:00
return template ( ' settings ' , settings_general = settings_general , settings_languages = settings_languages , settings_providers = settings_providers , settings_sonarr = settings_sonarr , base_url = base_url )
2017-09-19 18:43:14 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' save_settings ' , method = ' POST ' )
2017-09-19 18:43:14 +08:00
def save_settings ( ) :
2017-10-19 02:54:24 +08:00
ref = request . environ [ ' HTTP_REFERER ' ]
2017-12-05 08:01:10 +08:00
conn = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-10-03 10:59:45 +08:00
c = conn . cursor ( )
2017-09-19 18:43:14 +08:00
2017-10-03 10:59:45 +08:00
settings_general_ip = request . forms . get ( ' settings_general_ip ' )
settings_general_port = request . forms . get ( ' settings_general_port ' )
settings_general_baseurl = request . forms . get ( ' settings_general_baseurl ' )
2017-10-17 07:27:19 +08:00
settings_general_loglevel = request . forms . get ( ' settings_general_loglevel ' )
2017-10-03 10:59:45 +08:00
settings_general_sourcepath = request . forms . getall ( ' settings_general_sourcepath ' )
settings_general_destpath = request . forms . getall ( ' settings_general_destpath ' )
settings_general_pathmapping = [ ]
settings_general_pathmapping . extend ( [ list ( a ) for a in zip ( settings_general_sourcepath , settings_general_destpath ) ] )
2017-10-28 09:41:24 +08:00
settings_general_branch = request . forms . get ( ' settings_general_branch ' )
settings_general_automatic = request . forms . get ( ' settings_general_automatic ' )
2017-10-28 10:09:03 +08:00
if settings_general_automatic is None :
settings_general_automatic = ' False '
else :
settings_general_automatic = ' True '
2017-10-28 10:00:39 +08:00
c . execute ( " UPDATE table_settings_general SET ip = ?, port = ?, base_url = ?, path_mapping = ?, log_level = ?, branch=?, auto_update=? " , ( settings_general_ip , settings_general_port , settings_general_baseurl , str ( settings_general_pathmapping ) , settings_general_loglevel , settings_general_branch , settings_general_automatic ) )
2017-12-20 12:27:53 +08:00
get_general_settings ( )
2017-10-03 10:59:45 +08:00
settings_sonarr_ip = request . forms . get ( ' settings_sonarr_ip ' )
settings_sonarr_port = request . forms . get ( ' settings_sonarr_port ' )
settings_sonarr_baseurl = request . forms . get ( ' settings_sonarr_baseurl ' )
settings_sonarr_ssl = request . forms . get ( ' settings_sonarr_ssl ' )
if settings_sonarr_ssl is None :
settings_sonarr_ssl = ' False '
2017-09-19 18:43:14 +08:00
else :
2017-10-03 10:59:45 +08:00
settings_sonarr_ssl = ' True '
settings_sonarr_apikey = request . forms . get ( ' settings_sonarr_apikey ' )
c . execute ( " UPDATE table_settings_sonarr SET ip = ?, port = ?, base_url = ?, ssl = ?, apikey = ? " , ( settings_sonarr_ip , settings_sonarr_port , settings_sonarr_baseurl , settings_sonarr_ssl , settings_sonarr_apikey ) )
2017-12-08 09:03:32 +08:00
2017-10-03 10:59:45 +08:00
settings_subliminal_providers = request . forms . getall ( ' settings_subliminal_providers ' )
c . execute ( " UPDATE table_settings_providers SET enabled = 0 " )
for item in settings_subliminal_providers :
c . execute ( " UPDATE table_settings_providers SET enabled = ' 1 ' WHERE name = ? " , ( item , ) )
2017-12-08 09:03:32 +08:00
settings_addic7ed_username = request . forms . get ( ' settings_addic7ed_username ' )
settings_addic7ed_password = request . forms . get ( ' settings_addic7ed_password ' )
c . execute ( " UPDATE table_settings_providers SET username = ?, password = ? WHERE name = ' addic7ed ' " , ( settings_addic7ed_username , settings_addic7ed_password ) )
settings_legendastv_username = request . forms . get ( ' settings_legendastv_username ' )
settings_legendastv_password = request . forms . get ( ' settings_legendastv_password ' )
c . execute ( " UPDATE table_settings_providers SET username = ?, password = ? WHERE name = ' legendastv ' " , ( settings_legendastv_username , settings_legendastv_password ) )
settings_opensubtitles_username = request . forms . get ( ' settings_opensubtitles_username ' )
settings_opensubtitles_password = request . forms . get ( ' settings_opensubtitles_password ' )
c . execute ( " UPDATE table_settings_providers SET username = ?, password = ? WHERE name = ' opensubtitles ' " , ( settings_opensubtitles_username , settings_opensubtitles_password ) )
2017-10-03 10:59:45 +08:00
settings_subliminal_languages = request . forms . getall ( ' settings_subliminal_languages ' )
c . execute ( " UPDATE table_settings_languages SET enabled = 0 " )
for item in settings_subliminal_languages :
c . execute ( " UPDATE table_settings_languages SET enabled = ' 1 ' WHERE code2 = ? " , ( item , ) )
2017-09-19 18:43:14 +08:00
conn . commit ( )
c . close ( )
2017-12-06 12:07:37 +08:00
logging . info ( ' Settings saved succefully. You must restart Bazarr. ' )
2017-10-03 10:59:45 +08:00
2017-10-19 02:54:24 +08:00
redirect ( ref )
2017-09-16 08:49:46 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' check_update ' )
2017-11-11 13:54:19 +08:00
def check_update ( ) :
2017-11-10 05:13:14 +08:00
ref = request . environ [ ' HTTP_REFERER ' ]
2017-12-06 12:07:37 +08:00
check_and_apply_update ( )
2017-11-10 05:13:14 +08:00
redirect ( ref )
@route ( base_url + ' system ' )
2017-09-16 08:49:46 +08:00
def system ( ) :
2017-11-20 11:38:06 +08:00
def get_time_from_interval ( interval ) :
interval_clean = interval . split ( ' [ ' )
interval_clean = interval_clean [ 1 ] [ : - 1 ]
interval_split = interval_clean . split ( ' : ' )
2017-11-20 11:49:17 +08:00
hour = interval_split [ 0 ]
minute = interval_split [ 1 ] . lstrip ( " 0 " )
second = interval_split [ 2 ] . lstrip ( " 0 " )
2017-11-20 11:38:06 +08:00
text = " every "
2017-11-20 11:49:17 +08:00
if hour != " 0 " :
text = text + hour
if hour == " 1 " :
2017-11-20 11:38:06 +08:00
text = text + " hour "
else :
text = text + " hours "
2017-11-20 11:49:17 +08:00
if minute != " " and second != " " :
2017-11-20 11:38:06 +08:00
text = text + " , "
2017-11-20 11:49:17 +08:00
elif minute == " " and second != " " :
text = text + " and "
elif minute != " " and second == " " :
text = text + " and "
if minute != " " :
text = text + minute
if minute == " 1 " :
2017-11-20 11:38:06 +08:00
text = text + " minute "
else :
text = text + " minutes "
2017-11-20 11:49:17 +08:00
if second != " " :
2017-11-20 11:38:06 +08:00
text = text + " and "
2017-11-20 11:49:17 +08:00
if second != " " :
text = text + second
if second == " 1 " :
2017-11-20 11:38:06 +08:00
text = text + " second "
else :
text = text + " seconds "
return text
def get_time_from_cron ( cron ) :
text = " at "
hour = str ( cron [ 5 ] )
minute = str ( cron [ 6 ] )
second = str ( cron [ 7 ] )
if hour != " 0 " and hour != " * " :
text = text + hour
if hour == " 0 " or hour == " 1 " :
text = text + " hour "
else :
text = text + " hours "
if minute != " * " and second != " 0 " :
text = text + " , "
elif minute == " * " and second != " 0 " :
text = text + " and "
elif minute != " 0 " and minute != " * " and second == " 0 " :
text = text + " and "
if minute != " 0 " and minute != " * " :
text = text + minute
if minute == " 0 " or minute == " 1 " :
text = text + " minute "
else :
text = text + " minutes "
if second != " 0 " and second != " * " :
text = text + " and "
if second != " 0 " and second != " * " :
text = text + second
if second == " 0 " or second == " 1 " :
text = text + " second "
else :
text = text + " seconds "
return text
2017-10-23 11:00:11 +08:00
task_list = [ ]
for job in scheduler . get_jobs ( ) :
2017-11-16 10:07:21 +08:00
if job . trigger . __str__ ( ) . startswith ( ' interval ' ) :
2017-11-20 11:38:06 +08:00
task_list . append ( [ job . name , get_time_from_interval ( str ( job . trigger ) ) , pretty . date ( job . next_run_time . replace ( tzinfo = None ) ) , job . id ] )
2017-11-16 10:07:21 +08:00
elif job . trigger . __str__ ( ) . startswith ( ' cron ' ) :
2017-11-20 11:38:06 +08:00
task_list . append ( [ job . name , get_time_from_cron ( job . trigger . fields ) , pretty . date ( job . next_run_time . replace ( tzinfo = None ) ) , job . id ] )
2017-11-22 12:01:26 +08:00
2017-11-30 11:54:38 +08:00
i = 0
2017-11-22 12:01:26 +08:00
with open ( os . path . join ( os . path . dirname ( __file__ ) , ' data/log/bazarr.log ' ) ) as f :
for i , l in enumerate ( f , 1 ) :
pass
row_count = i
max_page = ( row_count / 50 ) + 1
2017-10-17 07:27:19 +08:00
2017-11-22 12:01:26 +08:00
return template ( ' system ' , base_url = base_url , task_list = task_list , row_count = row_count , max_page = max_page , bazarr_version = bazarr_version )
@route ( base_url + ' logs/<page:int> ' )
def get_logs ( page ) :
page_size = 50
begin = ( page * page_size ) - page_size
end = ( page * page_size ) - 1
logs_complete = [ ]
for line in reversed ( open ( os . path . join ( os . path . dirname ( __file__ ) , ' data/log/bazarr.log ' ) ) . readlines ( ) ) :
logs_complete . append ( line . rstrip ( ) )
logs = logs_complete [ begin : end ]
return template ( ' logs ' , logs = logs , base_url = base_url )
2017-10-17 07:27:19 +08:00
2017-11-16 10:07:21 +08:00
@route ( base_url + ' execute/<taskid> ' )
def execute_task ( taskid ) :
ref = request . environ [ ' HTTP_REFERER ' ]
execute_now ( taskid )
redirect ( ref )
2017-11-10 05:13:14 +08:00
@route ( base_url + ' remove_subtitles ' , method = ' POST ' )
2017-09-16 08:49:46 +08:00
def remove_subtitles ( ) :
2017-10-17 07:27:19 +08:00
episodePath = request . forms . get ( ' episodePath ' )
language = request . forms . get ( ' language ' )
subtitlesPath = request . forms . get ( ' subtitlesPath ' )
sonarrSeriesId = request . forms . get ( ' sonarrSeriesId ' )
sonarrEpisodeId = request . forms . get ( ' sonarrEpisodeId ' )
2017-11-16 22:53:12 +08:00
tvdbid = request . forms . get ( ' tvdbid ' )
2017-09-16 08:49:46 +08:00
try :
os . remove ( subtitlesPath )
2017-09-17 21:02:16 +08:00
result = pycountry . languages . lookup ( language ) . name + " subtitles deleted from disk. "
history_log ( 0 , sonarrSeriesId , sonarrEpisodeId , result )
2017-09-16 08:49:46 +08:00
except OSError :
2017-09-17 08:11:47 +08:00
pass
store_subtitles ( episodePath )
2017-11-22 04:42:18 +08:00
list_missing_subtitles ( sonarrSeriesId )
2017-10-17 07:27:19 +08:00
2017-11-10 05:13:14 +08:00
@route ( base_url + ' get_subtitle ' , method = ' POST ' )
2017-09-17 08:11:47 +08:00
def get_subtitle ( ) :
2017-10-03 10:59:45 +08:00
ref = request . environ [ ' HTTP_REFERER ' ]
2017-10-17 07:27:19 +08:00
episodePath = request . forms . get ( ' episodePath ' )
language = request . forms . get ( ' language ' )
hi = request . forms . get ( ' hi ' )
sonarrSeriesId = request . forms . get ( ' sonarrSeriesId ' )
sonarrEpisodeId = request . forms . get ( ' sonarrEpisodeId ' )
2017-11-16 22:53:12 +08:00
tvdbid = request . forms . get ( ' tvdbid ' )
2017-10-03 10:59:45 +08:00
2017-12-05 08:01:10 +08:00
db = sqlite3 . connect ( os . path . join ( os . path . dirname ( __file__ ) , ' data/db/bazarr.db ' ) , timeout = 30 )
2017-10-03 10:59:45 +08:00
c = db . cursor ( )
2017-12-08 09:03:32 +08:00
c . execute ( " SELECT * FROM table_settings_providers WHERE enabled = 1 " )
enabled_providers = c . fetchall ( )
2017-10-03 10:59:45 +08:00
c . close ( )
providers_list = [ ]
2017-12-08 09:03:32 +08:00
providers_auth = { }
if len ( enabled_providers ) > 0 :
for provider in enabled_providers :
providers_list . append ( provider [ 0 ] )
try :
if provider [ 2 ] is not ' ' and provider [ 3 ] is not ' ' :
provider_auth = providers_auth . append ( provider [ 0 ] )
provider_auth . update ( { ' username ' : providers [ 2 ] , ' password ' : providers [ 3 ] } )
else :
providers_auth = None
except :
providers_auth = None
else :
providers_list = None
providers_auth = None
2017-09-17 08:11:47 +08:00
2017-09-16 09:33:49 +08:00
try :
2017-12-08 09:03:32 +08:00
result = download_subtitle ( episodePath , language , hi , providers_list , providers_auth )
2017-10-03 10:59:45 +08:00
if result is not None :
history_log ( 1 , sonarrSeriesId , sonarrEpisodeId , result )
store_subtitles ( episodePath )
2017-11-22 04:42:18 +08:00
list_missing_subtitles ( sonarrSeriesId )
2017-10-03 10:59:45 +08:00
redirect ( ref )
2017-09-16 09:33:49 +08:00
except OSError :
2017-11-16 22:53:12 +08:00
pass
2017-09-16 09:33:49 +08:00
2017-12-14 01:42:09 +08:00
logging . info ( ' Bazarr is started and waiting for request on http:// ' + str ( ip ) + ' : ' + str ( port ) + str ( base_url ) )
2017-09-28 09:55:21 +08:00
run ( host = ip , port = port , server = ' waitress ' )
2017-12-14 01:42:09 +08:00
logging . info ( ' Bazarr has been stopped. ' )