mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-25 20:37:41 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/janeczku/calibre-web into 617
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | ||||
| helper.py ident export-subst | ||||
| /test export-ignore | ||||
| cps/static/css/libs/* linguist-vendored | ||||
| cps/static/js/libs/* linguist-vendored | ||||
|   | ||||
| @@ -236,8 +236,8 @@ def update_dir_structure_file(book_id, calibrepath): | ||||
|             path = new_title_path | ||||
|             localbook.path = localbook.path.split('/')[0] + '/' + new_titledir | ||||
|         except OSError as ex: | ||||
|             web.app.logger.error("Rename title from: " + path + " to " + new_title_path) | ||||
|             web.app.logger.error(ex, exc_info=True) | ||||
|             web.app.logger.error("Rename title from: " + path + " to " + new_title_path + ": " + str(ex)) | ||||
|             web.app.logger.debug(ex, exc_info=True) | ||||
|             return _("Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s", src=path, dest=new_title_path, error=str(ex)) | ||||
|     if authordir != new_authordir: | ||||
|         try: | ||||
| @@ -245,9 +245,9 @@ def update_dir_structure_file(book_id, calibrepath): | ||||
|             os.renames(path, new_author_path) | ||||
|             localbook.path = new_authordir + '/' + localbook.path.split('/')[1] | ||||
|         except OSError as ex: | ||||
|             web.app.logger.error("Rename author from: " + path + " to " + new_author_path) | ||||
|             web.app.logger.error(ex, exc_info=True) | ||||
|             return _("Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s", src=path, dest=new_title_path, error=str(ex)) | ||||
|             web.app.logger.error("Rename author from: " + path + " to " + new_author_path + ": " + str(ex)) | ||||
|             web.app.logger.debug(ex, exc_info=True) | ||||
|             return _("Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s", src=path, dest=new_author_path, error=str(ex)) | ||||
|     return False | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,9 +6,9 @@ | ||||
|   <div class="col-sm-3 col-lg-3 col-xs-12"> | ||||
|     <div class="cover"> | ||||
|       {% if book.has_cover %} | ||||
|         <img src="{{ url_for('get_cover', cover_path=book.path.replace('\\','/')) }}" /> | ||||
|         <img src="{{ url_for('get_cover', cover_path=book.path.replace('\\','/')) }}" alt="{{ book.title }}"/> | ||||
|       {% else %} | ||||
|         <img src="{{ url_for('static', filename='generic_cover.jpg') }}" /> | ||||
|         <img src="{{ url_for('static', filename='generic_cover.jpg') }}" alt="{{ book.title }}"/> | ||||
|       {% endif %} | ||||
|     </div> | ||||
| {% if g.user.role_delete_books() %} | ||||
| @@ -174,7 +174,7 @@ | ||||
|       </label> | ||||
|     </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> | ||||
|     <button type="submit" id="submit" class="btn btn-default">{{_('Submit')}}</button> | ||||
|     <a href="{{ url_for('show_book', book_id=book.id) }}" class="btn btn-default">{{_('Back')}}</a> | ||||
|   </div> | ||||
| </form> | ||||
|   | ||||
| @@ -250,7 +250,7 @@ | ||||
|       {% if g.user.role_edit() %} | ||||
|       <div class="btn-toolbar" role="toolbar"> | ||||
|         <div class="btn-group" role="group" aria-label="Edit/Delete book"> | ||||
|           <a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" role="button"><span class="glyphicon glyphicon-edit"></span> {{_('Edit metadata')}}</a> | ||||
|           <a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" id="edit_book" role="button"><span class="glyphicon glyphicon-edit"></span> {{_('Edit metadata')}}</a> | ||||
|         </div> | ||||
|       </div> | ||||
|       {% endif %} | ||||
|   | ||||
							
								
								
									
										16
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cps/web.py
									
									
									
									
									
								
							| @@ -173,7 +173,12 @@ cache_buster.init_cache_busting(app) | ||||
|  | ||||
| formatter = logging.Formatter( | ||||
|     "[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s") | ||||
| file_handler = RotatingFileHandler(config.get_config_logfile(), maxBytes=50000, backupCount=2) | ||||
| try: | ||||
|     file_handler = RotatingFileHandler(config.get_config_logfile(), maxBytes=50000, backupCount=2) | ||||
| except IOError: | ||||
|     file_handler = RotatingFileHandler(os.path.join(config.get_main_dir, "calibre-web.log"), | ||||
|                                        maxBytes=50000, backupCount=2) | ||||
|     # ToDo: reset logfile value in config class | ||||
| file_handler.setFormatter(formatter) | ||||
| app.logger.addHandler(file_handler) | ||||
| app.logger.setLevel(config.config_log_level) | ||||
| @@ -208,7 +213,8 @@ def get_locale(): | ||||
|     # if a user is logged in, use the locale from the user settings | ||||
|     user = getattr(g, 'user', None) | ||||
|     if user is not None and hasattr(user, "locale"): | ||||
|         return user.locale | ||||
|         if user.nickname != 'Guest':   # if the account is the guest account bypass the config lang settings | ||||
|             return user.locale | ||||
|     translations = [item.language for item in babel.list_translations()] + ['en'] | ||||
|     preferred = [x.replace('-', '_') for x in request.accept_languages.values()] | ||||
|     return negotiate_locale(preferred, translations) | ||||
| @@ -3582,10 +3588,10 @@ def edit_book(book_id): | ||||
|         # Update book | ||||
|         edited_books_id = None | ||||
|         #handle book title | ||||
|         if book.title != to_save["book_title"]: | ||||
|         if book.title != to_save["book_title"].rstrip().strip(): | ||||
|             if to_save["book_title"] == '': | ||||
|                 to_save["book_title"] = _(u'unknown') | ||||
|             book.title = to_save["book_title"] | ||||
|             book.title = to_save["book_title"].rstrip().strip() | ||||
|             edited_books_id = book.id | ||||
|  | ||||
|         # handle author(s) | ||||
| @@ -3610,8 +3616,6 @@ def edit_book(book_id): | ||||
|         error = False | ||||
|         if edited_books_id: | ||||
|             error = helper.update_dir_stucture(edited_books_id, config.config_calibre_dir) | ||||
|             if error:   # stop on error | ||||
|                 flash(error, category="error") | ||||
|  | ||||
|         if not error: | ||||
|             if to_save["cover_url"]: | ||||
|   | ||||
							
								
								
									
										2481
									
								
								test/Calibre-Web TestSummary.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2481
									
								
								test/Calibre-Web TestSummary.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								test/css/runner.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								test/css/runner.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| .hiddenRow { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .bg-grey { | ||||
|   background-color: rgba(0, 0, 0, 0.03); | ||||
| } | ||||
|  | ||||
| .table-curved { | ||||
|   border-radius: 20px; | ||||
| } | ||||
|  | ||||
| .buttons, .report-description { | ||||
|   margin: 5px; | ||||
|   padding: 5px; | ||||
| } | ||||
|  | ||||
| .piechart{ | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
							
								
								
									
										189
									
								
								test/js/runner.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								test/js/runner.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| output_list = Array(); | ||||
|  | ||||
| /* Level - 0: Summary; 1: Failed; 2: All; 3: Skipped */ | ||||
| function showCase(level) { | ||||
|     table_rows = document.getElementsByTagName("tr"); | ||||
|     for (var i = 0; i < table_rows.length; i++) { | ||||
|         row = table_rows[i]; | ||||
|         id = row.id; | ||||
|         if (id.substr(0,2) == 'ft') { | ||||
|             if (level < 1 || level == 3) { | ||||
|                 row.classList.add('hiddenRow'); | ||||
|             } | ||||
|             else { | ||||
|                 row.classList.remove('hiddenRow'); | ||||
|             } | ||||
|         } | ||||
|         if (id.substr(0,2) == 'pt') { | ||||
|             if (level > 1 && level != 3) { | ||||
|                 row.classList.remove('hiddenRow'); | ||||
|             } | ||||
|             else { | ||||
|                 row.classList.add('hiddenRow'); | ||||
|             } | ||||
|         } | ||||
|         if (id.substr(0,2) == 'st') { | ||||
|             if (level >=2) {  | ||||
|                 row.classList.remove('hiddenRow'); | ||||
|             } | ||||
|             else { | ||||
|                 row.classList.add('hiddenRow'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| 		 | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function showClassDetail(class_id, count) { | ||||
|     var testcases_list = Array(count); | ||||
|     var all_hidden = true; | ||||
|     for (var i = 0; i < count; i++) { | ||||
|         testcase_postfix_id = 't' + class_id.substr(1) + '.' + (i+1); | ||||
|         testcase_id = 'f' + testcase_postfix_id; | ||||
|         testcase = document.getElementById(testcase_id); | ||||
|         if (!testcase) { | ||||
|             testcase_id = 'p' + testcase_postfix_id; | ||||
|             testcase = document.getElementById(testcase_id); | ||||
|         } | ||||
|         if (!testcase) { | ||||
|             testcase_id = 's' + testcase_postfix_id; | ||||
|             testcase = document.getElementById(testcase_id); | ||||
|         } | ||||
|         testcases_list[i] = testcase; | ||||
|         if (testcase.classList.contains('hiddenRow')) { | ||||
|             all_hidden = false; | ||||
|         } | ||||
|     } | ||||
|     for (var i = 0; i < count; i++) { | ||||
|         testcase = testcases_list[i]; | ||||
|         if (!all_hidden) { | ||||
|             testcase.classList.remove('hiddenRow'); | ||||
|         } | ||||
|         else { | ||||
|             testcase.classList.add('hiddenRow'); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function showTestDetail(div_id){ | ||||
|     var details_div = document.getElementById(div_id) | ||||
|     var displayState = details_div.style.display | ||||
|     // alert(displayState) | ||||
|     if (displayState != 'block' ) { | ||||
|         displayState = 'block' | ||||
|         details_div.style.display = 'block' | ||||
|     } | ||||
|     else { | ||||
|         details_div.style.display = 'none' | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function html_escape(s) { | ||||
|     s = s.replace(/&/g,'&'); | ||||
|     s = s.replace(/</g,'<'); | ||||
|     s = s.replace(/>/g,'>'); | ||||
|     return s; | ||||
| } | ||||
|  | ||||
| /* obsoleted by detail in <div> | ||||
| function showOutput(id, name) { | ||||
|     var w = window.open("", //url | ||||
|                     name, | ||||
|                     "resizable,scrollbars,status,width=800,height=450"); | ||||
|     d = w.document; | ||||
|     d.write("<pre>"); | ||||
|     d.write(html_escape(output_list[id])); | ||||
|     d.write("\n"); | ||||
|     d.write("<a href='javascript:window.close()'>close</a>\n"); | ||||
|     d.write("</pre>\n"); | ||||
|     d.close(); | ||||
| } | ||||
| */ | ||||
| function drawCircle(pass, fail, error, skip){ | ||||
|     var color = ["#5cb85c","#d9534f","#c00","#f0ad4e"]; | ||||
|     var data = [pass,fail,error,skip]; | ||||
|     var text_arr = ["pass", "fail", "error","skip"]; | ||||
|  | ||||
|     var canvas = document.getElementById("circle");   | ||||
|     var ctx = canvas.getContext("2d");   | ||||
|     var startPoint=0; | ||||
|     var width = 20, height = 10; | ||||
|     var posX = 112 * 2 + 20, posY = 30; | ||||
|     var textX = posX + width + 5, textY = posY + 10; | ||||
|     for(var i=0;i<data.length;i++){   | ||||
|         ctx.fillStyle = color[i];   | ||||
|         ctx.beginPath();   | ||||
|         ctx.moveTo(112,84);    | ||||
|         ctx.arc(112,84,84,startPoint,startPoint+Math.PI*2*(data[i]/(data[0]+data[1]+data[2]+data[3])),false); | ||||
|         ctx.fill();   | ||||
|         startPoint += Math.PI*2*(data[i]/(data[0]+data[1]+data[2]+data[3])); | ||||
|         ctx.fillStyle = color[i];   | ||||
|         ctx.fillRect(posX, posY + 20 * i, width, height);   | ||||
|         ctx.moveTo(posX, posY + 20 * i);   | ||||
|         ctx.font = 'bold 14px'; | ||||
|         ctx.fillStyle = color[i]; | ||||
|         var percent = text_arr[i] + ":"+data[i];   | ||||
|         ctx.fillText(percent, textX, textY + 20 * i);   | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function show_img(obj) { | ||||
|     var obj1 = obj.nextElementSibling | ||||
|     obj1.style.display='block' | ||||
|     var index = 0;//每张图片的下标, | ||||
|     var len = obj1.getElementsByTagName('img').length; | ||||
|     var imgyuan = obj1.getElementsByClassName('imgyuan')[0] | ||||
|     //var start=setInterval(autoPlay,500); | ||||
|     obj1.onmouseover=function(){//当鼠标光标停在图片上,则停止轮播 | ||||
|         clearInterval(start); | ||||
|     } | ||||
|     obj1.onmouseout=function(){//当鼠标光标停在图片上,则开始轮播 | ||||
|         start=setInterval(autoPlay,1000); | ||||
|     }     | ||||
|     for (var i = 0; i < len; i++) { | ||||
|         var font = document.createElement('font') | ||||
|         imgyuan.appendChild(font) | ||||
|     } | ||||
|     var lis = obj1.getElementsByTagName('font');//得到所有圆圈 | ||||
|     changeImg(0) | ||||
|     var funny = function (i) { | ||||
|         lis[i].onmouseover = function () { | ||||
|             index=i | ||||
|             changeImg(i) | ||||
|         } | ||||
|     } | ||||
|     for (var i = 0; i < lis.length; i++) { | ||||
|         funny(i); | ||||
|     } | ||||
|      | ||||
|     function autoPlay(){ | ||||
|         if(index>len-1){ | ||||
|             index=0; | ||||
|             clearInterval(start); //运行一轮后停止 | ||||
|         } | ||||
|         changeImg(index++); | ||||
|     } | ||||
|     imgyuan.style.width= 25*len +"px"; | ||||
|     //对应圆圈和图片同步 | ||||
|     function changeImg(index) { | ||||
|         var list = obj1.getElementsByTagName('img'); | ||||
|         var list1 = obj1.getElementsByTagName('font'); | ||||
|         for (i = 0; i < list.length; i++) { | ||||
|             list[i].style.display = 'none'; | ||||
|             list1[i].style.backgroundColor = 'white'; | ||||
|         } | ||||
|         list[index].style.display = 'block'; | ||||
|         list1[index].style.backgroundColor = 'blue'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| function hide_img(obj){ | ||||
|     obj.parentElement.style.display = "none"; | ||||
|     obj.parentElement.getElementsByClassName('imgyuan')[0].innerHTML = ""; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 bodybybuddha
					bodybybuddha