diff --git a/cps.py b/cps.py index 180be500..523246b2 100755 --- a/cps.py +++ b/cps.py @@ -22,7 +22,7 @@ except ImportError: if __name__ == '__main__': if web.ub.DEVELOPMENT: - web.app.run(host="0.0.0.0", port=web.ub.config.config_port, debug=True) + web.app.run(port=web.ub.config.config_port, debug=True) else: if gevent_present: web.app.logger.info('Attempting to start gevent') diff --git a/cps/helper.py b/cps/helper.py index 7f561319..71cacd74 100755 --- a/cps/helper.py +++ b/cps/helper.py @@ -13,6 +13,7 @@ import os import traceback import re import unicodedata + try: from StringIO import StringIO from email.MIMEBase import MIMEBase diff --git a/cps/static/js/edit_books.js b/cps/static/js/edit_books.js index 07d25148..810869a5 100644 --- a/cps/static/js/edit_books.js +++ b/cps/static/js/edit_books.js @@ -8,7 +8,7 @@ Takes a prefix, query typeahead callback, Bloodhound typeahead adapter and returns the completions it gets from the bloodhound engine prefixed. */ -function prefixed_source(prefix, query, cb, bhAdapter) { +function prefixedSource(prefix, query, cb, bhAdapter) { bhAdapter(query, function(retArray){ var matches = []; for (var i = 0; i < retArray.length; i++) { @@ -18,7 +18,7 @@ function prefixed_source(prefix, query, cb, bhAdapter) { cb(matches); }); } -function get_path(){ +function getPath(){ var jsFileLocation = $("script[src*=edit_books]").attr("src"); // the js file path jsFileLocation = jsFileLocation.replace("/static/js/edit_books.js", ''); // the js folder path return jsFileLocation; @@ -31,7 +31,7 @@ var authors = new Bloodhound({ }, queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { - url: get_path()+"/get_authors_json?q=%QUERY" + url: getPath()+"/get_authors_json?q=%QUERY" } }); @@ -44,7 +44,7 @@ var series = new Bloodhound({ return [query]; }, remote: { - url: get_path()+"/get_series_json?q=", + url: getPath()+"/get_series_json?q=", replace: function(url, query) { return url+encodeURIComponent(query); } @@ -63,7 +63,7 @@ var tags = new Bloodhound({ return tokens; }, remote: { - url: get_path()+"/get_tags_json?q=%QUERY" + url: getPath()+"/get_tags_json?q=%QUERY" } }); @@ -76,10 +76,9 @@ var languages = new Bloodhound({ return [query]; }, remote: { - url: get_path()+"/get_languages_json?q=", + url: getPath()+"/get_languages_json?q=", replace: function(url, query) { - url_query = url+encodeURIComponent(query); - return url_query; + return url+encodeURIComponent(query); } } }); @@ -101,7 +100,7 @@ function sourceSplit(query, cb, split, source) { for (var i = 0; i < tokens.length; i++) { prefix += tokens[i].trim() + newSplit; } - prefixed_source(prefix, currentSource, cb, bhAdapter); + prefixedSource(prefix, currentSource, cb, bhAdapter); } var promiseAuthors = authors.initialize(); @@ -130,7 +129,7 @@ var promiseSeries = series.initialize(); displayKey: "name", source: series.ttAdapter() } - ) + ); }); var promiseTags = tags.initialize(); @@ -165,7 +164,7 @@ var promiseLanguages = languages.initialize(); $("form").on("change input typeahead:selected", function(data){ var form = $("form").serialize(); - $.getJSON( get_path()+"/get_matching_tags", form, function( data ) { + $.getJSON( getPath()+"/get_matching_tags", form, function( data ) { $(".tags_click").each(function() { if ($.inArray(parseInt($(this).children("input").first().val(), 10), data.tags) === -1 ) { if (!($(this).hasClass("active"))) { diff --git a/cps/static/js/get_meta.js b/cps/static/js/get_meta.js index 583abea2..316d2651 100644 --- a/cps/static/js/get_meta.js +++ b/cps/static/js/get_meta.js @@ -9,36 +9,95 @@ $(document).ready(function () { var msg = i18nMsg; var douban = "https://api.douban.com"; var dbSearch = "/v2/book/search"; - var db_get_info = "/v2/book/"; - var db_get_info_by_isbn = "/v2/book/isbn/ "; + // var dbGetInfo = "/v2/book/"; + // var db_get_info_by_isbn = "/v2/book/isbn/ "; var dbDone = false; var google = "https://www.googleapis.com/"; - var gg_search = "/books/v1/volumes"; - var gg_get_info = "/books/v1/volumes/"; - var gg_done = false; + var ggSearch = "/books/v1/volumes"; + // var gg_get_info = "/books/v1/volumes/"; + var ggDone = false; - var db_results = []; - var gg_results = []; - var show_flag = 0; - String.prototype.replaceAll = function (s1, s2) {   + var dbResults = []; + var ggResults = []; + var showFlag = 0; + String.prototype.replaceAll = function (s1, s2) { return this.replace(new RegExp(s1, "gm"), s2); }; - function gg_search_book (title) { + function showResult () { + showFlag++; + if (showFlag === 1) { + $("#meta-info").html(''); + } + if (ggDone && dbDone) { + if (!ggResults && !dbResults) { + $("#meta-info").html('

'+ msg.no_result +"

"); + return; + } + } + if (ggDone && ggResults.length > 0) { + for (var i = 0; i < ggResults.length; i++) { + var book = ggResults[i]; + var bookCover; + if (book.volumeInfo.imageLinks) { + bookCover = book.volumeInfo.imageLinks.thumbnail; + } else { + bookCover = "/static/generic_cover.jpg"; + } + var bookHtml = '
  • ' + + 'Cover' + + '
    ' + + '

    ' + book.volumeInfo.title + '

    ' + + "

    "+ msg.author +":" + book.volumeInfo.authors + "

    " + + "

    "+ msg.publisher + ":" + book.volumeInfo.publisher + "

    " + + "

    "+ msg.description + ":" + book.volumeInfo.description + "

    " + + "

    "+ msg.source + ':Google Books

    ' + + "
    " + + "
  • "; + $("#book-list").append(bookHtml); + } + ggDone = false; + } + if (dbDone && dbResults.length > 0) { + for (var i = 0; i < dbResults.length; i++) { + var book = dbResults[i]; + var bookHtml = '
  • ' + + 'Cover' + + '
    ' + + '

    ' + book.title + "

    " + + "

    " + msg.author + ":" + book.author + "

    " + + "

    " + msg.publisher + ":" + book.publisher + "

    " + + "

    " + msg.description + ":" + book.summary + "

    " + + "

    " + msg.source + ':Douban Books

    ' + + "
    " + + "
  • "; + $("#book-list").append(bookHtml); + } + dbDone = false; + } + } + + function ggSearchBook (title) { title = title.replaceAll(/\s+/, "+"); - var url = google + gg_search + "?q=" + title; + var url = google + ggSearch + "?q=" + title; $.ajax({ url, type: "GET", dataType: "jsonp", jsonp: "callback", success: function (data) { - gg_results = data.items; + ggResults = data.items; }, complete: function () { - gg_done = true; - show_result(); + ggDone = true; + showResult(); } }); } @@ -47,7 +106,7 @@ $(document).ready(function () { var meta; var tags; if (source === "google") { - meta = gg_results[id]; + meta = ggResults[id]; $("#description").val(meta.volumeInfo.description); $("#bookAuthor").val(meta.volumeInfo.authors.join(" & ")); $("#book_title").val(meta.volumeInfo.title); @@ -61,13 +120,13 @@ $(document).ready(function () { return; } if (source === "douban") { - meta = db_results[id]; + meta = dbResults[id]; $("#description").val(meta.summary); $("#bookAuthor").val(meta.author.join(" & ")); $("#book_title").val(meta.title); - tags = ''; + tags = ""; for (var i = 0; i < meta.tags.length; i++) { - tags = tags + meta.tags[i].title + ','; + tags = tags + meta.tags[i].title + ","; } $("#tags").val(tags); $("#rating").val(Math.round(meta.rating.average / 2)); @@ -75,91 +134,32 @@ $(document).ready(function () { } } - function do_search (keyword) { - show_flag = 0; + function doSearch (keyword) { + showFlag = 0; $("#meta-info").text(msg.loading); - var keyword = $("#keyword").val(); + // var keyword = $("#keyword").val(); if (keyword) { - db_search_book(keyword); - gg_search_book(keyword); + dbSearchBook(keyword); + ggSearchBook(keyword); } } - function show_result () { - show_flag++; - if (show_flag == 1) { - $('#meta-info').html(''); - } - if (gg_done && dbDone) { - if (!gg_results && !db_results) { - $('#meta-info').html('

    '+ msg.no_result +'

    '); - return; - } - } - if (gg_done && gg_results.length > 0) { - for (var i = 0; i < gg_results.length; i++) { - var book = gg_results[i]; - var book_cover; - if (book.volumeInfo.imageLinks) { - book_cover = book.volumeInfo.imageLinks.thumbnail; - } else { - book_cover = '/static/generic_cover.jpg'; - } - var book_html = '
  • ' + - 'Cover' + - '
    ' + - '

    ' + book.volumeInfo.title + '

    ' + - '

    '+ msg.author +':' + book.volumeInfo.authors + '

    ' + - '

    '+ msg.publisher + ':' + book.volumeInfo.publisher + '

    ' + - '

    '+ msg.description + ':' + book.volumeInfo.description + '

    ' + - '

    '+ msg.source + ':Google Books

    ' + - '
    ' + - '
  • '; - $("#book-list").append(book_html); - } - gg_done = false; - } - if (dbDone && db_results.length > 0) { - for (var i = 0; i < db_results.length; i++) { - var book = db_results[i]; - var book_html = '
  • ' + - 'Cover' + - '
    ' + - '

    ' + book.title + '

    ' + - '

    ' + msg.author + ':' + book.author + '

    ' + - '

    ' + msg.publisher + ':' + book.publisher + '

    ' + - '

    ' + msg.description + ':' + book.summary + '

    ' + - '

    ' + msg.source + ':Douban Books

    ' + - '
    ' + - "
  • "; - $("#book-list").append(book_html); - } - dbDone = false; - } - } - - db_search_book = function (title) { - var url = douban + dbSearch + '?q=' + title + '&fields=all&count=10'; + function dbSearchBook (title) { + var url = douban + dbSearch + "?q=" + title + "&fields=all&count=10"; $.ajax({ url: url, type: "GET", dataType: "jsonp", - jsonp: 'callback', + jsonp: "callback", success: function (data) { - db_results = data.books; + dbResults = data.books; }, error: function () { - $('#meta-info').html('

    '+ msg.search_error+'!

    '); + $("#meta-info").html('

    '+ msg.search_error+"!

    "); }, complete: function () { dbDone = true; - show_result(); + showResult(); } }); } @@ -167,15 +167,15 @@ $(document).ready(function () { $("#do-search").click(function () { var keyword = $("#keyword").val(); if (keyword) { - do_search(keyword); + doSearch(keyword); } }); $("#get_meta").click(function () { - var book_title = $("#book_title").val(); - if (book_title) { - $("#keyword").val(book_title); - do_search(book_title); + var bookTitle = $("#book_title").val(); + if (bookTitle) { + $("#keyword").val(bookTitle); + doSearch(bookTitle); } }); diff --git a/cps/static/js/main.js b/cps/static/js/main.js index 8494973f..10e4dc08 100644 --- a/cps/static/js/main.js +++ b/cps/static/js/main.js @@ -49,13 +49,13 @@ $(function() { }); }); $("#check_for_update").click(function() { - var button_text = $("#check_for_update").html(); + var buttonText = $("#check_for_update").html(); $("#check_for_update").html("..."); $.ajax({ dataType: "json", url: window.location.pathname+"/../../get_update_status", success: function(data) { - $("#check_for_update").html(button_text); + $("#check_for_update").html(buttonText); if (data.status === true) { $("#check_for_update").addClass("hidden"); $("#perform_update").removeClass("hidden"); @@ -67,7 +67,7 @@ $(function() { }); $("#restart_database").click(function() { $.ajax({ - dataType: 'json', + dataType: "json", url: window.location.pathname+"/../../shutdown", data: {"parameter":2} }); @@ -76,7 +76,7 @@ $(function() { $("#spinner2").show(); $.ajax({ type: "POST", - dataType: 'json', + dataType: "json", data: { start: "True"}, url: window.location.pathname+"/../../get_updater_status", success: function(data) { @@ -94,10 +94,10 @@ $(function() { function updateTimer() { $.ajax({ - dataType: 'json', + dataType: "json", url: window.location.pathname+"/../../get_updater_status", success: function(data) { - console.log(data.status); + // console.log(data.status); $("#UpdateprogressDialog #Updatecontent").html(updateText[data.status]); if (data.status >6){ clearInterval(updateTimerID); diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index 165512c7..b94ddbb2 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -106,7 +106,7 @@ {{_('Get metadata')}} - {{_('Back')}} + {{_('Back')}} {% endif %} diff --git a/cps/templates/detail.html b/cps/templates/detail.html index e0a7ef01..44fc8f55 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -15,7 +15,7 @@

    {{entry.title}}

    {% for author in entry.authors %} - {{author.name}} + {{author.name}} {% if not loop.last %} & {% endif %} @@ -37,7 +37,7 @@ {% endif %} {% if entry.series|length > 0 %} -

    {{_('Book')}} {{entry.series_index}} {{_('of')}} {{entry.series[0].name}}

    +

    {{_('Book')}} {{entry.series_index}} {{_('of')}} {{entry.series[0].name}}

    {% endif %} {% if entry.languages.__len__() > 0 %} @@ -65,7 +65,7 @@ {% for tag in entry.tags %} - {{tag.name}} + {{tag.name}} {%endfor%}

    @@ -110,7 +110,7 @@ {% if not g.user.is_anonymous() %}

    -
    +
    @@ -136,7 +136,7 @@
    @@ -154,7 +154,7 @@ diff --git a/cps/templates/discover.html b/cps/templates/discover.html index c340cfc0..32f89a47 100644 --- a/cps/templates/discover.html +++ b/cps/templates/discover.html @@ -8,14 +8,14 @@
    {% if entry.has_cover is defined %} - + {% endif %}

    {{entry.title|shortentitle}}

    -

    {{entry.authors[0].name}}

    +

    {{entry.authors[0].name}}

    {% if entry.ratings.__len__() > 0 %}
    {% for number in range((entry.ratings[0].rating/2)|int(2)) %} diff --git a/cps/templates/feed.xml b/cps/templates/feed.xml index 8d57cfb3..65471fde 100644 --- a/cps/templates/feed.xml +++ b/cps/templates/feed.xml @@ -56,7 +56,7 @@ {% endif %} {% for format in entry.data %} - {% endfor %} @@ -65,9 +65,9 @@ {% for entry in listelements %} {{entry.name}} - {{ url_for(folder, id=entry.id) }} - - + {{ url_for(folder, book_id=entry.id) }} + + {% endfor %} diff --git a/cps/templates/index.html b/cps/templates/index.html index 744fea89..768c28bd 100755 --- a/cps/templates/index.html +++ b/cps/templates/index.html @@ -8,7 +8,7 @@ {% for entry in random %}

    {{entry.title|shortentitle}}

    -

    {{entry.authors[0].name}}

    +

    {{entry.authors[0].name}}

    {% if entry.ratings.__len__() > 0 %}
    {% for number in range((entry.ratings[0].rating/2)|int(2)) %} @@ -44,7 +44,7 @@ {% for entry in entries %}
    - + {% if entry.has_cover %} {% else %} @@ -56,7 +56,7 @@

    {{entry.title|shortentitle}}

    {% for author in entry.authors %} - {{author.name}} + {{author.name}} {% if not loop.last %} & {% endif %} diff --git a/cps/templates/json.txt b/cps/templates/json.txt index 9e86c41d..be69bf7c 100644 --- a/cps/templates/json.txt +++ b/cps/templates/json.txt @@ -36,7 +36,7 @@ "timestamp": "{{entry.timestamp}}", "thumbnail": "{{url_for('feed_get_cover', book_id=entry.id)}}", "main_format": { - "{{entry.data[0].format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, format=entry.data[0].format|lower)}}" + "{{entry.data[0].format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, book_format=entry.data[0].format|lower)}}" }, "rating":{% if entry.ratings.__len__() > 0 %} "{{entry.ratings[0].rating}}.0"{% else %}0.0{% endif %}, "authors": [ @@ -47,7 +47,7 @@ "other_formats": { {% if entry.data.__len__() > 1 %} {% for format in entry.data[1:] %} - "{{format.format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, format=format.format|lower)}}"{% if not loop.last %},{% endif %} + "{{format.format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, book_format=format.format|lower)}}"{% if not loop.last %},{% endif %} {% endfor %} {% endif %} }, "title_sort": "{{entry.sort}}" diff --git a/cps/templates/list.html b/cps/templates/list.html index 0a63b139..55d07e82 100644 --- a/cps/templates/list.html +++ b/cps/templates/list.html @@ -10,7 +10,7 @@ {% endif %}

    {{entry.count}}
    - +
    {% endfor %}
    diff --git a/cps/templates/search.html b/cps/templates/search.html index 79c86b84..7e82c1fc 100644 --- a/cps/templates/search.html +++ b/cps/templates/search.html @@ -15,7 +15,7 @@
    {% if entry.has_cover is defined %} - + {% endif %} @@ -24,7 +24,7 @@

    {{entry.title|shortentitle}}

    {% for author in entry.authors %} - {{author.name}} + {{author.name}} {% if not loop.last %} & {% endif %} diff --git a/cps/templates/shelf.html b/cps/templates/shelf.html index 1d1e91d2..b6e5d854 100644 --- a/cps/templates/shelf.html +++ b/cps/templates/shelf.html @@ -15,14 +15,14 @@

    {% if entry.has_cover is defined %} - + {% endif %}

    {{entry.title|shortentitle}}

    -

    {{entry.authors[0].name}}

    +

    {{entry.authors[0].name}}

    {% if entry.ratings.__len__() > 0 %}
    {% for number in range((entry.ratings[0].rating/2)|int(2)) %} diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html index 6da290bd..ac2386a8 100644 --- a/cps/templates/user_edit.html +++ b/cps/templates/user_edit.html @@ -131,7 +131,7 @@

    {{_('Recent Downloads')}}

    {% for entry in downloads %} diff --git a/cps/ub.py b/cps/ub.py index 49a182b9..858501a6 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -93,9 +93,11 @@ class UserBase: else: return False + @staticmethod def is_active(self): return True + @staticmethod def is_anonymous(self): return False @@ -526,7 +528,6 @@ def create_admin_user(): session.commit() except Exception: session.rollback() - pass # Open session for database connection diff --git a/cps/web.py b/cps/web.py index a0492652..a436197c 100755 --- a/cps/web.py +++ b/cps/web.py @@ -403,10 +403,10 @@ def timestamptodate(date, fmt=None): ) native = date.replace(tzinfo=None) if fmt: - format=fmt + time_format=fmt else: - format='%d %m %Y - %H:%S' - return native.strftime(format) + time_format='%d %m %Y - %H:%S' + return native.strftime(time_format) def admin_required(f): """ @@ -469,11 +469,11 @@ def edit_required(f): # Fill indexpage with all requested data from database def fill_indexpage(page, database, db_filter, order): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True if current_user.show_detail_random(): - random = db.session.query(db.Books).filter(filter).order_by(func.random()).limit(config.config_random_books) + random = db.session.query(db.Books).filter(lang_filter).order_by(func.random()).limit(config.config_random_books) else: random = false off = int(int(config.config_books_per_page) * (page - 1)) @@ -588,15 +588,15 @@ def feed_normal_search(): def feed_search(term): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True if term: entries = db.session.query(db.Books).filter(db.or_(db.Books.tags.any(db.Tags.name.like("%" + term + "%")), db.Books.series.any(db.Series.name.like("%" + term + "%")), db.Books.authors.any(db.Authors.name.like("%" + term + "%")), db.Books.publishers.any(db.Publishers.name.like("%" + term + "%")), - db.Books.title.like("%" + term + "%"))).filter(filter).all() + db.Books.title.like("%" + term + "%"))).filter(lang_filter).all() entriescount = len(entries) if len(entries) > 0 else 1 pagination = Pagination(1, entriescount, entriescount) xml = render_title_template('feed.xml', searchterm=term, entries=entries, pagination=pagination) @@ -625,10 +625,10 @@ def feed_new(): @requires_basic_auth_if_no_ano def feed_discover(): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True - entries = db.session.query(db.Books).filter(filter).order_by(func.random()).limit(config.config_books_per_page) + lang_filter = True + entries = db.session.query(db.Books).filter(lang_filter).order_by(func.random()).limit(config.config_books_per_page) pagination = Pagination(1, config.config_books_per_page, int(config.config_books_per_page)) xml = render_title_template('feed.xml', entries=entries, pagination=pagination) response = make_response(xml) @@ -656,9 +656,9 @@ def feed_hot(): if not off: off = 0 if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True all_books = ub.session.query(ub.Downloads, ub.func.count(ub.Downloads.book_id)).order_by( ub.func.count(ub.Downloads.book_id).desc()).group_by(ub.Downloads.book_id) hot_books = all_books.offset(off).limit(config.config_books_per_page) @@ -667,7 +667,7 @@ def feed_hot(): downloadBook = db.session.query(db.Books).filter(db.Books.id == book.Downloads.book_id).first() if downloadBook: entries.append( - db.session.query(db.Books).filter(filter).filter(db.Books.id == book.Downloads.book_id).first()) + db.session.query(db.Books).filter(lang_filter).filter(db.Books.id == book.Downloads.book_id).first()) else: ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete() ub.session.commit() @@ -686,10 +686,10 @@ def feed_authorindex(): if not off: off = 0 if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True - entries = db.session.query(db.Authors).join(db.books_authors_link).join(db.Books).filter(filter)\ + lang_filter = True + entries = db.session.query(db.Authors).join(db.books_authors_link).join(db.Books).filter(lang_filter)\ .group_by('books_authors_link.author').order_by(db.Authors.sort).limit(config.config_books_per_page).offset(off) pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, len(db.session.query(db.Authors).all())) @@ -699,14 +699,14 @@ def feed_authorindex(): return response -@app.route("/opds/author/") +@app.route("/opds/author/") @requires_basic_auth_if_no_ano -def feed_author(id): +def feed_author(book_id): off = request.args.get("offset") if not off: off = 0 entries, random, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), - db.Books, db.Books.authors.any(db.Authors.id == id), db.Books.timestamp.desc()) + db.Books, db.Books.authors.any(db.Authors.id == book_id), db.Books.timestamp.desc()) xml = render_title_template('feed.xml', entries=entries, pagination=pagination) response = make_response(xml) response.headers["Content-Type"] = "application/xml" @@ -720,10 +720,10 @@ def feed_categoryindex(): if not off: off = 0 if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True - entries = db.session.query(db.Tags).join(db.books_tags_link).join(db.Books).filter(filter).\ + lang_filter = True + entries = db.session.query(db.Tags).join(db.books_tags_link).join(db.Books).filter(lang_filter).\ group_by('books_tags_link.tag').order_by(db.Tags.name).offset(off).limit(config.config_books_per_page) pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, len(db.session.query(db.Tags).all())) @@ -733,14 +733,14 @@ def feed_categoryindex(): return response -@app.route("/opds/category/") +@app.route("/opds/category/") @requires_basic_auth_if_no_ano -def feed_category(id): +def feed_category(book_id): off = request.args.get("offset") if not off: off = 0 entries, random, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), - db.Books, db.Books.tags.any(db.Tags.id == id), db.Books.timestamp.desc()) + db.Books, db.Books.tags.any(db.Tags.id == book_id), db.Books.timestamp.desc()) xml = render_title_template('feed.xml', entries=entries, pagination=pagination) response = make_response(xml) response.headers["Content-Type"] = "application/xml" @@ -754,10 +754,10 @@ def feed_seriesindex(): if not off: off = 0 if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True - entries = db.session.query(db.Series).join(db.books_series_link).join(db.Books).filter(filter).\ + lang_filter = True + entries = db.session.query(db.Series).join(db.books_series_link).join(db.Books).filter(lang_filter).\ group_by('books_series_link.series').order_by(db.Series.sort).offset(off).all() pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, len(db.session.query(db.Series).all())) @@ -767,14 +767,14 @@ def feed_seriesindex(): return response -@app.route("/opds/series/") +@app.route("/opds/series/") @requires_basic_auth_if_no_ano -def feed_series(id): +def feed_series(book_id): off = request.args.get("offset") if not off: off = 0 entries, random, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), - db.Books, db.Books.series.any(db.Series.id == id),db.Books.series_index) + db.Books, db.Books.series.any(db.Series.id == book_id),db.Books.series_index) xml = render_title_template('feed.xml', entries=entries, pagination=pagination) response = make_response(xml) response.headers["Content-Type"] = "application/xml" @@ -793,8 +793,8 @@ def do_gdrive_download(df, headers): download_url = df.metadata.get('downloadUrl') s = partial(total_size, 1024 * 1024) # I'm downloading BIG files, so 100M chunk size is fine for me def stream(): - for bytes in s: - headers = {"Range" : 'bytes=%s-%s' % (bytes[0], bytes[1])} + for byte in s: + headers = {"Range" : 'bytes=%s-%s' % (byte[0], byte[1])} resp, content = df.auth.Get_Http_Object().request(download_url, headers=headers) if resp.status == 206 : yield content @@ -803,14 +803,14 @@ def do_gdrive_download(df, headers): return return Response(stream_with_context(stream()), headers=headers) -@app.route("/opds/download///") +@app.route("/opds/download///") @requires_basic_auth_if_no_ano @download_required -def get_opds_download_link(book_id, format): +def get_opds_download_link(book_id, book_format): startTime=time.time() - format = format.split(".")[0] + book_format = book_format.split(".")[0] book = db.session.query(db.Books).filter(db.Books.id == book_id).first() - data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == format.upper()).first() + data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == book_format.upper()).first() app.logger.info (data.name) if current_user.is_authenticated: helper.update_download(book_id, int(current_user.id)) @@ -819,15 +819,15 @@ def get_opds_download_link(book_id, format): file_name = book.authors[0].name + '_' + file_name file_name = helper.get_valid_filename(file_name) headers = Headers () - headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf8')), format) + headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf8')), book_format) app.logger.info (time.time()-startTime) startTime=time.time() if config.config_use_google_drive: app.logger.info(time.time() - startTime) - df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, data.name + "." + format) + df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, data.name + "." + book_format) return do_gdrive_download(df, headers) else: - response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + format)) + response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + book_format)) response.headers=headers return response @@ -984,11 +984,11 @@ def index(page): @login_required_if_no_ano def hot_books(page): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True if current_user.show_detail_random(): - random = db.session.query(db.Books).filter(filter).order_by(func.random()).limit(config.config_random_books) + random = db.session.query(db.Books).filter(lang_filter).order_by(func.random()).limit(config.config_random_books) else: random = false off = int(int(config.config_books_per_page) * (page - 1)) @@ -1000,7 +1000,7 @@ def hot_books(page): downloadBook = db.session.query(db.Books).filter(db.Books.id == book.Downloads.book_id).first() if downloadBook: entries.append( - db.session.query(db.Books).filter(filter).filter(db.Books.id == book.Downloads.book_id).first()) + db.session.query(db.Books).filter(lang_filter).filter(db.Books.id == book.Downloads.book_id).first()) else: ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete() ub.session.commit() @@ -1033,22 +1033,22 @@ def discover(page): @login_required_if_no_ano def author_list(): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True entries = db.session.query(db.Authors, func.count('books_authors_link.book').label('count')).join( db.books_authors_link).join(db.Books).filter( - filter).group_by('books_authors_link.author').order_by(db.Authors.sort).all() + lang_filter).group_by('books_authors_link.author').order_by(db.Authors.sort).all() return render_title_template('list.html', entries=entries, folder='author', title=_(u"Author list")) -@app.route("/author/", defaults={'page': 1}) -@app.route("/author//'") +@app.route("/author/", defaults={'page': 1}) +@app.route("/author//'") @login_required_if_no_ano -def author(id,page): - entries, random, pagination = fill_indexpage(page, db.Books, db.Books.authors.any(db.Authors.id == id), +def author(book_id,page): + entries, random, pagination = fill_indexpage(page, db.Books, db.Books.authors.any(db.Authors.id == book_id), db.Books.timestamp.desc()) - name = db.session.query(db.Authors).filter(db.Authors.id == id).first().name + name = db.session.query(db.Authors).filter(db.Authors.id == book_id).first().name if entries: return render_title_template('index.html', random=random, entries=entries, title=_(u"Author: %(name)s", name=name)) else: @@ -1060,22 +1060,22 @@ def author(id,page): @login_required_if_no_ano def series_list(): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True entries = db.session.query(db.Series, func.count('books_series_link.book').label('count')).join( db.books_series_link).join(db.Books).filter( - filter).group_by('books_series_link.series').order_by(db.Series.sort).all() + lang_filter).group_by('books_series_link.series').order_by(db.Series.sort).all() return render_title_template('list.html', entries=entries, folder='series', title=_(u"Series list")) -@app.route("/series//", defaults={'page': 1}) -@app.route("/series//'") +@app.route("/series//", defaults={'page': 1}) +@app.route("/series//'") @login_required_if_no_ano -def series(id, page): - entries, random, pagination = fill_indexpage(page, db.Books, db.Books.series.any(db.Series.id == id), +def series(book_id, page): + entries, random, pagination = fill_indexpage(page, db.Books, db.Books.series.any(db.Series.id == book_id), db.Books.series_index) - name=db.session.query(db.Series).filter(db.Series.id == id).first().name + name=db.session.query(db.Series).filter(db.Series.id == book_id).first().name if entries: return render_title_template('index.html', random=random, pagination=pagination, entries=entries, title=_(u"Series: %(serie)s", serie=name)) @@ -1133,52 +1133,52 @@ def language(name, page): @login_required_if_no_ano def category_list(): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True entries = db.session.query(db.Tags, func.count('books_tags_link.book').label('count')).join( db.books_tags_link).join(db.Books).filter( - filter).group_by('books_tags_link.tag').all() + lang_filter).group_by('books_tags_link.tag').all() return render_title_template('list.html', entries=entries, folder='category', title=_(u"Category list")) -@app.route("/category/", defaults={'page': 1}) -@app.route('/category//') +@app.route("/category/", defaults={'page': 1}) +@app.route('/category//') @login_required_if_no_ano -def category(id, page): - entries, random, pagination = fill_indexpage(page, db.Books, db.Books.tags.any(db.Tags.id == id), +def category(book_id, page): + entries, random, pagination = fill_indexpage(page, db.Books, db.Books.tags.any(db.Tags.id == book_id), db.Books.timestamp.desc()) - name=db.session.query(db.Tags).filter(db.Tags.id == id).first().name + name=db.session.query(db.Tags).filter(db.Tags.id == book_id).first().name return render_title_template('index.html', random=random, entries=entries, pagination=pagination, title=_(u"Category: %(name)s", name=name)) -@app.route("/ajax/toggleread/", methods=['POST']) +@app.route("/ajax/toggleread/", methods=['POST']) @login_required -def toggle_read(id): +def toggle_read(book_id): book = ub.session.query(ub.ReadBook).filter(ub.and_(ub.ReadBook.user_id == int(current_user.id), - ub.ReadBook.book_id == id)).first() + ub.ReadBook.book_id == book_id)).first() if book: book.is_read=not book.is_read else: readBook=ub.ReadBook() readBook.user_id=int(current_user.id) - readBook.book_id = id + readBook.book_id = book_id readBook.is_read=True book=readBook ub.session.merge(book) ub.session.commit() return "" -@app.route("/book/") +@app.route("/book/") @login_required_if_no_ano -def show_book(id): +def show_book(book_id): if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True - entries = db.session.query(db.Books).filter(db.Books.id == id).filter(filter).first() + lang_filter = True + entries = db.session.query(db.Books).filter(db.Books.id == book_id).filter(lang_filter).first() if entries: for index in range(0, len(entries.languages)): try: @@ -1198,7 +1198,7 @@ def show_book(id): else: cc=tmpcc book_in_shelfs = [] - shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == id).all() + shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all() for entry in shelfs: book_in_shelfs.append(entry.shelf) @@ -1206,7 +1206,7 @@ def show_book(id): # title=entries.title, books_shelfs=book_in_shelfs) if not current_user.is_anonymous(): matching_have_read_book=ub.session.query(ub.ReadBook).filter(ub.and_(ub.ReadBook.user_id == int(current_user.id), - ub.ReadBook.book_id == id)).all() + ub.ReadBook.book_id == book_id)).all() have_read=len(matching_have_read_book) > 0 and matching_have_read_book[0].is_read else: have_read=None @@ -1337,13 +1337,13 @@ def on_received_watch_confirmation(): if not response['deleted'] and response['file']['title'] == 'metadata.db' and response['file']['md5Checksum'] != md5(dbpath): tmpDir=tempfile.gettempdir() app.logger.info ('Database file updated') - copyfile (dbpath, tmpDir + "/metadata.db_" + str(current_milli_time())) + copyfile (dbpath, os.path.join(tmpDir, "metadata.db_" + str(current_milli_time()))) app.logger.info ('Backing up existing and downloading updated metadata.db') - gdriveutils.downloadFile(Gdrive.Instance().drive, None, "metadata.db", tmpDir + "/tmp_metadata.db") + gdriveutils.downloadFile(Gdrive.Instance().drive, None, "metadata.db", os.path.join(tmpDir, "tmp_metadata.db")) app.logger.info ('Setting up new DB') - os.rename(tmpDir + "/tmp_metadata.db", dbpath) + os.rename(os.path.join(tmpDir, "tmp_metadata.db"), dbpath) db.setup_db() - except Exception, e: + except Exception as e: app.logger.exception(e) updateMetaData() @@ -1395,14 +1395,14 @@ def search(): term = request.args.get("query").strip() if term: if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True + lang_filter = True entries = db.session.query(db.Books).filter(db.or_(db.Books.tags.any(db.Tags.name.like("%" + term + "%")), db.Books.series.any(db.Series.name.like("%" + term + "%")), db.Books.authors.any(db.Authors.name.like("%" + term + "%")), db.Books.publishers.any(db.Publishers.name.like("%" + term + "%")), - db.Books.title.like("%" + term + "%"))).filter(filter).all() + db.Books.title.like("%" + term + "%"))).filter(lang_filter).all() return render_title_template('search.html', searchterm=term, entries=entries) else: return render_title_template('search.html', searchterm="") @@ -1563,15 +1563,15 @@ def feed_unread_books(): def unread_books(page): return render_read_books(page, False) -@app.route("/read//") +@app.route("/read//") @login_required_if_no_ano -def read_book(book_id, format): +def read_book(book_id, book_format): book = db.session.query(db.Books).filter(db.Books.id == book_id).first() if book: book_dir = os.path.join(config.get_main_dir, "cps", "static", str(book_id)) if not os.path.exists(book_dir): os.mkdir(book_dir) - if format.lower() == "epub": + if book_format.lower() == "epub": # check if mimetype file is exists mime_file = str(book_id) + "/mimetype" if not os.path.exists(mime_file): @@ -1586,9 +1586,7 @@ def read_book(book_id, format): try: os.makedirs(newDir) except OSError as exception: - if exception.errno == errno.EEXIST: - pass - else: + if not exception.errno == errno.EEXIST: raise if fileName: fd = open(os.path.join(newDir, fileName), "wb") @@ -1596,21 +1594,21 @@ def read_book(book_id, format): fd.close() zfile.close() return render_title_template('read.html', bookid=book_id, title=_(u"Read a Book")) - elif format.lower() == "pdf": + elif book_format.lower() == "pdf": all_name = str(book_id) + "/" + book.data[0].name + ".pdf" tmp_file = os.path.join(book_dir, book.data[0].name) + ".pdf" if not os.path.exists(tmp_file): pdf_file = os.path.join(config.config_calibre_dir, book.path, book.data[0].name) + ".pdf" copyfile(pdf_file, tmp_file) return render_title_template('readpdf.html', pdffile=all_name, title=_(u"Read a Book")) - elif format.lower() == "txt": + elif book_format.lower() == "txt": all_name = str(book_id) + "/" + book.data[0].name + ".txt" tmp_file = os.path.join(book_dir, book.data[0].name) + ".txt" if not os.path.exists(all_name): txt_file = os.path.join(config.config_calibre_dir, book.path, book.data[0].name) + ".txt" copyfile(txt_file, tmp_file) return render_title_template('readtxt.html', txtfile=all_name, title=_(u"Read a Book")) - elif format.lower() == "cbr": + elif book_format.lower() == "cbr": all_name = str(book_id) + "/" + book.data[0].name + ".cbr" tmp_file = os.path.join(book_dir, book.data[0].name) + ".cbr" if not os.path.exists(all_name): @@ -1622,13 +1620,13 @@ def read_book(book_id, format): flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error") return redirect(url_for("index")) -@app.route("/download//") +@app.route("/download//") @login_required_if_no_ano @download_required -def get_download_link(book_id, format): - format = format.split(".")[0] +def get_download_link(book_id, book_format): + book_format = book_format.split(".")[0] book = db.session.query(db.Books).filter(db.Books.id == book_id).first() - data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == format.upper()).first() + data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == book_format.upper()).first() if data: # collect downloaded books only for registered user and not for anonymous user if current_user.is_authenticated: @@ -1639,25 +1637,25 @@ def get_download_link(book_id, format): file_name = helper.get_valid_filename(file_name) headers = Headers () try: - headers["Content-Type"] = mimetypes.types_map['.' + format] - except: - pass - headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf-8')), format) + headers["Content-Type"] = mimetypes.types_map['.' + book_format] + except KeyError: + headers["Content-Type"] = "application/octet-stream" + headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf-8')), book_format) if config.config_use_google_drive: - df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, '%s.%s' % (data.name, format)) + df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, '%s.%s' % (data.name, book_format)) return do_gdrive_download(df, headers) else: - response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + format)) + response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + book_format)) response.headers=headers return response else: abort(404) -@app.route("/download///") +@app.route("/download///") @login_required_if_no_ano @download_required -def get_download_link_ext(book_id, format, anyname): - return get_download_link(book_id, format) +def get_download_link_ext(book_id, book_format, anyname): + return get_download_link(book_id, book_format) @app.route('/register', methods=['GET', 'POST']) def register(): @@ -2370,10 +2368,10 @@ def edit_book(book_id): db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort) cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() if current_user.filter_language() != "all": - filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) + lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language()) else: - filter = True - book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(filter).first() + lang_filter = True + book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(lang_filter).first() author_names = [] if book: for index in range(0, len(book.languages)): @@ -2575,7 +2573,7 @@ def edit_book(book_id): if config.config_use_google_drive: updateGdriveCalibreFromLocal() if "detail_view" in to_save: - return redirect(url_for('show_book', id=book.id)) + 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")) @@ -2597,9 +2595,9 @@ def upload(): db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort) db.session.connection().connection.connection.create_function('uuid4', 0, lambda: str(uuid4())) if request.method == 'POST' and 'btn-upload' in request.files: - file = request.files['btn-upload'] - if '.' in file.filename: - file_ext = file.filename.rsplit('.', 1)[-1].lower() + requested_file = request.files['btn-upload'] + if '.' in requested_file.filename: + file_ext = requested_file.filename.rsplit('.', 1)[-1].lower() if file_ext not in ALLOWED_EXTENSIONS: flash( _('File extension "%s" is not allowed to be uploaded to this server' % @@ -2610,7 +2608,7 @@ def upload(): else: flash(_('File to be uploaded must have an extension'), category="error") return redirect(url_for('index')) - meta = uploader.upload(file) + meta = uploader.upload(requested_file) title = meta.title author = meta.author