mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 07:13:02 +00:00 
			
		
		
		
	Fix #365
This commit is contained in:
		| @@ -104,7 +104,10 @@ | ||||
|           <nav class="navigation"> | ||||
|             <ul class="list-unstyled" id="scnd-nav" intent in-standard-append="nav.navigation" in-mobile-after="#main-nav" in-mobile-class="nav navbar-nav"> | ||||
|               <li class="nav-head hidden-xs">{{_('Browse')}}</li> | ||||
|               {% if g.user.show_recent() %} | ||||
|               <li id="nav_new"><a href="{{url_for('index')}}"><span class="glyphicon glyphicon-book"></span> {{_('Recently Added')}}</a></li> | ||||
|               {%endif%} | ||||
|               {% if g.user.show_sorted() %} | ||||
|               <li class="dropdown"> | ||||
|                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> | ||||
|                   <span class="glyphicon glyphicon-sort-by-attributes"></span> {{_('Sorted Books')}} | ||||
| @@ -117,6 +120,7 @@ | ||||
|                   <li><a href="{{url_for('titles_descending')}}">{{_('Sort By')}} {{_('Title')}}  ({{_('Descending')}})</a></li> | ||||
|                 </ul> | ||||
|               </li> | ||||
|               {%endif%} | ||||
|               {% if g.user.show_hot_books() %} | ||||
|               <li id="nav_hot"><a href="{{url_for('hot_books')}}"><span class="glyphicon glyphicon-fire"></span> {{_('Hot Books')}}</a></li> | ||||
|               {%endif%} | ||||
|   | ||||
| @@ -45,6 +45,14 @@ | ||||
|           <input type="checkbox" name="show_random" id="show_random" {% if content.show_random_books() %}checked{% endif %}> | ||||
|           <label for="show_random">{{_('Show random books')}}</label> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|           <input type="checkbox" name="show_recent" id="show_recent" {% if content.show_recent() %}checked{% endif %}> | ||||
|           <label for="show_recent">{{_('Show recent books')}}</label> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|           <input type="checkbox" name="show_sorted" id="show_sorted" {% if content.show_sorted() %}checked{% endif %}> | ||||
|           <label for="show_sorted">{{_('Show sorted books')}}</label> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|           <input type="checkbox" name="show_hot" id="show_hot" {% if content.show_hot_books() %}checked{% endif %}> | ||||
|           <label for="show_hot">{{_('Show hot books')}}</label> | ||||
|   | ||||
							
								
								
									
										20
									
								
								cps/ub.py
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								cps/ub.py
									
									
									
									
									
								
							| @@ -39,6 +39,9 @@ SIDEBAR_RANDOM = 32 | ||||
| SIDEBAR_AUTHOR = 64 | ||||
| SIDEBAR_BEST_RATED = 128 | ||||
| SIDEBAR_READ_AND_UNREAD = 256 | ||||
| SIDEBAR_RECENT = 512 | ||||
| SIDEBAR_SORTED = 1024 | ||||
|  | ||||
|  | ||||
| DEFAULT_PASS = "admin123" | ||||
| DEFAULT_PORT = int(os.environ.get("CALIBRE_PORT", 8083)) | ||||
| @@ -120,6 +123,12 @@ class UserBase: | ||||
|     def show_hot_books(self): | ||||
|         return bool((self.sidebar_view is not None)and(self.sidebar_view & SIDEBAR_HOT == SIDEBAR_HOT)) | ||||
|  | ||||
|     def show_recent(self): | ||||
|         return bool((self.sidebar_view is not None)and(self.sidebar_view & SIDEBAR_RECENT == SIDEBAR_RECENT)) | ||||
|  | ||||
|     def show_sorted(self): | ||||
|         return bool((self.sidebar_view is not None)and(self.sidebar_view & SIDEBAR_SORTED == SIDEBAR_SORTED)) | ||||
|  | ||||
|     def show_series(self): | ||||
|         return bool((self.sidebar_view is not None)and(self.sidebar_view & SIDEBAR_SERIES == SIDEBAR_SERIES)) | ||||
|  | ||||
| @@ -496,9 +505,10 @@ def migrate_Database(): | ||||
|         conn = engine.connect() | ||||
|         conn.execute("UPDATE user SET 'sidebar_view' = (random_books* :side_random + language_books * :side_lang " | ||||
|             "+ series_books * :side_series + category_books * :side_category + hot_books * " | ||||
|             ":side_hot + :side_autor + :detail_random)",{'side_random': SIDEBAR_RANDOM, | ||||
|             'side_lang': SIDEBAR_LANGUAGE, 'side_series': SIDEBAR_SERIES, 'side_category': SIDEBAR_CATEGORY, | ||||
|             'side_hot': SIDEBAR_HOT, 'side_autor': SIDEBAR_AUTHOR, 'detail_random': DETAIL_RANDOM}) | ||||
|             ":side_hot + :side_autor + :detail_random)" | ||||
|             ,{'side_random': SIDEBAR_RANDOM, 'side_lang': SIDEBAR_LANGUAGE, 'side_series': SIDEBAR_SERIES, | ||||
|             'side_category': SIDEBAR_CATEGORY, 'side_hot': SIDEBAR_HOT, 'side_autor': SIDEBAR_AUTHOR, | ||||
|             'detail_random': DETAIL_RANDOM}) | ||||
|         session.commit() | ||||
|     try: | ||||
|         session.query(exists().where(User.mature_content)).scalar() | ||||
| @@ -582,8 +592,8 @@ def create_admin_user(): | ||||
|     user.nickname = "admin" | ||||
|     user.role = ROLE_USER + ROLE_ADMIN + ROLE_DOWNLOAD + ROLE_UPLOAD + ROLE_EDIT + ROLE_DELETE_BOOKS + ROLE_PASSWD | ||||
|     user.sidebar_view = DETAIL_RANDOM + SIDEBAR_LANGUAGE + SIDEBAR_SERIES + SIDEBAR_CATEGORY + SIDEBAR_HOT + \ | ||||
|             SIDEBAR_RANDOM + SIDEBAR_AUTHOR + SIDEBAR_BEST_RATED + SIDEBAR_READ_AND_UNREAD | ||||
|  | ||||
|             SIDEBAR_RANDOM + SIDEBAR_AUTHOR + SIDEBAR_BEST_RATED + SIDEBAR_READ_AND_UNREAD + SIDEBAR_RECENT + \ | ||||
|             SIDEBAR_SORTED | ||||
|  | ||||
|     user.password = generate_password_hash(DEFAULT_PASS) | ||||
|  | ||||
|   | ||||
							
								
								
									
										190
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								cps/web.py
									
									
									
									
									
								
							| @@ -1046,27 +1046,35 @@ def index(page): | ||||
| @app.route('/books/newest/page/<int:page>') | ||||
| @login_required_if_no_ano | ||||
| def newest_books(page): | ||||
|     entries, random, pagination = fill_indexpage(page, db.Books, True, db.Books.pubdate.desc()) | ||||
|     return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                  title=_(u"Newest Books")) | ||||
|  | ||||
|     if current_cuser.show_sorted(): | ||||
|         entries, random, pagination = fill_indexpage(page, db.Books, True, db.Books.pubdate.desc()) | ||||
|         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                      title=_(u"Newest Books")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
| @app.route('/books/oldest', defaults={'page': 1}) | ||||
| @app.route('/books/oldest/page/<int:page>') | ||||
| @login_required_if_no_ano | ||||
| def oldest_books(page): | ||||
|     entries, random, pagination = fill_indexpage(page, db.Books, True, db.Books.pubdate) | ||||
|     return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                  title=_(u"Oldest Books")) | ||||
|     if current_cuser.show_sorted(): | ||||
|         entries, random, pagination = fill_indexpage(page, db.Books, True, db.Books.pubdate) | ||||
|         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                      title=_(u"Oldest Books")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route('/books/a-z', defaults={'page': 1}) | ||||
| @app.route('/books/a-z/page/<int:page>') | ||||
| @login_required_if_no_ano | ||||
| def titles_ascending(page): | ||||
|     entries, random, pagination = fill_indexpage(page, db.Books, True, db.Books.sort) | ||||
|     return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                  title=_(u"Books (A-Z)")) | ||||
|     if current_cuser.show_sorted(): | ||||
|         entries, random, pagination = fill_indexpage(page, db.Books, True, db.Books.sort) | ||||
|         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                      title=_(u"Books (A-Z)")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route('/books/z-a', defaults={'page': 1}) | ||||
| @@ -1082,57 +1090,68 @@ def titles_descending(page): | ||||
| @app.route('/hot/page/<int:page>') | ||||
| @login_required_if_no_ano | ||||
| def hot_books(page): | ||||
|     if current_user.show_detail_random(): | ||||
|         random = db.session.query(db.Books).filter(common_filters())\ | ||||
|             .order_by(func.random()).limit(config.config_random_books) | ||||
|     else: | ||||
|         random = false | ||||
|     off = int(int(config.config_books_per_page) * (page - 1)) | ||||
|     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) | ||||
|     entries = list() | ||||
|     for book in hot_books: | ||||
|         downloadBook = db.session.query(db.Books).filter(common_filters()).filter(db.Books.id == book.Downloads.book_id).first() | ||||
|         if downloadBook: | ||||
|             entries.append(downloadBook) | ||||
|     if current_user.show_hot_books(): | ||||
|         if current_user.show_detail_random(): | ||||
|             random = db.session.query(db.Books).filter(common_filters())\ | ||||
|                 .order_by(func.random()).limit(config.config_random_books) | ||||
|         else: | ||||
|             ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete() | ||||
|             ub.session.commit() | ||||
|     numBooks = entries.__len__() | ||||
|     pagination = Pagination(page, config.config_books_per_page, numBooks) | ||||
|     return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                  title=_(u"Hot Books (most downloaded)")) | ||||
|             random = false | ||||
|         off = int(int(config.config_books_per_page) * (page - 1)) | ||||
|         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) | ||||
|         entries = list() | ||||
|         for book in hot_books: | ||||
|             downloadBook = db.session.query(db.Books).filter(common_filters()).filter(db.Books.id == book.Downloads.book_id).first() | ||||
|             if downloadBook: | ||||
|                 entries.append(downloadBook) | ||||
|             else: | ||||
|                 ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete() | ||||
|                 ub.session.commit() | ||||
|         numBooks = entries.__len__() | ||||
|         pagination = Pagination(page, config.config_books_per_page, numBooks) | ||||
|         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                      title=_(u"Hot Books (most downloaded)")) | ||||
|     else: | ||||
|        abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/rated", defaults={'page': 1}) | ||||
| @app.route('/rated/page/<int:page>') | ||||
| @login_required_if_no_ano | ||||
| def best_rated_books(page): | ||||
|     entries, random, pagination = fill_indexpage(page, db.Books, db.Books.ratings.any(db.Ratings.rating > 9), | ||||
|                                                  db.Books.timestamp.desc()) | ||||
|     return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                  title=_(u"Best rated books")) | ||||
|     if current_user.show_best_rated_books(): | ||||
|         entries, random, pagination = fill_indexpage(page, db.Books, db.Books.ratings.any(db.Ratings.rating > 9), | ||||
|                                                      db.Books.timestamp.desc()) | ||||
|         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||
|                                      title=_(u"Best rated books")) | ||||
|     abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/discover", defaults={'page': 1}) | ||||
| @app.route('/discover/page/<int:page>') | ||||
| @login_required_if_no_ano | ||||
| def discover(page): | ||||
|     entries, __, pagination = fill_indexpage(page, db.Books, True, func.randomblob(2)) | ||||
|     pagination = Pagination(1, config.config_books_per_page,config.config_books_per_page) | ||||
|     return render_title_template('discover.html', entries=entries, pagination=pagination, title=_(u"Random Books")) | ||||
|     if current_user.show_random_books(): | ||||
|         entries, __, pagination = fill_indexpage(page, db.Books, True, func.randomblob(2)) | ||||
|         pagination = Pagination(1, config.config_books_per_page,config.config_books_per_page) | ||||
|         return render_title_template('discover.html', entries=entries, pagination=pagination, title=_(u"Random Books")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/author") | ||||
| @login_required_if_no_ano | ||||
| def author_list(): | ||||
|     entries = db.session.query(db.Authors, func.count('books_authors_link.book').label('count'))\ | ||||
|         .join(db.books_authors_link).join(db.Books).filter(common_filters())\ | ||||
|         .group_by('books_authors_link.author').order_by(db.Authors.sort).all() | ||||
|     for entry in entries: | ||||
|         entry.Authors.name=entry.Authors.name.replace('|',',') | ||||
|     return render_title_template('list.html', entries=entries, folder='author', title=_(u"Author list")) | ||||
|     if current_user.show_author(): | ||||
|         entries = db.session.query(db.Authors, func.count('books_authors_link.book').label('count'))\ | ||||
|             .join(db.books_authors_link).join(db.Books).filter(common_filters())\ | ||||
|             .group_by('books_authors_link.author').order_by(db.Authors.sort).all() | ||||
|         for entry in entries: | ||||
|             entry.Authors.name=entry.Authors.name.replace('|',',') | ||||
|         return render_title_template('list.html', entries=entries, folder='author', title=_(u"Author list")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/author/<int:book_id>", defaults={'page': 1}) | ||||
| @@ -1181,10 +1200,13 @@ def get_unique_other_books(library_books, author_books): | ||||
| @app.route("/series") | ||||
| @login_required_if_no_ano | ||||
| def series_list(): | ||||
|     entries = db.session.query(db.Series, func.count('books_series_link.book').label('count'))\ | ||||
|         .join(db.books_series_link).join(db.Books).filter(common_filters())\ | ||||
|         .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")) | ||||
|     if current_user.show_series(): | ||||
|         entries = db.session.query(db.Series, func.count('books_series_link.book').label('count'))\ | ||||
|             .join(db.books_series_link).join(db.Books).filter(common_filters())\ | ||||
|             .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")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/series/<int:book_id>/", defaults={'page': 1}) | ||||
| @@ -1205,30 +1227,33 @@ def series(book_id, page): | ||||
| @app.route("/language") | ||||
| @login_required_if_no_ano | ||||
| def language_overview(): | ||||
|     if current_user.filter_language() == u"all": | ||||
|         languages = db.session.query(db.Languages).all() | ||||
|         for lang in languages: | ||||
|             try: | ||||
|                 cur_l = LC.parse(lang.lang_code) | ||||
|                 lang.name = cur_l.get_language_name(get_locale()) | ||||
|             except Exception: | ||||
|                 lang.name = _(isoLanguages.get(part3=lang.lang_code).name) | ||||
|     else: | ||||
|         try: | ||||
|             cur_l = LC.parse(current_user.filter_language()) | ||||
|         except Exception: | ||||
|             cur_l = None | ||||
|         languages = db.session.query(db.Languages).filter( | ||||
|             db.Languages.lang_code == current_user.filter_language()).all() | ||||
|         if cur_l: | ||||
|             languages[0].name = cur_l.get_language_name(get_locale()) | ||||
|     if current_user.show_language(): | ||||
|         if current_user.filter_language() == u"all": | ||||
|             languages = db.session.query(db.Languages).all() | ||||
|             for lang in languages: | ||||
|                 try: | ||||
|                     cur_l = LC.parse(lang.lang_code) | ||||
|                     lang.name = cur_l.get_language_name(get_locale()) | ||||
|                 except Exception: | ||||
|                     lang.name = _(isoLanguages.get(part3=lang.lang_code).name) | ||||
|         else: | ||||
|             languages[0].name = _(isoLanguages.get(part3=languages[0].lang_code).name) | ||||
|     lang_counter = db.session.query(db.books_languages_link, | ||||
|                                     func.count('books_languages_link.book').label('bookcount')).group_by( | ||||
|         'books_languages_link.lang_code').all() | ||||
|     return render_title_template('languages.html', languages=languages, lang_counter=lang_counter, | ||||
|                                  title=_(u"Available languages")) | ||||
|             try: | ||||
|                 cur_l = LC.parse(current_user.filter_language()) | ||||
|             except Exception: | ||||
|                 cur_l = None | ||||
|             languages = db.session.query(db.Languages).filter( | ||||
|                 db.Languages.lang_code == current_user.filter_language()).all() | ||||
|             if cur_l: | ||||
|                 languages[0].name = cur_l.get_language_name(get_locale()) | ||||
|             else: | ||||
|                 languages[0].name = _(isoLanguages.get(part3=languages[0].lang_code).name) | ||||
|         lang_counter = db.session.query(db.books_languages_link, | ||||
|                                         func.count('books_languages_link.book').label('bookcount')).group_by( | ||||
|             'books_languages_link.lang_code').all() | ||||
|         return render_title_template('languages.html', languages=languages, lang_counter=lang_counter, | ||||
|                                      title=_(u"Available languages")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/language/<name>", defaults={'page': 1}) | ||||
| @@ -1249,10 +1274,13 @@ def language(name, page): | ||||
| @app.route("/category") | ||||
| @login_required_if_no_ano | ||||
| def category_list(): | ||||
|     entries = db.session.query(db.Tags, func.count('books_tags_link.book').label('count'))\ | ||||
|         .join(db.books_tags_link).join(db.Books).order_by(db.Tags.name).filter(common_filters())\ | ||||
|         .group_by('books_tags_link.tag').all() | ||||
|     return render_title_template('list.html', entries=entries, folder='category', title=_(u"Category list")) | ||||
|     if current_user.show_category(): | ||||
|         entries = db.session.query(db.Tags, func.count('books_tags_link.book').label('count'))\ | ||||
|             .join(db.books_tags_link).join(db.Books).order_by(db.Tags.name).filter(common_filters())\ | ||||
|             .group_by('books_tags_link.tag').all() | ||||
|         return render_title_template('list.html', entries=entries, folder='category', title=_(u"Category list")) | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
|  | ||||
| @app.route("/category/<int:book_id>", defaults={'page': 1}) | ||||
| @@ -2307,6 +2335,10 @@ def profile(): | ||||
|             content.sidebar_view += ub.SIDEBAR_SERIES | ||||
|         if "show_category" in to_save: | ||||
|             content.sidebar_view += ub.SIDEBAR_CATEGORY | ||||
|         if "show_recent" in to_save: | ||||
|             content.sidebar_view += ub.SIDEBAR_RECENT | ||||
|         if "show_sorted" in to_save: | ||||
|             content.sidebar_view += ub.SIDEBAR_SORTED | ||||
|         if "show_hot" in to_save: | ||||
|             content.sidebar_view += ub.SIDEBAR_HOT | ||||
|         if "show_best_rated" in to_save: | ||||
| @@ -2689,6 +2721,16 @@ def edit_user(user_id): | ||||
|             elif "show_category" not in to_save and content.show_category(): | ||||
|                 content.sidebar_view -= ub.SIDEBAR_CATEGORY | ||||
|  | ||||
|             if "show_recent" in to_save and not content.show_recent(): | ||||
|                 content.sidebar_view += ub.SIDEBAR_RECENT | ||||
|             elif "show_recent" not in to_save and content.show_recent(): | ||||
|                 content.sidebar_view -= ub.SIDEBAR_RECENT | ||||
|  | ||||
|             if "show_sorted" in to_save and not content.show_sorted(): | ||||
|                 content.sidebar_view += ub.SIDEBAR_SORTED | ||||
|             elif "show_sorted" not in to_save and content.show_sorted(): | ||||
|                 content.sidebar_view -= ub.SIDEBAR_SORTED | ||||
|  | ||||
|             if "show_hot" in to_save and not content.show_hot_books(): | ||||
|                 content.sidebar_view += ub.SIDEBAR_HOT | ||||
|             elif "show_hot" not in to_save and content.show_hot_books(): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 OzzieIsaacs
					OzzieIsaacs