mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 07:13:02 +00:00 
			
		
		
		
	Fix pdf cover
Fix massadding books Add feature inform of duplicate books
This commit is contained in:
		| @@ -567,6 +567,12 @@ def upload(): | ||||
|             filepath = os.path.join(config.config_calibre_dir, author_dir, title_dir) | ||||
|             saved_filename = os.path.join(filepath, title_dir + meta.extension.lower()) | ||||
|  | ||||
|             if unicode(title) != u'Unknown' and unicode(authr) != u'Unknown': | ||||
|                 entry = helper.check_exists_book(authr, title) | ||||
|                 if entry: | ||||
|                     book_html = flash(_(u"Uploaded book probably exists in the library, consider to change before upload new: ") | ||||
|                         + Markup(render_title_template('book_exists_flash.html', entry=entry)), category="warning") | ||||
|  | ||||
|             # check if file path exists, otherwise create it, copy file to calibre path and delete temp file | ||||
|             if not os.path.exists(filepath): | ||||
|                 try: | ||||
|   | ||||
| @@ -780,7 +780,17 @@ def get_download_link(book_id, book_format): | ||||
|     else: | ||||
|         abort(404) | ||||
|  | ||||
| def check_exists_book(authr,title): | ||||
|     db.session.connection().connection.connection.create_function("lower", 1, lcase) | ||||
|     q = list() | ||||
|     authorterms = re.split(r'\s*&\s*', authr) | ||||
|     for authorterm in authorterms: | ||||
|         q.append(db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + authorterm + "%"))) | ||||
|  | ||||
|     return db.session.query(db.Books).filter( | ||||
|         and_(db.Books.authors.any(and_(*q)), | ||||
|             func.lower(db.Books.title).ilike("%" + title + "%") | ||||
|             )).first() | ||||
|  | ||||
| ############### Database Helper functions | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								cps/templates/book_exists_flash.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								cps/templates/book_exists_flash.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"> | ||||
| 	<span class="title">{{entry.title|shortentitle}}</span> | ||||
| </a> | ||||
| @@ -99,6 +99,11 @@ | ||||
|         <div id="flash_info" class="alert alert-info">{{ message[1] }}</div> | ||||
|       </div> | ||||
|       {%endif%} | ||||
|       {%if message[0] == "warning" %} | ||||
|       <div class="row-fluid text-center" style="margin-top: -20px;"> | ||||
|         <div id="flash_warning" class="alert alert-warning">{{ message[1] }}</div> | ||||
|       </div> | ||||
|       {%endif%} | ||||
|       {%if message[0] == "success" %} | ||||
|       <div class="row-fluid text-center" style="margin-top: -20px;"> | ||||
|         <div id="flash_success" class="alert alert-success">{{ message[1] }}</div> | ||||
|   | ||||
							
								
								
									
										65
									
								
								cps/tess.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								cps/tess.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 -*- | ||||
|  | ||||
| #  This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) | ||||
| #    Copyright (C) 2018-2019 OzzieIsaacs | ||||
| # | ||||
| #  This program is free software: you can redistribute it and/or modify | ||||
| #  it under the terms of the GNU General Public License as published by | ||||
| #  the Free Software Foundation, either version 3 of the License, or | ||||
| #  (at your option) any later version. | ||||
| # | ||||
| #  This program is distributed in the hope that it will be useful, | ||||
| #  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| #  GNU General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public License | ||||
| #  along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| from subproc_wrapper import process_open, cmdlineCall | ||||
| import os | ||||
| import sys | ||||
| import re | ||||
| import time | ||||
|  | ||||
| def main(): | ||||
|     quotes = [1, 2] | ||||
|     format_new_ext = '.mobi' | ||||
|     format_old_ext = '.epub' | ||||
|     file_path = '/home/matthias/Dokumente/bücher/Bettina Szramah/Die Giftmischerin TCP_IP (10)/Die Giftmischerin TCP_IP - Bettina, Szrama' | ||||
|     command = ['/opt/calibre/ebook-convert', (file_path + format_old_ext), | ||||
|                (file_path + format_new_ext)] | ||||
|  | ||||
|     #print(command) | ||||
|     #p1 = cmdlineCall(command[0],command[1:]) | ||||
|     #time.sleep(10) | ||||
|     #print(p1) | ||||
|  | ||||
|     p = process_open(command, quotes) | ||||
|     while p.poll() is None: | ||||
|         nextline = p.stdout.readline() | ||||
|         if os.name == 'nt' and sys.version_info < (3, 0): | ||||
|             nextline = nextline.decode('windows-1252') | ||||
|         elif os.name == 'posix' and sys.version_info < (3, 0): | ||||
|             nextline = nextline.decode('utf-8') | ||||
|         # log.debug(nextline.strip('\r\n')) | ||||
|         # parse progress string from calibre-converter | ||||
|         progress = re.search(r"(\d+)%\s.*", nextline) | ||||
|         if progress: | ||||
|             print('Progress:' + str(progress)) | ||||
|             # self.UIqueue[index]['progress'] = progress.group(1) + ' % | ||||
|  | ||||
|     # process returncode | ||||
|     check = p.returncode | ||||
|     calibre_traceback = p.stderr.readlines() | ||||
|     for ele in calibre_traceback: | ||||
|         if sys.version_info < (3, 0): | ||||
|             ele = ele.decode('utf-8') | ||||
|         print(ele.strip('\n')) | ||||
|         if not ele.startswith('Traceback') and not ele.startswith('  File'): | ||||
|             print( "Calibre failed with error: %s" % ele.strip('\n')) | ||||
|     print(str(check)) | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     main() | ||||
| @@ -65,7 +65,7 @@ except ImportError as e: | ||||
|     use_fb2_meta = False | ||||
|  | ||||
| try: | ||||
|     from PIL import PILImage | ||||
|     from PIL import Image as PILImage | ||||
|     from PIL import __version__ as PILversion | ||||
|     use_PIL = True | ||||
| except ImportError as e: | ||||
|   | ||||
| @@ -193,21 +193,27 @@ class WorkerThread(threading.Thread): | ||||
|     def run(self): | ||||
|         main_thread = _get_main_thread() | ||||
|         while main_thread.is_alive(): | ||||
|             self.doLock.acquire() | ||||
|             if self.current != self.last: | ||||
|                 index = self.current | ||||
|                 self.doLock.release() | ||||
|                 if self.queue[index]['taskType'] == TASK_EMAIL: | ||||
|                     self._send_raw_email() | ||||
|                 if self.queue[index]['taskType'] == TASK_CONVERT: | ||||
|                     self._convert_any_format() | ||||
|                 if self.queue[index]['taskType'] == TASK_CONVERT_ANY: | ||||
|                     self._convert_any_format() | ||||
|                 # TASK_UPLOAD is handled implicitly | ||||
|             try: | ||||
|                 self.doLock.acquire() | ||||
|                 self.current += 1 | ||||
|                 self.doLock.release() | ||||
|             else: | ||||
|                 if self.current != self.last: | ||||
|                     index = self.current | ||||
|                     self.doLock.release() | ||||
|                     if self.queue[index]['taskType'] == TASK_EMAIL: | ||||
|                         self._send_raw_email() | ||||
|                     if self.queue[index]['taskType'] == TASK_CONVERT: | ||||
|                         self._convert_any_format() | ||||
|                     if self.queue[index]['taskType'] == TASK_CONVERT_ANY: | ||||
|                         self._convert_any_format() | ||||
|                     # TASK_UPLOAD is handled implicitly | ||||
|                     self.doLock.acquire() | ||||
|                     self.current += 1 | ||||
|                     if self.current > self.last: | ||||
|                         self.current = self.last | ||||
|                     self.doLock.release() | ||||
|                 else: | ||||
|                     self.doLock.release() | ||||
|             except Exception as e: | ||||
| 				log.exception(e) | ||||
|                 self.doLock.release() | ||||
|             if main_thread.is_alive(): | ||||
|                 time.sleep(1) | ||||
| @@ -225,7 +231,8 @@ class WorkerThread(threading.Thread): | ||||
|                 self.queue.pop(index) | ||||
|                 self.UIqueue.pop(index) | ||||
|                 # if we are deleting entries before the current index, adjust the index | ||||
|                 self.current -= 1 | ||||
|                 if index <= self.current and index: | ||||
|                     self.current -= 1 | ||||
|         self.last = len(self.queue) | ||||
|  | ||||
|     def get_taskstatus(self): | ||||
| @@ -248,7 +255,7 @@ class WorkerThread(threading.Thread): | ||||
|         self.doLock.release() | ||||
|         self.UIqueue[index]['stat'] = STAT_STARTED | ||||
|         self.queue[index]['starttime'] = datetime.now() | ||||
|         self.UIqueue[index]['formStarttime'] = self.queue[self.current]['starttime'] | ||||
|         self.UIqueue[index]['formStarttime'] = self.queue[index]['starttime'] | ||||
|         curr_task = self.queue[index]['taskType'] | ||||
|         filename = self._convert_ebook_format() | ||||
|         if filename: | ||||
| @@ -390,8 +397,7 @@ class WorkerThread(threading.Thread): | ||||
|  | ||||
|  | ||||
|     def add_convert(self, file_path, bookid, user_name, taskMessage, settings, kindle_mail=None): | ||||
|         addLock = threading.Lock() | ||||
|         addLock.acquire() | ||||
|         self.doLock.acquire() | ||||
|         if self.last >= 20: | ||||
|             self._delete_completed_tasks() | ||||
|         # progress, runtime, and status = 0 | ||||
| @@ -405,13 +411,12 @@ class WorkerThread(threading.Thread): | ||||
|                              'runtime': '0 s', 'stat': STAT_WAITING,'id': self.id, 'taskType': task } ) | ||||
|  | ||||
|         self.last=len(self.queue) | ||||
|         addLock.release() | ||||
|         self.doLock.release() | ||||
|  | ||||
|     def add_email(self, subject, filepath, attachment, settings, recipient, user_name, taskMessage, | ||||
|                   text): | ||||
|         # if more than 20 entries in the list, clean the list | ||||
|         addLock = threading.Lock() | ||||
|         addLock.acquire() | ||||
|         self.doLock.acquire() | ||||
|         if self.last >= 20: | ||||
|             self._delete_completed_tasks() | ||||
|         # progress, runtime, and status = 0 | ||||
| @@ -422,23 +427,31 @@ class WorkerThread(threading.Thread): | ||||
|         self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'taskMess': taskMessage, | ||||
|                              'runtime': '0 s', 'stat': STAT_WAITING,'id': self.id, 'taskType': TASK_EMAIL }) | ||||
|         self.last=len(self.queue) | ||||
|         addLock.release() | ||||
|         self.doLock.release() | ||||
|  | ||||
|     def add_upload(self, user_name, taskMessage): | ||||
|         # if more than 20 entries in the list, clean the list | ||||
|         addLock = threading.Lock() | ||||
|         addLock.acquire() | ||||
|         self.doLock.acquire() | ||||
|  | ||||
|  | ||||
|         if self.last >= 20: | ||||
|             self._delete_completed_tasks() | ||||
|         # progress=100%, runtime=0, and status finished | ||||
|         self.id += 1 | ||||
|         self.queue.append({'starttime': datetime.now(), 'taskType': TASK_UPLOAD}) | ||||
|         self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': "100 %", 'taskMess': taskMessage, | ||||
|                              'runtime': '0 s', 'stat': STAT_FINISH_SUCCESS,'id': self.id, 'taskType': TASK_UPLOAD}) | ||||
|         self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime'] | ||||
|         self.last=len(self.queue) | ||||
|         addLock.release() | ||||
|         log.info("Last " + str(self.last)) | ||||
|         log.info("Current " + str(self.current)) | ||||
|         log.info("id" + str(self.id)) | ||||
|         for i in range(0, len(self.queue)): | ||||
|             message = '%s:%s' % (i, self.queue[i].items()) | ||||
|             log.info(message) | ||||
|  | ||||
|         self.id += 1 | ||||
|         starttime = datetime.now() | ||||
|         self.queue.append({'starttime': starttime, 'taskType': TASK_UPLOAD}) | ||||
|         self.UIqueue.append({'user': user_name, 'formStarttime': starttime, 'progress': "100 %", 'taskMess': taskMessage, | ||||
|                              'runtime': '0 s', 'stat': STAT_FINISH_SUCCESS,'id': self.id, 'taskType': TASK_UPLOAD}) | ||||
|         # self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime'] | ||||
|         self.last=len(self.queue) | ||||
|         self.doLock.release() | ||||
|  | ||||
|     def _send_raw_email(self): | ||||
|         self.doLock.acquire() | ||||
| @@ -525,7 +538,7 @@ class WorkerThread(threading.Thread): | ||||
|         self.doLock.release() | ||||
|         self.UIqueue[index]['stat'] = STAT_FAIL | ||||
|         self.UIqueue[index]['progress'] = "100 %" | ||||
|         self.UIqueue[index]['formRuntime'] = datetime.now() - self.queue[self.current]['starttime'] | ||||
|         self.UIqueue[index]['formRuntime'] = datetime.now() - self.queue[index]['starttime'] | ||||
|         self.UIqueue[index]['message'] = error_message | ||||
|  | ||||
|     def _handleSuccess(self): | ||||
| @@ -534,7 +547,7 @@ class WorkerThread(threading.Thread): | ||||
|         self.doLock.release() | ||||
|         self.UIqueue[index]['stat'] = STAT_FINISH_SUCCESS | ||||
|         self.UIqueue[index]['progress'] = "100 %" | ||||
|         self.UIqueue[index]['formRuntime'] = datetime.now() - self.queue[self.current]['starttime'] | ||||
|         self.UIqueue[index]['formRuntime'] = datetime.now() - self.queue[index]['starttime'] | ||||
|  | ||||
|  | ||||
| _worker = WorkerThread() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ozzieisaacs
					Ozzieisaacs