Merge remote-tracking branch 'adv/edit-publish-date'
This commit is contained in:
commit
626e2e393e
|
@ -230,6 +230,8 @@ class Data(Base):
|
||||||
class Books(Base):
|
class Books(Base):
|
||||||
__tablename__ = 'books'
|
__tablename__ = 'books'
|
||||||
|
|
||||||
|
DEFAULT_PUBDATE = "0101-01-01 00:00:00+00:00"
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
title = Column(String)
|
title = Column(String)
|
||||||
sort = Column(String)
|
sort = Column(String)
|
||||||
|
|
1
cps/static/css/libs/bootstrap-datepicker3.css.map
vendored
Normal file
1
cps/static/css/libs/bootstrap-datepicker3.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
cps/static/css/libs/bootstrap-datepicker3.min.css
vendored
Normal file
7
cps/static/css/libs/bootstrap-datepicker3.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,31 @@
|
||||||
/**
|
/**
|
||||||
* Created by SpeedProg on 05.04.2015.
|
* Created by SpeedProg on 05.04.2015.
|
||||||
*/
|
*/
|
||||||
/* global Bloodhound */
|
/* global Bloodhound, language, Modernizr, tinymce */
|
||||||
|
|
||||||
|
tinymce.init({
|
||||||
|
selector: "#description",
|
||||||
|
branding: false,
|
||||||
|
menubar: "edit view format",
|
||||||
|
language
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!Modernizr.inputtypes.date) {
|
||||||
|
$("#pubdate").datepicker({
|
||||||
|
format: "yyyy-mm-dd",
|
||||||
|
language
|
||||||
|
}).on("change", function () {
|
||||||
|
// Show localized date over top of the standard YYYY-MM-DD date
|
||||||
|
let pubDate;
|
||||||
|
const results = /(\d{4})[-\/\\](\d{1,2})[-\/\\](\d{1,2})/.exec(this.value); // YYYY-MM-DD
|
||||||
|
if (results) {
|
||||||
|
pubDate = new Date(results[1], parseInt(results[2], 10)-1, results[3]) || new Date(this.value);
|
||||||
|
}
|
||||||
|
$("#fake_pubdate")
|
||||||
|
.val(pubDate.toLocaleDateString(language))
|
||||||
|
.removeClass("hidden");
|
||||||
|
}).trigger("change");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Takes a prefix, query typeahead callback, Bloodhound typeahead adapter
|
Takes a prefix, query typeahead callback, Bloodhound typeahead adapter
|
||||||
|
|
8
cps/static/js/libs/bootstrap-datepicker/bootstrap-datepicker.min.js
vendored
Normal file
8
cps/static/js/libs/bootstrap-datepicker/bootstrap-datepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.de.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.de.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["Son","Mon","Die","Mit","Don","Fre","Sam"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",monthsTitle:"Monate",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery);
|
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.es.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.es.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates.es={days:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],daysShort:["Dom","Lun","Mar","Mié","Jue","Vie","Sáb"],daysMin:["Do","Lu","Ma","Mi","Ju","Vi","Sa"],months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthsShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],today:"Hoy",monthsTitle:"Meses",clear:"Borrar",weekStart:1,format:"dd/mm/yyyy"}}(jQuery);
|
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.fr.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.fr.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"}}(jQuery);
|
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.nl.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.nl.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates.nl={days:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],daysShort:["zo","ma","di","wo","do","vr","za"],daysMin:["zo","ma","di","wo","do","vr","za"],months:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthsShort:["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec"],today:"Vandaag",monthsTitle:"Maanden",clear:"Wissen",weekStart:1,format:"dd-mm-yyyy"}}(jQuery);
|
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.pl.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.pl.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates.pl={days:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],daysShort:["Niedz.","Pon.","Wt.","Śr.","Czw.","Piąt.","Sob."],daysMin:["Ndz.","Pn.","Wt.","Śr.","Czw.","Pt.","Sob."],months:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthsShort:["Sty.","Lut.","Mar.","Kwi.","Maj","Cze.","Lip.","Sie.","Wrz.","Paź.","Lis.","Gru."],today:"Dzisiaj",weekStart:1,clear:"Wyczyść",format:"dd.mm.yyyy"}}(jQuery);
|
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.ru.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.ru.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"}}(jQuery);
|
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(a){a.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今日",clear:"清除",format:"yyyy年mm月dd日",titleFormat:"yyyy年mm月",weekStart:1}}(jQuery);
|
|
@ -35,23 +35,30 @@
|
||||||
<input type="text" class="form-control typeahead" name="tags" id="tags" value="{% for tag in book.tags %}{{tag.name.strip()}}, {% endfor %}">
|
<input type="text" class="form-control typeahead" name="tags" id="tags" value="{% for tag in book.tags %}{{tag.name.strip()}}, {% endfor %}">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="series">{{_('Series')}}</label>
|
<label for="series">{{_('Series')}}</label>
|
||||||
<input type="text" class="form-control typeahead" name="series" id="series" value="{% if book.series %}{{book.series[0].name}}{% endif %}">
|
<input type="text" class="form-control typeahead" name="series" id="series" value="{% if book.series %}{{book.series[0].name}}{% endif %}">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="series_index">{{_('Series id')}}</label>
|
<label for="series_index">{{_('Series id')}}</label>
|
||||||
<input type="text" class="form-control" name="series_index" id="series_index" value="{{book.series_index}}">
|
<input type="text" class="form-control" name="series_index" id="series_index" value="{{book.series_index}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="rating">{{_('Rating')}}</label>
|
<label for="rating">{{_('Rating')}}</label>
|
||||||
<input type="number" name="rating" id="rating" class="rating input-lg" data-clearable="" value="{% if book.ratings %}{{(book.ratings[0].rating / 2)|int}}{% endif %}">
|
<input type="number" name="rating" id="rating" class="rating input-lg" data-clearable="" value="{% if book.ratings %}{{(book.ratings[0].rating / 2)|int}}{% endif %}">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cover_url">{{_('Cover URL (jpg)')}}</label>
|
<label for="cover_url">{{_('Cover URL (jpg)')}}</label>
|
||||||
<input type="text" class="form-control" name="cover_url" id="cover_url" value="">
|
<input type="text" class="form-control" name="cover_url" id="cover_url" value="">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pubdate">{{_('Publishing date')}}</label>
|
||||||
|
<div style="position: relative">
|
||||||
|
<input type="date" class="form-control" name="pubdate" id="pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdateinput}}{% endif %}">
|
||||||
|
<input type="text" class="form-control fake-input hidden" id="fake_pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdate}}{% endif %}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="languages">{{_('Language')}}</label>
|
<label for="languages">{{_('Language')}}</label>
|
||||||
<input type="text" class="form-control typeahead" name="languages" id="languages" value="{% for language in book.languages %}{{language.language_name.strip()}}, {% endfor %}">
|
<input type="text" class="form-control typeahead" name="languages" id="languages" value="{% for language in book.languages %}{{language.language_name.strip()}}, {% endfor %}">
|
||||||
|
@ -183,21 +190,19 @@
|
||||||
'description': {{_('Description')|safe|tojson}},
|
'description': {{_('Description')|safe|tojson}},
|
||||||
'source': {{_('Source')|safe|tojson}},
|
'source': {{_('Source')|safe|tojson}},
|
||||||
};
|
};
|
||||||
|
var language = '{{ g.user.locale }}';
|
||||||
</script>
|
</script>
|
||||||
<script src="{{ url_for('static', filename='js/libs/typeahead.bundle.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/typeahead.bundle.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/edit_books.js') }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='js/libs/bootstrap-rating-input.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-rating-input.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/get_meta.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/get_meta.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/libs/tinymce/tinymce.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/tinymce/tinymce.min.js') }}"></script>
|
||||||
<script type="text/javascript">
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-datepicker/bootstrap-datepicker.min.js') }}"></script>
|
||||||
tinymce.init({
|
{% if not g.user.locale == 'en' %}
|
||||||
selector: '#description',
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.' + g.user.locale + '.min.js') }}" charset="UTF-8"></script>
|
||||||
branding: false,
|
{% endif %}
|
||||||
menubar: 'edit view format',
|
<script src="{{ url_for('static', filename='js/edit_books.js') }}"></script>
|
||||||
language: '{{ g.user.locale }}'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block header %}
|
{% block header %}
|
||||||
<link href="{{ url_for('static', filename='css/libs/typeahead.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/libs/typeahead.css') }}" rel="stylesheet" media="screen">
|
||||||
|
<link href="{{ url_for('static', filename='css/libs/bootstrap-datepicker3.min.css') }}" rel="stylesheet" media="screen">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
369
cps/web.py
369
cps/web.py
|
@ -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(
|
||||||
|
@ -2689,195 +2697,208 @@ def edit_book(book_id):
|
||||||
lang_filter = True
|
lang_filter = True
|
||||||
book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(lang_filter).first()
|
book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(lang_filter).first()
|
||||||
author_names = []
|
author_names = []
|
||||||
if book:
|
|
||||||
for index in range(0, len(book.languages)):
|
# Book not found
|
||||||
try:
|
if not book:
|
||||||
book.languages[index].language_name = LC.parse(book.languages[index].lang_code).get_language_name(
|
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
|
||||||
get_locale())
|
return redirect(url_for("index"))
|
||||||
except Exception:
|
|
||||||
book.languages[index].language_name = _(isoLanguages.get(part3=book.languages[index].lang_code).name)
|
for index in range(0, len(book.languages)):
|
||||||
for author in book.authors:
|
try:
|
||||||
author_names.append(author.name)
|
book.languages[index].language_name = LC.parse(book.languages[index].lang_code).get_language_name(
|
||||||
if request.method == 'POST':
|
get_locale())
|
||||||
edited_books_id = set()
|
except Exception:
|
||||||
to_save = request.form.to_dict()
|
book.languages[index].language_name = _(isoLanguages.get(part3=book.languages[index].lang_code).name)
|
||||||
if book.title != to_save["book_title"]:
|
for author in book.authors:
|
||||||
book.title = to_save["book_title"]
|
author_names.append(author.name)
|
||||||
edited_books_id.add(book.id)
|
|
||||||
input_authors = to_save["author_name"].split('&')
|
# Show form
|
||||||
input_authors = map(lambda it: it.strip(), input_authors)
|
if request.method != 'POST':
|
||||||
# we have all author names now
|
return render_title_template('book_edit.html', book=book, authors=author_names, cc=cc,
|
||||||
if input_authors == ['']:
|
title=_(u"edit metadata"))
|
||||||
input_authors = [_(u'unknown')] # prevent empty Author
|
|
||||||
if book.authors:
|
# Update book
|
||||||
author0_before_edit = book.authors[0].name
|
edited_books_id = set()
|
||||||
|
to_save = request.form.to_dict()
|
||||||
|
if book.title != to_save["book_title"]:
|
||||||
|
book.title = to_save["book_title"]
|
||||||
|
edited_books_id.add(book.id)
|
||||||
|
input_authors = to_save["author_name"].split('&')
|
||||||
|
input_authors = map(lambda it: it.strip(), input_authors)
|
||||||
|
# we have all author names now
|
||||||
|
if input_authors == ['']:
|
||||||
|
input_authors = [_(u'unknown')] # prevent empty Author
|
||||||
|
if book.authors:
|
||||||
|
author0_before_edit = book.authors[0].name
|
||||||
|
else:
|
||||||
|
author0_before_edit = db.Authors(_(u'unknown'),'',0)
|
||||||
|
modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author')
|
||||||
|
if book.authors:
|
||||||
|
if author0_before_edit != book.authors[0].name:
|
||||||
|
edited_books_id.add(book.id)
|
||||||
|
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":
|
||||||
|
img = requests.get(to_save["cover_url"])
|
||||||
|
if config.config_use_google_drive:
|
||||||
|
tmpDir = tempfile.gettempdir()
|
||||||
|
f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb")
|
||||||
|
f.write(img.content)
|
||||||
|
f.close()
|
||||||
|
gdriveutils.uploadFileToEbooksFolder(Gdrive.Instance().drive, os.path.join(book.path, 'cover.jpg'), os.path.join(tmpDir, f.name))
|
||||||
|
else:
|
||||||
|
f = open(os.path.join(config.config_calibre_dir, book.path, "cover.jpg"), "wb")
|
||||||
|
f.write(img.content)
|
||||||
|
f.close()
|
||||||
|
book.has_cover = 1
|
||||||
|
|
||||||
|
if book.series_index != to_save["series_index"]:
|
||||||
|
book.series_index = to_save["series_index"]
|
||||||
|
|
||||||
|
if len(book.comments):
|
||||||
|
book.comments[0].text = to_save["description"]
|
||||||
|
else:
|
||||||
|
book.comments.append(db.Comments(text=to_save["description"], book=book.id))
|
||||||
|
|
||||||
|
input_tags = to_save["tags"].split(',')
|
||||||
|
input_tags = map(lambda it: it.strip(), input_tags)
|
||||||
|
modify_database_object(input_tags, book.tags, db.Tags, db.session, 'tags')
|
||||||
|
|
||||||
|
input_series = [to_save["series"].strip()]
|
||||||
|
input_series = [x for x in input_series if x != '']
|
||||||
|
modify_database_object(input_series, book.series, db.Series, db.session, 'series')
|
||||||
|
|
||||||
|
input_languages = to_save["languages"].split(',')
|
||||||
|
input_languages = map(lambda it: it.strip().lower(), input_languages)
|
||||||
|
|
||||||
|
if to_save["pubdate"]:
|
||||||
|
try:
|
||||||
|
book.pubdate = datetime.datetime.strptime(to_save["pubdate"], "%Y-%m-%d")
|
||||||
|
except ValueError:
|
||||||
|
book.pubdate = db.Books.DEFAULT_PUBDATE
|
||||||
|
else:
|
||||||
|
book.pubdate = db.Books.DEFAULT_PUBDATE
|
||||||
|
|
||||||
|
# retranslate displayed text to language codes
|
||||||
|
languages = db.session.query(db.Languages).all()
|
||||||
|
input_l = []
|
||||||
|
for lang in languages:
|
||||||
|
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:
|
else:
|
||||||
author0_before_edit = db.Authors(_(u'unknown'),'',0)
|
new_rating = db.Ratings(rating=ratingx2)
|
||||||
modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author')
|
book.ratings.append(new_rating)
|
||||||
if book.authors:
|
if old_rating:
|
||||||
if author0_before_edit != book.authors[0].name:
|
book.ratings.remove(book.ratings[0])
|
||||||
edited_books_id.add(book.id)
|
else:
|
||||||
book.author_sort = helper.get_sorted_author(input_authors[0])
|
if len(book.ratings) > 0:
|
||||||
|
book.ratings.remove(book.ratings[0])
|
||||||
|
|
||||||
if to_save["cover_url"] and os.path.splitext(to_save["cover_url"])[1].lower() == ".jpg":
|
for c in cc:
|
||||||
img = requests.get(to_save["cover_url"])
|
cc_string = "custom_column_" + str(c.id)
|
||||||
if config.config_use_google_drive:
|
if not c.is_multiple:
|
||||||
tmpDir = tempfile.gettempdir()
|
if len(getattr(book, cc_string)) > 0:
|
||||||
f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb")
|
cc_db_value = getattr(book, cc_string)[0].value
|
||||||
f.write(img.content)
|
|
||||||
f.close()
|
|
||||||
gdriveutils.uploadFileToEbooksFolder(Gdrive.Instance().drive, os.path.join(book.path, 'cover.jpg'), os.path.join(tmpDir, f.name))
|
|
||||||
else:
|
|
||||||
f = open(os.path.join(config.config_calibre_dir, book.path, "cover.jpg"), "wb")
|
|
||||||
f.write(img.content)
|
|
||||||
f.close()
|
|
||||||
book.has_cover = 1
|
|
||||||
|
|
||||||
if book.series_index != to_save["series_index"]:
|
|
||||||
book.series_index = to_save["series_index"]
|
|
||||||
|
|
||||||
if len(book.comments):
|
|
||||||
book.comments[0].text = to_save["description"]
|
|
||||||
else:
|
else:
|
||||||
book.comments.append(db.Comments(text=to_save["description"], book=book.id))
|
cc_db_value = None
|
||||||
|
if to_save[cc_string].strip():
|
||||||
input_tags = to_save["tags"].split(',')
|
if c.datatype == 'bool':
|
||||||
input_tags = map(lambda it: it.strip(), input_tags)
|
if to_save[cc_string] == 'None':
|
||||||
modify_database_object(input_tags, book.tags, db.Tags, db.session, 'tags')
|
to_save[cc_string] = None
|
||||||
|
|
||||||
input_series = [to_save["series"].strip()]
|
|
||||||
input_series = [x for x in input_series if x != '']
|
|
||||||
modify_database_object(input_series, book.series, db.Series, db.session, 'series')
|
|
||||||
|
|
||||||
input_languages = to_save["languages"].split(',')
|
|
||||||
input_languages = map(lambda it: it.strip().lower(), input_languages)
|
|
||||||
|
|
||||||
# retranslate displayed text to language codes
|
|
||||||
languages = db.session.query(db.Languages).all()
|
|
||||||
input_l = []
|
|
||||||
for lang in languages:
|
|
||||||
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:
|
else:
|
||||||
new_rating = db.Ratings(rating=ratingx2)
|
to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0
|
||||||
book.ratings.append(new_rating)
|
if to_save[cc_string] != cc_db_value:
|
||||||
if old_rating:
|
if cc_db_value is not None:
|
||||||
book.ratings.remove(book.ratings[0])
|
if to_save[cc_string] is not None:
|
||||||
else:
|
setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string])
|
||||||
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:
|
||||||
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:
|
else:
|
||||||
return render_title_template('book_edit.html', book=book, authors=author_names, cc=cc,
|
input_tags = to_save[cc_string].split(',')
|
||||||
title=_(u"edit metadata"))
|
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:
|
else:
|
||||||
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
|
return render_title_template('book_edit.html', book=book, authors=author_names, cc=cc,
|
||||||
return redirect(url_for("index"))
|
title=_(u"edit metadata"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/upload", methods=["GET", "POST"])
|
@app.route("/upload", methods=["GET", "POST"])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user