mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +00:00 
			
		
		
		
	Code cosmetics
This commit is contained in:
		
							
								
								
									
										2
									
								
								cps.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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') | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import os | ||||
| import traceback | ||||
| import re | ||||
| import unicodedata | ||||
|  | ||||
| try: | ||||
|     from StringIO import StringIO | ||||
|     from email.MIMEBase import MIMEBase | ||||
|   | ||||
| @@ -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"))) { | ||||
|   | ||||
| @@ -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('<ul id="book-list" class="media-list"></ul>'); | ||||
|         } | ||||
|         if (ggDone && dbDone) { | ||||
|             if (!ggResults && !dbResults) { | ||||
|                 $("#meta-info").html('<p class="text-danger">'+ msg.no_result +"</p>"); | ||||
|                 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 = '<li class="media">' + | ||||
|                     '<img class="pull-left img-responsive" data-toggle="modal" data-target="#metaModal" src="' + | ||||
|                     bookCover + '" alt="Cover" style="width:100px;height:150px" onclick=\'javascript:get_meta("google",' + | ||||
|                     i + ')\'>' + | ||||
|                     '<div class="media-body">' + | ||||
|                     '<h4 class="media-heading"><a href="https://books.google.com/books?id=' + | ||||
|                     book.id + '"  target="_blank">' + book.volumeInfo.title + '</a></h4>' + | ||||
|                     "<p>"+ msg.author +":" + book.volumeInfo.authors + "</p>" + | ||||
|                     "<p>"+ msg.publisher + ":" + book.volumeInfo.publisher + "</p>" + | ||||
|                     "<p>"+ msg.description + ":" + book.volumeInfo.description + "</p>" + | ||||
|                     "<p>"+ msg.source + ':<a href="https://books.google.com" target="_blank">Google Books</a></p>' + | ||||
|                     "</div>" + | ||||
|                     "</li>"; | ||||
|                 $("#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 = '<li class="media">' + | ||||
|                     '<img class="pull-left img-responsive" data-toggle="modal" data-target="#metaModal" src="' + | ||||
|                     book.image + '" alt="Cover" style="width:100px;height: 150px" onclick=\'javascript:get_meta("douban",' + | ||||
|                     i + ')\'>' + | ||||
|                     '<div class="media-body">' + | ||||
|                     '<h4 class="media-heading"><a href="https://book.douban.com/subject/' + | ||||
|                     book.id + '"  target="_blank">' + book.title + "</a></h4>" + | ||||
|                     "<p>" + msg.author + ":" + book.author + "</p>" + | ||||
|                     "<p>" + msg.publisher + ":" + book.publisher + "</p>" + | ||||
|                     "<p>" + msg.description + ":" + book.summary + "</p>" + | ||||
|                     "<p>" + msg.source + ':<a href="https://book.douban.com" target="_blank">Douban Books</a></p>' + | ||||
|                     "</div>" + | ||||
|                     "</li>"; | ||||
|                 $("#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('<ul id="book-list" class="media-list"></ul>'); | ||||
|         } | ||||
|         if (gg_done && dbDone) { | ||||
|             if (!gg_results && !db_results) { | ||||
|                 $('#meta-info').html('<p class="text-danger">'+ msg.no_result +'</p>'); | ||||
|                 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 = '<li class="media">' + | ||||
|                     '<img class="pull-left img-responsive" data-toggle="modal" data-target="#metaModal" src="' + | ||||
|                     book_cover + '" alt="Cover" style="width:100px;height:150px" onclick=\'javascript:get_meta("google",' + | ||||
|                     i + ')\'>' + | ||||
|                     '<div class="media-body">' + | ||||
|                     '<h4 class="media-heading"><a href="https://books.google.com/books?id=' + | ||||
|                     book.id + '"  target="_blank">' + book.volumeInfo.title + '</a></h4>' + | ||||
|                     '<p>'+ msg.author +':' + book.volumeInfo.authors + '</p>' + | ||||
|                     '<p>'+ msg.publisher + ':' + book.volumeInfo.publisher + '</p>' + | ||||
|                     '<p>'+ msg.description + ':' + book.volumeInfo.description + '</p>' + | ||||
|                     '<p>'+ msg.source + ':<a href="https://books.google.com" target="_blank">Google Books</a></p>' + | ||||
|                     '</div>' + | ||||
|                     '</li>'; | ||||
|                 $("#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 = '<li class="media">' + | ||||
|                     '<img class="pull-left img-responsive" data-toggle="modal" data-target="#metaModal" src="' + | ||||
|                     book.image + '" alt="Cover" style="width:100px;height: 150px" onclick=\'javascript:get_meta("douban",' + | ||||
|                     i + ')\'>' + | ||||
|                     '<div class="media-body">' + | ||||
|                     '<h4 class="media-heading"><a href="https://book.douban.com/subject/' + | ||||
|                     book.id + '"  target="_blank">' + book.title + '</a></h4>' + | ||||
|                     '<p>' + msg.author + ':' + book.author + '</p>' + | ||||
|                     '<p>' + msg.publisher + ':' + book.publisher + '</p>' + | ||||
|                     '<p>' + msg.description + ':' + book.summary + '</p>' + | ||||
|                     '<p>' + msg.source + ':<a href="https://book.douban.com" target="_blank">Douban Books</a></p>' + | ||||
|                     '</div>' + | ||||
|                     "</li>"; | ||||
|                 $("#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('<p class="text-danger">'+ msg.search_error+'!</p>'); | ||||
|                 $("#meta-info").html('<p class="text-danger">'+ msg.search_error+"!</p>"); | ||||
|             }, | ||||
|             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); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -106,7 +106,7 @@ | ||||
|     </div> | ||||
|     <a href="#" id="get_meta" class="btn btn-default" data-toggle="modal" data-target="#metaModal">{{_('Get metadata')}}</a> | ||||
|     <button type="submit" class="btn btn-default">{{_('Submit')}}</button> | ||||
|     <a href="{{ url_for('show_book',id=book.id) }}" class="btn btn-default">{{_('Back')}}</a> | ||||
|     <a href="{{ url_for('show_book', book_id=book.id) }}" class="btn btn-default">{{_('Back')}}</a> | ||||
|   </form> | ||||
| </div> | ||||
| {% endif %} | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|       <h2>{{entry.title}}</h2> | ||||
|       <p class="author"> | ||||
|           {% for author in entry.authors %} | ||||
|             <a href="{{url_for('author', id=author.id ) }}">{{author.name}}</a> | ||||
|             <a href="{{url_for('author', book_id=author.id ) }}">{{author.name}}</a> | ||||
|             {% if not loop.last %} | ||||
|               & | ||||
|             {% endif %} | ||||
| @@ -37,7 +37,7 @@ | ||||
|       {% endif %} | ||||
|  | ||||
|       {% if entry.series|length > 0 %} | ||||
|         <p>{{_('Book')}} {{entry.series_index}} {{_('of')}} <a href="{{url_for('series', id=entry.series[0].id)}}">{{entry.series[0].name}}</a></p> | ||||
|         <p>{{_('Book')}} {{entry.series_index}} {{_('of')}} <a href="{{url_for('series', book_id=entry.series[0].id)}}">{{entry.series[0].name}}</a></p> | ||||
|       {% endif %} | ||||
|  | ||||
|       {% if entry.languages.__len__() > 0 %} | ||||
| @@ -65,7 +65,7 @@ | ||||
|         <span class="glyphicon glyphicon-tags"></span> | ||||
|          | ||||
|         {% for tag in entry.tags %} | ||||
|           <a href="{{ url_for('category', id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a> | ||||
|           <a href="{{ url_for('category', book_id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a> | ||||
|         {%endfor%} | ||||
|       </div> | ||||
|       </p> | ||||
| @@ -110,7 +110,7 @@ | ||||
|       {% if not g.user.is_anonymous() %} | ||||
|       <p> | ||||
|         <div class="custom_columns" id="have_read_container"> | ||||
|           <form id="have_read_form" action="{{ url_for('toggle_read', id=entry.id)}}" method="POST") > | ||||
|           <form id="have_read_form" action="{{ url_for('toggle_read', book_id=entry.id)}}" method="POST") > | ||||
|             <input id="have_read_cb" type="checkbox" {% if have_read %}checked{% endif %} > | ||||
|             <label for="have_read_cb">{{_('Read')}}</label> | ||||
|           </form> | ||||
| @@ -136,7 +136,7 @@ | ||||
|               </button> | ||||
|               <ul class="dropdown-menu" aria-labelledby="btnGroupDrop1"> | ||||
|                 {% for format in entry.data %} | ||||
|                 <li><a href="{{ url_for('get_download_link_ext', book_id=entry.id, format=format.format|lower, anyname=entry.id|string+'.'+format.format) }}">{{format.format}}</a></li> | ||||
|                 <li><a href="{{ url_for('get_download_link_ext', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format) }}">{{format.format}}</a></li> | ||||
|                 {%endfor%} | ||||
|               </ul> | ||||
|             </div> | ||||
| @@ -154,7 +154,7 @@ | ||||
|                 <ul class="dropdown-menu" aria-labelledby="btnGroupDrop2"> | ||||
|                   {% for format in entry.data %} | ||||
|                   {%if format.format|lower == 'epub' or format.format|lower == 'txt' or format.format|lower == 'pdf' or format.format|lower == 'cbr' or format.format|lower == 'cbt' or format.format|lower == 'cbz' %} | ||||
|                   <li><a target="_blank" href="{{ url_for('read_book', book_id=entry.id, format=format.format|lower) }}">{{format.format}}</a></li> | ||||
|                   <li><a target="_blank" href="{{ url_for('read_book', book_id=entry.id, book_format=format.format|lower) }}">{{format.format}}</a></li> | ||||
|                   {% endif %} | ||||
|                   {%endfor%} | ||||
|                 </ul> | ||||
|   | ||||
| @@ -8,14 +8,14 @@ | ||||
|     <div class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||
|       <div class="cover"> | ||||
|         {% if entry.has_cover is defined %} | ||||
|           <a href="{{ url_for('show_book', id=entry.id) }}"> | ||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> | ||||
|             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||
|           </a> | ||||
|         {% endif %} | ||||
|       </div> | ||||
|       <div class="meta"> | ||||
|         <p class="title">{{entry.title|shortentitle}}</p> | ||||
|         <p class="author"><a href="{{url_for('author', id=entry.authors[0].id) }}">{{entry.authors[0].name}}</a></p> | ||||
|         <p class="author"><a href="{{url_for('author', book_id=entry.authors[0].id) }}">{{entry.authors[0].name}}</a></p> | ||||
|         {% if entry.ratings.__len__() > 0 %} | ||||
|         <div class="rating"> | ||||
|           {% for number in range((entry.ratings[0].rating/2)|int(2)) %} | ||||
|   | ||||
| @@ -56,7 +56,7 @@ | ||||
|     <link type="image/jpeg" href="{{url_for('feed_get_cover', book_id=entry.id)}}" rel="http://opds-spec.org/image/thumbnail"/> | ||||
|     {% endif %} | ||||
|     {% for format in entry.data %} | ||||
|     <link rel="http://opds-spec.org/acquisition" href="{{ url_for('get_opds_download_link', book_id=entry.id, format=format.format|lower)}}" | ||||
|     <link rel="http://opds-spec.org/acquisition" href="{{ url_for('get_opds_download_link', book_id=entry.id, book_format=format.format|lower)}}" | ||||
|           length="{{format.uncompressed_size}}" mtime="{{entry.timestamp}}" type="{{format.format|lower|mimetype}}"/> | ||||
|     {% endfor %} | ||||
|   </entry> | ||||
| @@ -65,9 +65,9 @@ | ||||
|   {% for entry in listelements %} | ||||
|   <entry> | ||||
|     <title>{{entry.name}}</title> | ||||
|     <id>{{ url_for(folder, id=entry.id) }}</id> | ||||
|     <link type="application/atom+xml;profile=opds-catalog;type=feed;kind=acquisition" href="{{url_for(folder, id=entry.id)}}"/> | ||||
|     <link type="application/atom+xml" href="{{url_for(folder, id=entry.id)}}" rel="subsection"/> | ||||
|     <id>{{ url_for(folder, book_id=entry.id) }}</id> | ||||
|     <link type="application/atom+xml;profile=opds-catalog;type=feed;kind=acquisition" href="{{url_for(folder, book_id=entry.id)}}"/> | ||||
|     <link type="application/atom+xml" href="{{url_for(folder, book_id=entry.id)}}" rel="subsection"/> | ||||
|   </entry> | ||||
|   {% endfor %} | ||||
| </feed> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|     {% for entry in random %} | ||||
|     <div id="books_rand" class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||
|       <div class="cover"> | ||||
|           <a href="{{ url_for('show_book', id=entry.id) }}"> | ||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> | ||||
|             {% if entry.has_cover %} | ||||
|               <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||
|             {% else %} | ||||
| @@ -18,7 +18,7 @@ | ||||
|       </div> | ||||
|       <div class="meta"> | ||||
|         <p class="title">{{entry.title|shortentitle}}</p> | ||||
|         <p class="author"><a href="{{url_for('author', id=entry.authors[0].id) }}">{{entry.authors[0].name}}</a></p> | ||||
|         <p class="author"><a href="{{url_for('author', book_id=entry.authors[0].id) }}">{{entry.authors[0].name}}</a></p> | ||||
|         {% if entry.ratings.__len__() > 0 %} | ||||
|         <div class="rating"> | ||||
|           {% for number in range((entry.ratings[0].rating/2)|int(2)) %} | ||||
| @@ -44,7 +44,7 @@ | ||||
|     {% for entry in entries %} | ||||
|     <div id="books" class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||
|       <div class="cover"> | ||||
|           <a href="{{ url_for('show_book', id=entry.id) }}"> | ||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> | ||||
|             {% if entry.has_cover %} | ||||
|               <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||
|             {% else %} | ||||
| @@ -56,7 +56,7 @@ | ||||
|         <p class="title">{{entry.title|shortentitle}}</p> | ||||
|         <p class="author"> | ||||
|           {% for author in entry.authors %} | ||||
|             <a href="{{url_for('author', id=author.id) }}">{{author.name}}</a> | ||||
|             <a href="{{url_for('author', book_id=author.id) }}">{{author.name}}</a> | ||||
|             {% if not loop.last %} | ||||
|               & | ||||
|             {% endif %} | ||||
|   | ||||
| @@ -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}}" | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
|       {% endif %} | ||||
|       <div class="row"> | ||||
|         <div class="col-xs-1" align="left"><span class="badge">{{entry.count}}</span></div> | ||||
|         <div class="col-xs-6"><a id="list_{{loop.index0}}" href="{{url_for(folder, id=entry[0].id )}}">{{entry[0].name}}</a></div> | ||||
|         <div class="col-xs-6"><a id="list_{{loop.index0}}" href="{{url_for(folder, book_id=entry[0].id )}}">{{entry[0].name}}</a></div> | ||||
|       </div> | ||||
|     {% endfor %} | ||||
|   </div> | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|     <div class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||
|       <div class="cover"> | ||||
|         {% if entry.has_cover is defined %} | ||||
|            <a href="{{ url_for('show_book', id=entry.id) }}"> | ||||
|            <a href="{{ url_for('show_book', book_id=entry.id) }}"> | ||||
|             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||
|           </a> | ||||
|         {% endif %} | ||||
| @@ -24,7 +24,7 @@ | ||||
|         <p class="title">{{entry.title|shortentitle}}</p> | ||||
|         <p class="author"> | ||||
|           {% for author in entry.authors %} | ||||
|             <a href="{{url_for('author', id=author.id ) }}">{{author.name}}</a> | ||||
|             <a href="{{url_for('author', book_id=author.id ) }}">{{author.name}}</a> | ||||
|             {% if not loop.last %} | ||||
|               & | ||||
|             {% endif %} | ||||
|   | ||||
| @@ -15,14 +15,14 @@ | ||||
|     <div class="col-sm-3 col-lg-2 col-xs-6 book"> | ||||
|       <div class="cover"> | ||||
|         {% if entry.has_cover is defined %} | ||||
|           <a href="{{ url_for('show_book', id=entry.id) }}"> | ||||
|           <a href="{{ url_for('show_book', book_id=entry.id) }}"> | ||||
|             <img src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" /> | ||||
|           </a> | ||||
|         {% endif %} | ||||
|       </div> | ||||
|       <div class="meta"> | ||||
|         <p class="title">{{entry.title|shortentitle}}</p> | ||||
|         <p class="author"><a href="{{url_for('author', id=entry.authors[0].id) }}">{{entry.authors[0].name}}</a></p> | ||||
|         <p class="author"><a href="{{url_for('author', book_id=entry.authors[0].id) }}">{{entry.authors[0].name}}</a></p> | ||||
|         {% if entry.ratings.__len__() > 0 %} | ||||
|         <div class="rating"> | ||||
|           {% for number in range((entry.ratings[0].rating/2)|int(2)) %} | ||||
|   | ||||
| @@ -131,7 +131,7 @@ | ||||
|     <h2>{{_('Recent Downloads')}}</h2> | ||||
|     {% for entry in downloads %} | ||||
|       <div class="col-sm-2"> | ||||
|         <a class="pull-left" href="{{ url_for('show_book', id=entry.id) }}"> | ||||
|         <a class="pull-left" href="{{ url_for('show_book', book_id=entry.id) }}"> | ||||
|           <img class="media-object" width="100" src="{{ url_for('get_cover', cover_path=entry.path.replace('\\','/')) }}" alt="..."> | ||||
|         </a> | ||||
|       </div> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										234
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								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/<int:id>") | ||||
| @app.route("/opds/author/<int:book_id>") | ||||
| @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/<int:id>") | ||||
| @app.route("/opds/category/<int:book_id>") | ||||
| @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/<int:id>") | ||||
| @app.route("/opds/series/<int:book_id>") | ||||
| @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/<book_id>/<format>/") | ||||
| @app.route("/opds/download/<book_id>/<book_format>/") | ||||
| @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/<int:id>", defaults={'page': 1}) | ||||
| @app.route("/author/<int:id>/<int:page>'") | ||||
| @app.route("/author/<int:book_id>", defaults={'page': 1}) | ||||
| @app.route("/author/<int:book_id>/<int:page>'") | ||||
| @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/<int:id>/", defaults={'page': 1}) | ||||
| @app.route("/series/<int:id>/<int:page>'") | ||||
| @app.route("/series/<int:book_id>/", defaults={'page': 1}) | ||||
| @app.route("/series/<int:book_id>/<int:page>'") | ||||
| @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/<int:id>", defaults={'page': 1}) | ||||
| @app.route('/category/<int:id>/<int:page>') | ||||
| @app.route("/category/<int:book_id>", defaults={'page': 1}) | ||||
| @app.route('/category/<int:book_id>/<int:page>') | ||||
| @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/<int:id>", methods=['POST']) | ||||
| @app.route("/ajax/toggleread/<int:book_id>", 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/<int:id>") | ||||
| @app.route("/book/<int:book_id>") | ||||
| @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/<int:book_id>/<format>") | ||||
| @app.route("/read/<int:book_id>/<book_format>") | ||||
| @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/<int:book_id>/<format>") | ||||
| @app.route("/download/<int:book_id>/<book_format>") | ||||
| @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/<int:book_id>/<format>/<anyname>") | ||||
| @app.route("/download/<int:book_id>/<book_format>/<anyname>") | ||||
| @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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 OzzieIsaacs
					OzzieIsaacs