@ -415,6 +415,14 @@ def formatdate(val):
return format_date ( formatdate , format = ' medium ' , locale = get_locale ( ) )
return format_date ( formatdate , format = ' medium ' , locale = get_locale ( ) )
@app.template_filter ( ' formatdateinput ' )
def format_date_input ( val ) :
conformed_timestamp = re . sub ( r " [:]|([-](?!(( \ d {2} [:] \ d {2} )|( \ d {4} ))$)) " , ' ' , val )
date_obj = datetime . datetime . strptime ( conformed_timestamp [ : 15 ] , " % Y % m %d % H % M % S " )
input_date = date_obj . isoformat ( ) . split ( ' T ' , 1 ) [ 0 ] # Hack to support dates <1900
return ' ' if input_date == " 0101-01-01 " else input_date
@app.template_filter ( ' strftime ' )
@app.template_filter ( ' strftime ' )
def timestamptodate ( date , fmt = None ) :
def timestamptodate ( date , fmt = None ) :
date = datetime . datetime . fromtimestamp (
date = datetime . datetime . fromtimestamp (
@ -2695,14 +2703,14 @@ def edit_book(book_id):
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 ( " index " ) )
return redirect ( url_for ( " index " ) )
for index in range ( 0 , len ( book . languages ) ) :
for index in range ( 0 , len ( book . languages ) ) :
try :
try :
book . languages [ index ] . language_name = LC . parse ( book . languages [ index ] . lang_code ) . get_language_name (
book . languages [ index ] . language_name = LC . parse ( book . languages [ index ] . lang_code ) . get_language_name (
get_locale ( ) )
get_locale ( ) )
except Exception :
except Exception :
book . languages [ index ] . language_name = _ ( isoLanguages . get ( part3 = book . languages [ index ] . lang_code ) . name )
book . languages [ index ] . language_name = _ ( isoLanguages . get ( part3 = book . languages [ index ] . lang_code ) . name )
for author in book . authors :
for author in book . authors :
author_names . append ( author . name )
author_names . append ( author . name )
# Show form
# Show form
if request . method != ' POST ' :
if request . method != ' POST ' :
@ -2710,179 +2718,187 @@ def edit_book(book_id):
title = _ ( u " edit metadata " ) )
title = _ ( u " edit metadata " ) )
# Update book
# Update book
edited_books_id = set ( )
edited_books_id = set ( )
to_save = request . form . to_dict ( )
to_save = request . form . to_dict ( )
if book . title != to_save [ " book_title " ] :
if book . title != to_save [ " book_title " ] :
book . title = to_save [ " book_title " ]
book . title = to_save [ " book_title " ]
edited_books_id . add ( book . id )
edited_books_id . add ( book . id )
input_authors = to_save [ " author_name " ] . split ( ' & ' )
input_authors = to_save [ " author_name " ] . split ( ' & ' )
input_authors = map ( lambda it : it . strip ( ) , input_authors )
input_authors = map ( lambda it : it . strip ( ) , input_authors )
# we have all author names now
# we have all author names now
if input_authors == [ ' ' ] :
if input_authors == [ ' ' ] :
input_authors = [ _ ( u ' unknown ' ) ] # prevent empty Author
input_authors = [ _ ( u ' unknown ' ) ] # prevent empty Author
if book . authors :
if book . authors :
author0_before_edit = book . authors [ 0 ] . name
author0_before_edit = book . authors [ 0 ] . name
else :
else :
author0_before_edit = db . Authors ( _ ( u ' unknown ' ) , ' ' , 0 )
author0_before_edit = db . Authors ( _ ( u ' unknown ' ) , ' ' , 0 )
modify_database_object ( input_authors , book . authors , db . Authors , db . session , ' author ' )
modify_database_object ( input_authors , book . authors , db . Authors , db . session , ' author ' )
if book . authors :
if book . authors :
if author0_before_edit != book . authors [ 0 ] . name :
if author0_before_edit != book . authors [ 0 ] . name :
edited_books_id . add ( book . id )
edited_books_id . add ( book . id )
book . author_sort = helper . get_sorted_author ( input_authors [ 0 ] )
book . author_sort = helper . get_sorted_author ( input_authors [ 0 ] )
if to_save [ " cover_url " ] and os . path . splitext ( to_save [ " cover_url " ] ) [ 1 ] . lower ( ) == " .jpg " :
if to_save [ " cover_url " ] and os . path . splitext ( to_save [ " cover_url " ] ) [ 1 ] . lower ( ) == " .jpg " :
img = requests . get ( to_save [ " cover_url " ] )
img = requests . get ( to_save [ " cover_url " ] )
if config . config_use_google_drive :
if config . config_use_google_drive :
tmpDir = tempfile . gettempdir ( )
tmpDir = tempfile . gettempdir ( )
f = open ( os . path . join ( tmpDir , " uploaded_cover.jpg " ) , " wb " )
f = open ( os . path . join ( tmpDir , " uploaded_cover.jpg " ) , " wb " )
f . write ( img . content )
f . write ( img . content )
f . close ( )
f . close ( )
gdriveutils . uploadFileToEbooksFolder ( Gdrive . Instance ( ) . drive , os . path . join ( book . path , ' cover.jpg ' ) , os . path . join ( tmpDir , f . name ) )
gdriveutils . uploadFileToEbooksFolder ( Gdrive . Instance ( ) . drive , os . path . join ( book . path , ' cover.jpg ' ) , os . path . join ( tmpDir , f . name ) )
else :
else :
f = open ( os . path . join ( config . config_calibre_dir , book . path , " cover.jpg " ) , " wb " )
f = open ( os . path . join ( config . config_calibre_dir , book . path , " cover.jpg " ) , " wb " )
f . write ( img . content )
f . write ( img . content )
f . close ( )
f . close ( )
book . has_cover = 1
book . has_cover = 1
if book . series_index != to_save [ " series_index " ] :
if book . series_index != to_save [ " series_index " ] :
book . series_index = to_save [ " series_index " ]
book . series_index = to_save [ " series_index " ]
if len ( book . comments ) :
if len ( book . comments ) :
book . comments [ 0 ] . text = to_save [ " description " ]
book . comments [ 0 ] . text = to_save [ " description " ]
else :
else :
book . comments . append ( db . Comments ( text = to_save [ " description " ] , book = book . id ) )
book . comments . append ( db . Comments ( text = to_save [ " description " ] , book = book . id ) )
input_tags = to_save [ " tags " ] . split ( ' , ' )
input_tags = to_save [ " tags " ] . split ( ' , ' )
input_tags = map ( lambda it : it . strip ( ) , input_tags )
input_tags = map ( lambda it : it . strip ( ) , input_tags )
modify_database_object ( input_tags , book . tags , db . Tags , db . session , ' tags ' )
modify_database_object ( input_tags , book . tags , db . Tags , db . session , ' tags ' )
input_series = [ to_save [ " series " ] . strip ( ) ]
input_series = [ to_save [ " series " ] . strip ( ) ]
input_series = [ x for x in input_series if x != ' ' ]
input_series = [ x for x in input_series if x != ' ' ]
modify_database_object ( input_series , book . series , db . Series , db . session , ' series ' )
modify_database_object ( input_series , book . series , db . Series , db . session , ' series ' )
input_languages = to_save [ " languages " ] . split ( ' , ' )
input_languages = to_save [ " languages " ] . split ( ' , ' )
input_languages = map ( lambda it : it . strip ( ) . lower ( ) , input_languages )
input_languages = map ( lambda it : it . strip ( ) . lower ( ) , input_languages )
# retranslate displayed text to language codes
if to_save [ " pubdate " ] :
languages = db . session . query ( db . Languages ) . all ( )
try :
input_l = [ ]
book . pubdate = datetime . datetime . strptime ( to_save [ " pubdate " ] , " % Y- % m- %d " )
for lang in languages :
except ValueError :
try :
book . pubdate = db . Books . DEFAULT_PUBDATE
lang . name = LC . parse ( lang . lang_code ) . get_language_name ( get_locale ( ) ) . lower ( )
else :
except Exception :
book . pubdate = db . Books . DEFAULT_PUBDATE
lang . name = _ ( isoLanguages . get ( part3 = lang . lang_code ) . name ) . lower ( )
for inp_lang in input_languages :
if inp_lang == lang . name :
input_l . append ( lang . lang_code )
modify_database_object ( input_l , book . languages , db . Languages , db . session , ' languages ' )
if to_save [ " rating " ] . strip ( ) :
old_rating = False
if len ( book . ratings ) > 0 :
old_rating = book . ratings [ 0 ] . rating
ratingx2 = int ( float ( to_save [ " rating " ] ) * 2 )
if ratingx2 != old_rating :
is_rating = db . session . query ( db . Ratings ) . filter ( db . Ratings . rating == ratingx2 ) . first ( )
if is_rating :
book . ratings . append ( is_rating )
else :
new_rating = db . Ratings ( rating = ratingx2 )
book . ratings . append ( new_rating )
if old_rating :
book . ratings . remove ( book . ratings [ 0 ] )
else :
if len ( book . ratings ) > 0 :
book . ratings . remove ( book . ratings [ 0 ] )
for c in cc :
# retranslate displayed text to language codes
cc_string = " custom_column_ " + str ( c . id )
languages = db . session . query ( db . Languages ) . all ( )
if not c . is_multiple :
input_l = [ ]
if len ( getattr ( book , cc_string ) ) > 0 :
for lang in languages :
cc_db_value = getattr ( book , cc_string ) [ 0 ] . value
try :
lang . name = LC . parse ( lang . lang_code ) . get_language_name ( get_locale ( ) ) . lower ( )
except Exception :
lang . name = _ ( isoLanguages . get ( part3 = lang . lang_code ) . name ) . lower ( )
for inp_lang in input_languages :
if inp_lang == lang . name :
input_l . append ( lang . lang_code )
modify_database_object ( input_l , book . languages , db . Languages , db . session , ' languages ' )
if to_save [ " rating " ] . strip ( ) :
old_rating = False
if len ( book . ratings ) > 0 :
old_rating = book . ratings [ 0 ] . rating
ratingx2 = int ( float ( to_save [ " rating " ] ) * 2 )
if ratingx2 != old_rating :
is_rating = db . session . query ( db . Ratings ) . filter ( db . Ratings . rating == ratingx2 ) . first ( )
if is_rating :
book . ratings . append ( is_rating )
else :
new_rating = db . Ratings ( rating = ratingx2 )
book . ratings . append ( new_rating )
if old_rating :
book . ratings . remove ( book . ratings [ 0 ] )
else :
if len ( book . ratings ) > 0 :
book . ratings . remove ( book . ratings [ 0 ] )
for c in cc :
cc_string = " custom_column_ " + str ( c . id )
if not c . is_multiple :
if len ( getattr ( book , cc_string ) ) > 0 :
cc_db_value = getattr ( book , cc_string ) [ 0 ] . value
else :
cc_db_value = None
if to_save [ cc_string ] . strip ( ) :
if c . datatype == ' bool ' :
if to_save [ cc_string ] == ' None ' :
to_save [ cc_string ] = None
else :
else :
cc_db_value = None
to_save[ cc_string ] = 1 if to_save [ cc_string ] == ' True ' else 0
if to_save [ cc_string ] . strip ( ) :
if to_save [ cc_string ] != cc_db_value :
if c . datatype == ' bool ' :
if c c_db_value is not None :
if to_save [ cc_string ] == ' None ' :
if to_save [ cc_string ] is not None :
to_save [ cc_string ] = None
setattr ( getattr ( book , cc_string ) [ 0 ] , ' value ' , to_save [ cc_string ] )
else :
else :
to_save [ cc_string ] = 1 if to_save [ cc_string ] == ' True ' else 0
del_cc = getattr ( book , cc_string ) [ 0 ]
if to_save [ cc_string ] != cc_db_value :
getattr ( book , cc_string ) . remove ( del_cc )
if cc_db_value is not None :
db . session . delete ( del_cc )
if to_save [ cc_string ] is not None :
setattr ( getattr ( book , cc_string ) [ 0 ] , ' value ' , to_save [ cc_string ] )
else :
del_cc = getattr ( book , cc_string ) [ 0 ]
getattr ( book , cc_string ) . remove ( del_cc )
db . session . delete ( del_cc )
else :
cc_class = db . cc_classes [ c . id ]
new_cc = cc_class ( value = to_save [ cc_string ] , book = book_id )
db . session . add ( new_cc )
elif c . datatype == ' int ' :
if to_save [ cc_string ] == ' None ' :
to_save [ cc_string ] = None
if to_save [ cc_string ] != cc_db_value :
if cc_db_value is not None :
if to_save [ cc_string ] is not None :
setattr ( getattr ( book , cc_string ) [ 0 ] , ' value ' , to_save [ cc_string ] )
else :
del_cc = getattr ( book , cc_string ) [ 0 ]
getattr ( book , cc_string ) . remove ( del_cc )
db . session . delete ( del_cc )
else :
cc_class = db . cc_classes [ c . id ]
new_cc = cc_class ( value = to_save [ cc_string ] , book = book_id )
db . session . add ( new_cc )
else :
else :
if c . datatype == ' rating ' :
cc_class = db . cc_classes [ c . id ]
to_save [ cc_string ] = str ( int ( float ( to_save [ cc_string ] ) * 2 ) )
new_cc = cc_class ( value = to_save [ cc_string ] , book = book_id )
if to_save [ cc_string ] . strip ( ) != cc_db_value :
db . session . add ( new_cc )
if cc_db_value is not None :
elif c . datatype == ' int ' :
# remove old cc_val
if to_save [ cc_string ] == ' None ' :
del_cc = getattr ( book , cc_string ) [ 0 ]
to_save [ cc_string ] = None
getattr ( book , cc_string ) . remove ( del_cc )
if to_save [ cc_string ] != cc_db_value :
if len ( del_cc . books ) == 0 :
if cc_db_value is not None :
db . session . delete ( del_cc )
if to_save [ cc_string ] is not None :
cc_class = db . cc_classes [ c . id ]
setattr ( getattr ( book , cc_string ) [ 0 ] , ' value ' , to_save [ cc_string ] )
new_cc = db . session . query ( cc_class ) . filter (
else :
cc_class . value == to_save [ cc_string ] . strip ( ) ) . first ( )
del_cc = getattr ( book , cc_string ) [ 0 ]
# if no cc val is found add it
getattr ( book , cc_string ) . remove ( del_cc )
if new_cc is None :
db . session . delete ( del_cc )
new_cc = cc_class ( value = to_save [ cc_string ] . strip ( ) )
else :
db . session . add ( new_cc )
cc_class = db . cc_classes [ c . id ]
new_cc = db . session . query ( cc_class ) . filter (
new_cc = cc_class ( value = to_save [ cc_string ] , book = book_id )
cc_class . value == to_save [ cc_string ] . strip ( ) ) . first ( )
db . session . add ( new_cc )
# add cc value to book
getattr ( book , cc_string ) . append ( new_cc )
else :
else :
if c . datatype == ' rating ' :
to_save [ cc_string ] = str ( int ( float ( to_save [ cc_string ] ) * 2 ) )
if to_save [ cc_string ] . strip ( ) != cc_db_value :
if cc_db_value is not None :
if cc_db_value is not None :
# remove old cc_val
# remove old cc_val
del_cc = getattr ( book , cc_string ) [ 0 ]
del_cc = getattr ( book , cc_string ) [ 0 ]
getattr ( book , cc_string ) . remove ( del_cc )
getattr ( book , cc_string ) . remove ( del_cc )
if len ( del_cc . books ) == 0 :
if len ( del_cc . books ) == 0 :
db . session . delete ( del_cc )
db . session . delete ( del_cc )
else :
cc_class = db . cc_classes [ c . id ]
input_tags = to_save [ cc_string ] . split ( ' , ' )
new_cc = db . session . query ( cc_class ) . filter (
input_tags = map ( lambda it : it . strip ( ) , input_tags )
cc_class . value == to_save [ cc_string ] . strip ( ) ) . first ( )
modify_database_object ( input_tags , getattr ( book , cc_string ) , db . cc_classes [ c . id ] , db . session , ' custom ' )
# if no cc val is found add it
db . session . commit ( )
if new_cc is None :
author_names = [ ]
new_cc = cc_class ( value = to_save [ cc_string ] . strip ( ) )
for author in book . authors :
db . session . add ( new_cc )
author_names . append ( author . name )
new_cc = db . session . query ( cc_class ) . filter (
for b in edited_books_id :
cc_class . value == to_save [ cc_string ] . strip ( ) ) . first ( )
if config . config_use_google_drive :
# add cc value to book
helper . update_dir_structure_gdrive ( b )
getattr ( book , cc_string ) . append ( new_cc )
else :
helper . update_dir_stucture ( b , config . config_calibre_dir )
if config . config_use_google_drive :
updateGdriveCalibreFromLocal ( )
if " detail_view " in to_save :
return redirect ( url_for ( ' show_book ' , book_id = book . id ) )
else :
else :
return render_title_template ( ' book_edit.html ' , book = book , authors = author_names , cc = cc ,
if cc_db_value is not None :
title = _ ( u " edit metadata " ) )
# remove old cc_val
del_cc = getattr ( book , cc_string ) [ 0 ]
getattr ( book , cc_string ) . remove ( del_cc )
if len ( del_cc . books ) == 0 :
db . session . delete ( del_cc )
else :
input_tags = to_save [ cc_string ] . split ( ' , ' )
input_tags = map ( lambda it : it . strip ( ) , input_tags )
modify_database_object ( input_tags , getattr ( book , cc_string ) , db . cc_classes [ c . id ] , db . session , ' custom ' )
db . session . commit ( )
author_names = [ ]
for author in book . authors :
author_names . append ( author . name )
for b in edited_books_id :
if config . config_use_google_drive :
helper . update_dir_structure_gdrive ( b )
else :
helper . update_dir_stucture ( b , config . config_calibre_dir )
if config . config_use_google_drive :
updateGdriveCalibreFromLocal ( )
if " detail_view " in to_save :
return redirect ( url_for ( ' show_book ' , book_id = book . id ) )
else :
return render_title_template ( ' book_edit.html ' , book = book , authors = author_names , cc = cc ,
title = _ ( u " edit metadata " ) )
@app.route ( " /upload " , methods = [ " GET " , " POST " ] )
@app.route ( " /upload " , methods = [ " GET " , " POST " ] )