@ -43,7 +43,7 @@ from werkzeug.exceptions import default_exceptions
from werkzeug . datastructures import Headers
from werkzeug . datastructures import Headers
from werkzeug . security import generate_password_hash , check_password_hash
from werkzeug . security import generate_password_hash , check_password_hash
from . import constants , logger, isoLanguages , services , worker
from . import constants , config, logger, isoLanguages , services , worker
from . import searched_ids , lm , babel , db , ub , config , get_locale , app
from . import searched_ids , lm , babel , db , ub , config , get_locale , app
from . gdriveutils import getFileFromEbooksFolder , do_gdrive_download
from . gdriveutils import getFileFromEbooksFolder , do_gdrive_download
from . helper import common_filters , get_search_results , fill_indexpage , speaking_language , check_valid_domain , \
from . helper import common_filters , get_search_results , fill_indexpage , speaking_language , check_valid_domain , \
@ -93,12 +93,11 @@ def error_http(error):
def internal_error ( error ) :
def internal_error ( error ) :
__ , __ , tb = sys . exc_info ( )
return render_template ( ' http_error.html ' ,
return render_template ( ' http_error.html ' ,
error_code = " Internal Server Error " ,
error_code = " Internal Server Error " ,
error_name = str ( error ) ,
error_name = str ( error ) ,
issue = True ,
issue = True ,
error_stack = traceback . format_ tb( tb ) ,
error_stack = traceback . format_ exc( ) . split ( " \n " ) ,
instance = config . config_calibre_web_title
instance = config . config_calibre_web_title
) , 500
) , 500
@ -791,9 +790,7 @@ def get_tasks_status():
@app.route ( " /reconnect " )
@app.route ( " /reconnect " )
def reconnect ( ) :
def reconnect ( ) :
db . session . close ( )
db . reconnect_db ( config )
db . engine . dispose ( )
db . setup_db ( )
return json . dumps ( { } )
return json . dumps ( { } )
@web.route ( " /search " , methods = [ " GET " ] )
@web.route ( " /search " , methods = [ " GET " ] )
@ -985,10 +982,7 @@ def render_read_books(page, are_read, as_xml=False, order=None):
entries , random , pagination = fill_indexpage ( page , db . Books , db_filter , order )
entries , random , pagination = fill_indexpage ( page , db . Books , db_filter , order )
if as_xml :
if as_xml :
xml = render_title_template ( ' feed.xml ' , entries = entries , pagination = pagination )
return entries , pagination
response = make_response ( xml )
response . headers [ " Content-Type " ] = " application/xml; charset=utf-8 "
return response
else :
else :
if are_read :
if are_read :
name = _ ( u ' Read Books ' ) + ' ( ' + str ( len ( readBookIds ) ) + ' ) '
name = _ ( u ' Read Books ' ) + ' ( ' + str ( len ( readBookIds ) ) + ' ) '
@ -1041,8 +1035,7 @@ def download_link(book_id, book_format):
@login_required
@login_required
@download_required
@download_required
def send_to_kindle ( book_id , book_format , convert ) :
def send_to_kindle ( book_id , book_format , convert ) :
settings = config . get_mail_settings ( )
if not config . get_mail_server_configured ( ) :
if settings . get ( " mail_server " , " mail.example.org " ) == " mail.example.org " :
flash ( _ ( u " Please configure the SMTP mail settings first... " ) , category = " error " )
flash ( _ ( u " Please configure the SMTP mail settings first... " ) , category = " error " )
elif current_user . kindle_mail :
elif current_user . kindle_mail :
result = send_mail ( book_id , book_format , convert , current_user . kindle_mail , config . config_calibre_dir ,
result = send_mail ( book_id , book_format , convert , current_user . kindle_mail , config . config_calibre_dir ,
@ -1067,16 +1060,19 @@ def register():
abort ( 404 )
abort ( 404 )
if current_user is not None and current_user . is_authenticated :
if current_user is not None and current_user . is_authenticated :
return redirect ( url_for ( ' web.index ' ) )
return redirect ( url_for ( ' web.index ' ) )
if not config . get_mail_server_configured ( ) :
flash ( _ ( u " E-Mail server is not configured, please contact your administrator! " ) , category = " error " )
return render_title_template ( ' register.html ' , title = _ ( u " register " ) , page = " register " )
if request . method == " POST " :
if request . method == " POST " :
to_save = request . form . to_dict ( )
to_save = request . form . to_dict ( )
if not to_save [ " nickname " ] or not to_save [ " email " ] :
if not to_save [ " nickname " ] or not to_save [ " email " ] :
flash ( _ ( u " Please fill out all fields! " ) , category = " error " )
flash ( _ ( u " Please fill out all fields! " ) , category = " error " )
return render_title_template ( ' register.html ' , title = _ ( u " register " ) , page = " register " )
return render_title_template ( ' register.html ' , title = _ ( u " register " ) , page = " register " )
existing_user = ub . session . query ( ub . User ) . filter ( func . lower ( ub . User . nickname ) == to_save [ " nickname " ]
existing_user = ub . session . query ( ub . User ) . filter ( func . lower ( ub . User . nickname ) == to_save [ " nickname " ]
. lower ( ) ) . first ( )
. lower ( ) ) . first ( )
existing_email = ub . session . query ( ub . User ) . filter ( ub . User . email == to_save [ " email " ] . lower ( ) ) . first ( )
existing_email = ub . session . query ( ub . User ) . filter ( ub . User . email == to_save [ " email " ] . lower ( ) ) . first ( )
if not existing_user and not existing_email :
if not existing_user and not existing_email :
content = ub . User ( )
content = ub . User ( )
# content.password = generate_password_hash(to_save["password"])
# content.password = generate_password_hash(to_save["password"])
@ -1116,10 +1112,12 @@ def register():
@web.route ( ' /login ' , methods = [ ' GET ' , ' POST ' ] )
@web.route ( ' /login ' , methods = [ ' GET ' , ' POST ' ] )
def login ( ) :
def login ( ) :
if not config . db_configured :
if not config . db_configured :
log . debug ( u " Redirect to initial configuration " )
return redirect ( url_for ( ' admin.basic_configuration ' ) )
return redirect ( url_for ( ' admin.basic_configuration ' ) )
if current_user is not None and current_user . is_authenticated :
if current_user is not None and current_user . is_authenticated :
return redirect ( url_for ( ' web.index ' ) )
return redirect ( url_for ( ' web.index ' ) )
if config . config_login_type == constants . LOGIN_LDAP and not services . ldap :
if config . config_login_type == constants . LOGIN_LDAP and not services . ldap :
log . error ( u " Cannot activate LDAP authentication " )
flash ( _ ( u " Cannot activate LDAP authentication " ) , category = " error " )
flash ( _ ( u " Cannot activate LDAP authentication " ) , category = " error " )
if request . method == " POST " :
if request . method == " POST " :
form = request . form . to_dict ( )
form = request . form . to_dict ( )
@ -1129,10 +1127,12 @@ def login():
login_result = services . ldap . bind_user ( form [ ' username ' ] , form [ ' password ' ] )
login_result = services . ldap . bind_user ( form [ ' username ' ] , form [ ' password ' ] )
if login_result :
if login_result :
login_user ( user , remember = True )
login_user ( user , remember = True )
log . debug ( u " You are now logged in as: ' %s ' " , user . nickname )
flash ( _ ( u " you are now logged in as: ' %(nickname)s ' " , nickname = user . nickname ) ,
flash ( _ ( u " you are now logged in as: ' %(nickname)s ' " , nickname = user . nickname ) ,
category = " success " )
category = " success " )
return redirect_back ( url_for ( " web.index " ) )
return redirect_back ( url_for ( " web.index " ) )
if login_result is None :
if login_result is None :
log . error ( ' Could not login. LDAP server down, please contact your administrator ' )
flash ( _ ( u " Could not login. LDAP server down, please contact your administrator " ) , category = " error " )
flash ( _ ( u " Could not login. LDAP server down, please contact your administrator " ) , category = " error " )
else :
else :
ipAdress = request . headers . get ( ' X-Forwarded-For ' , request . remote_addr )
ipAdress = request . headers . get ( ' X-Forwarded-For ' , request . remote_addr )
@ -1147,6 +1147,7 @@ def login():
flash ( _ ( u " New Password was send to your email address " ) , category = " info " )
flash ( _ ( u " New Password was send to your email address " ) , category = " info " )
log . info ( ' Password reset for user " %s " IP-adress: %s ' , form [ ' username ' ] , ipAdress )
log . info ( ' Password reset for user " %s " IP-adress: %s ' , form [ ' username ' ] , ipAdress )
else :
else :
log . info ( u " An unknown error occurred. Please try again later. " )
flash ( _ ( u " An unknown error occurred. Please try again later. " ) , category = " error " )
flash ( _ ( u " An unknown error occurred. Please try again later. " ) , category = " error " )
else :
else :
flash ( _ ( u " Please enter valid username to reset password " ) , category = " error " )
flash ( _ ( u " Please enter valid username to reset password " ) , category = " error " )
@ -1154,18 +1155,16 @@ def login():
else :
else :
if user and check_password_hash ( str ( user . password ) , form [ ' password ' ] ) and user . nickname != " Guest " :
if user and check_password_hash ( str ( user . password ) , form [ ' password ' ] ) and user . nickname != " Guest " :
login_user ( user , remember = True )
login_user ( user , remember = True )
log . debug ( u " You are now logged in as: ' %s ' " , user . nickname )
flash ( _ ( u " You are now logged in as: ' %(nickname)s ' " , nickname = user . nickname ) , category = " success " )
flash ( _ ( u " You are now logged in as: ' %(nickname)s ' " , nickname = user . nickname ) , category = " success " )
return redirect_back ( url_for ( " web.index " ) )
return redirect_back ( url_for ( " web.index " ) )
else :
else :
log . info ( ' Login failed for user " %s " IP-adress: %s ' , form [ ' username ' ] , ipAdress )
log . info ( ' Login failed for user " %s " IP-adress: %s ' , form [ ' username ' ] , ipAdress )
flash ( _ ( u " Wrong Username or Password " ) , category = " error " )
flash ( _ ( u " Wrong Username or Password " ) , category = " error " )
settings = config . get_mail_settings ( )
mail_configured = bool ( settings . get ( " mail_server " , " mail.example.org " ) != " mail.example.org " )
next_url = url_for ( ' web.index ' )
next_url = url_for ( ' web.index ' )
return render_title_template ( ' login.html ' , title = _ ( u " login " ) , next_url = next_url , config = config ,
return render_title_template ( ' login.html ' , title = _ ( u " login " ) , next_url = next_url , config = config ,
mail = mail_configured, page = " login " )
mail = config. get_ mail_server_ configured( ) , page = " login " )
@web.route ( ' /logout ' )
@web.route ( ' /logout ' )
@ -1175,6 +1174,7 @@ def logout():
logout_user ( )
logout_user ( )
if feature_support [ ' oauth ' ] and ( config . config_login_type == 2 or config . config_login_type == 3 ) :
if feature_support [ ' oauth ' ] and ( config . config_login_type == 2 or config . config_login_type == 3 ) :
logout_oauth_user ( )
logout_oauth_user ( )
log . debug ( u " User logged out " )
return redirect ( url_for ( ' web.login ' ) )
return redirect ( url_for ( ' web.login ' ) )
@ -1186,7 +1186,7 @@ def remote_login():
ub . session . commit ( )
ub . session . commit ( )
verify_url = url_for ( ' web.verify_token ' , token = auth_token . auth_token , _external = true )
verify_url = url_for ( ' web.verify_token ' , token = auth_token . auth_token , _external = true )
log . debug ( u " Remot Login request with token: %s " , auth_token . auth_token )
return render_title_template ( ' remote_login.html ' , title = _ ( u " login " ) , token = auth_token . auth_token ,
return render_title_template ( ' remote_login.html ' , title = _ ( u " login " ) , token = auth_token . auth_token ,
verify_url = verify_url , page = " remotelogin " )
verify_url = verify_url , page = " remotelogin " )
@ -1200,6 +1200,7 @@ def verify_token(token):
# Token not found
# Token not found
if auth_token is None :
if auth_token is None :
flash ( _ ( u " Token not found " ) , category = " error " )
flash ( _ ( u " Token not found " ) , category = " error " )
log . error ( u " Remote Login token not found " )
return redirect ( url_for ( ' web.index ' ) )
return redirect ( url_for ( ' web.index ' ) )
# Token expired
# Token expired
@ -1208,6 +1209,7 @@ def verify_token(token):
ub . session . commit ( )
ub . session . commit ( )
flash ( _ ( u " Token has expired " ) , category = " error " )
flash ( _ ( u " Token has expired " ) , category = " error " )
log . error ( u " Remote Login token expired " )
return redirect ( url_for ( ' web.index ' ) )
return redirect ( url_for ( ' web.index ' ) )
# Update token with user information
# Update token with user information
@ -1216,6 +1218,7 @@ def verify_token(token):
ub . session . commit ( )
ub . session . commit ( )
flash ( _ ( u " Success! Please return to your device " ) , category = " success " )
flash ( _ ( u " Success! Please return to your device " ) , category = " success " )
log . debug ( u " Remote Login token for userid %s verified " , auth_token . user_id )
return redirect ( url_for ( ' web.index ' ) )
return redirect ( url_for ( ' web.index ' ) )
@ -1251,6 +1254,7 @@ def token_verified():
ub . session . commit ( )
ub . session . commit ( )
data [ ' status ' ] = ' success '
data [ ' status ' ] = ' success '
log . debug ( u " Remote Login for userid %s succeded " , user . id )
flash ( _ ( u " you are now logged in as: ' %(nickname)s ' " , nickname = user . nickname ) , category = " success " )
flash ( _ ( u " you are now logged in as: ' %(nickname)s ' " , nickname = user . nickname ) , category = " success " )
response = make_response ( json . dumps ( data , ensure_ascii = False ) )
response = make_response ( json . dumps ( data , ensure_ascii = False ) )
@ -1278,8 +1282,6 @@ def profile():
downloads . append ( db . session . query ( db . Books ) . filter ( db . Books . id == book . book_id ) . first ( ) )
downloads . append ( db . session . query ( db . Books ) . filter ( db . Books . id == book . book_id ) . first ( ) )
else :
else :
ub . delete_download ( book . book_id )
ub . delete_download ( book . book_id )
# ub.session.query(ub.Downloads).filter(book.book_id == ub.Downloads.book_id).delete()
# ub.session.commit()
if request . method == " POST " :
if request . method == " POST " :
to_save = request . form . to_dict ( )
to_save = request . form . to_dict ( )
current_user . random_books = 0
current_user . random_books = 0
@ -1332,14 +1334,16 @@ def profile():
except IntegrityError :
except IntegrityError :
ub . session . rollback ( )
ub . session . rollback ( )
flash ( _ ( u " Found an existing account for this e-mail address. " ) , category = " error " )
flash ( _ ( u " Found an existing account for this e-mail address. " ) , category = " error " )
log . debug ( u " Found an existing account for this e-mail address. " )
return render_title_template ( " user_edit.html " , content = current_user , downloads = downloads ,
return render_title_template ( " user_edit.html " , content = current_user , downloads = downloads ,
translations = translations ,
translations = translations ,
title = _ ( u " %(name)s ' s profile " , name = current_user . nickname ) , page = " me " ,
title = _ ( u " %(name)s ' s profile " , name = current_user . nickname ) , page = " me " ,
registered_oauth = oauth_check , oauth_status = oauth_status )
registered_oauth = oauth_check , oauth_status = oauth_status )
flash ( _ ( u " Profile updated " ) , category = " success " )
flash ( _ ( u " Profile updated " ) , category = " success " )
log . debug ( u " Profile updated " )
return render_title_template ( " user_edit.html " , translations = translations , profile = 1 , languages = languages ,
return render_title_template ( " user_edit.html " , translations = translations , profile = 1 , languages = languages ,
content = current_user , downloads = downloads , title = _ ( u " %(name)s ' s profile " ,
content = current_user , downloads = downloads ,
name = current_user . nickname ) ,
title = _ ( u " %(name)s ' s profile " , name = current_user . nickname ) ,
page = " me " , registered_oauth = oauth_check , oauth_status = oauth_status )
page = " me " , registered_oauth = oauth_check , oauth_status = oauth_status )
@ -1353,6 +1357,7 @@ def read_book(book_id, book_format):
book = db . session . query ( db . Books ) . filter ( db . Books . id == book_id ) . filter ( common_filters ( ) ) . first ( )
book = db . session . query ( db . Books ) . filter ( db . Books . id == book_id ) . filter ( common_filters ( ) ) . first ( )
if not book :
if not book :
flash ( _ ( u " Error opening eBook. File does not exist or file is not accessible: " ) , category = " error " )
flash ( _ ( u " Error opening eBook. File does not exist or file is not accessible: " ) , category = " error " )
log . debug ( u " Error opening eBook. File does not exist or file is not accessible: " )
return redirect ( url_for ( " web.index " ) )
return redirect ( url_for ( " web.index " ) )
# check if book has bookmark
# check if book has bookmark
@ -1362,20 +1367,25 @@ def read_book(book_id, book_format):
ub . Bookmark . book_id == book_id ,
ub . Bookmark . book_id == book_id ,
ub . Bookmark . format == book_format . upper ( ) ) ) . first ( )
ub . Bookmark . format == book_format . upper ( ) ) ) . first ( )
if book_format . lower ( ) == " epub " :
if book_format . lower ( ) == " epub " :
log . debug ( u " Start epub reader for %d " , book_id )
return render_title_template ( ' read.html ' , bookid = book_id , title = _ ( u " Read a Book " ) , bookmark = bookmark )
return render_title_template ( ' read.html ' , bookid = book_id , title = _ ( u " Read a Book " ) , bookmark = bookmark )
elif book_format . lower ( ) == " pdf " :
elif book_format . lower ( ) == " pdf " :
log . debug ( u " Start pdf reader for %d " , book_id )
return render_title_template ( ' readpdf.html ' , pdffile = book_id , title = _ ( u " Read a Book " ) )
return render_title_template ( ' readpdf.html ' , pdffile = book_id , title = _ ( u " Read a Book " ) )
elif book_format . lower ( ) == " txt " :
elif book_format . lower ( ) == " txt " :
log . debug ( u " Start txt reader for %d " , book_id )
return render_title_template ( ' readtxt.html ' , txtfile = book_id , title = _ ( u " Read a Book " ) )
return render_title_template ( ' readtxt.html ' , txtfile = book_id , title = _ ( u " Read a Book " ) )
else :
else :
for fileExt in [ " mp3 " , " m4b " , " m4a " ] :
for fileExt in [ " mp3 " , " m4b " , " m4a " ] :
if book_format . lower ( ) == fileExt :
if book_format . lower ( ) == fileExt :
entries = db . session . query ( db . Books ) . filter ( db . Books . id == book_id ) . filter ( common_filters ( ) ) . first ( )
entries = db . session . query ( db . Books ) . filter ( db . Books . id == book_id ) . filter ( common_filters ( ) ) . first ( )
log . debug ( u " Start mp3 listening for %d " , book_id )
return render_title_template ( ' listenmp3.html ' , mp3file = book_id , audioformat = book_format . lower ( ) ,
return render_title_template ( ' listenmp3.html ' , mp3file = book_id , audioformat = book_format . lower ( ) ,
title = _ ( u " Read a Book " ) , entry = entries , bookmark = bookmark )
title = _ ( u " Read a Book " ) , entry = entries , bookmark = bookmark )
for fileExt in [ " cbr " , " cbt " , " cbz " ] :
for fileExt in [ " cbr " , " cbt " , " cbz " ] :
if book_format . lower ( ) == fileExt :
if book_format . lower ( ) == fileExt :
all_name = str ( book_id )
all_name = str ( book_id )
log . debug ( u " Start comic reader for %d " , book_id )
return render_title_template ( ' readcbr.html ' , comicfile = all_name , title = _ ( u " Read a Book " ) ,
return render_title_template ( ' readcbr.html ' , comicfile = all_name , title = _ ( u " Read a Book " ) ,
extension = fileExt )
extension = fileExt )
# if feature_support['rar']:
# if feature_support['rar']:
@ -1386,6 +1396,7 @@ def read_book(book_id, book_format):
# if book_format.lower() == fileext:
# if book_format.lower() == fileext:
# return render_title_template('readcbr.html', comicfile=book_id,
# return render_title_template('readcbr.html', comicfile=book_id,
# extension=fileext, title=_(u"Read a Book"), book=book)
# extension=fileext, title=_(u"Read a Book"), book=book)
log . debug ( u " Error opening eBook. File does not exist or file is not accessible: " )
flash ( _ ( u " Error opening eBook. File does not exist or file is not accessible. " ) , category = " error " )
flash ( _ ( u " Error opening eBook. File does not exist or file is not accessible. " ) , category = " error " )
return redirect ( url_for ( " web.index " ) )
return redirect ( url_for ( " web.index " ) )
@ -1418,7 +1429,7 @@ def show_book(book_id):
matching_have_read_book = getattr ( entries , ' custom_column_ ' + str ( config . config_read_column ) )
matching_have_read_book = getattr ( entries , ' custom_column_ ' + str ( config . config_read_column ) )
have_read = len ( matching_have_read_book ) > 0 and matching_have_read_book [ 0 ] . value
have_read = len ( matching_have_read_book ) > 0 and matching_have_read_book [ 0 ] . value
except KeyError :
except KeyError :
log . error ( " Custom Column No. %d is not exis i ting in calibre database" , config . config_read_column )
log . error ( " Custom Column No. %d is not exis ting in calibre database" , config . config_read_column )
have_read = None
have_read = None
else :
else :
@ -1440,5 +1451,6 @@ def show_book(book_id):
is_xhr = request . is_xhr , title = entries . title , books_shelfs = book_in_shelfs ,
is_xhr = request . is_xhr , title = entries . title , books_shelfs = book_in_shelfs ,
have_read = have_read , kindle_list = kindle_list , reader_list = reader_list , page = " book " )
have_read = have_read , kindle_list = kindle_list , reader_list = reader_list , page = " book " )
else :
else :
log . debug ( u " Error opening eBook. File does not exist or file is not accessible: " )
flash ( _ ( u " Error opening eBook. File does not exist or file is not accessible: " ) , category = " error " )
flash ( _ ( u " Error opening eBook. File does not exist or file is not accessible: " ) , category = " error " )
return redirect ( url_for ( " web.index " ) )
return redirect ( url_for ( " web.index " ) )