Merge branch 'master' into Develop
This commit is contained in:
		
						commit
						59987ed359
					
				| 
						 | 
				
			
			@ -2,7 +2,12 @@
 | 
			
		|||
 | 
			
		||||
Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing [Calibre](https://calibre-ebook.com) database.
 | 
			
		||||
 | 
			
		||||
   [](https://discord.gg/h2VsJ2NEfB) 
 | 
			
		||||
[](https://github.com/janeczku/calibre-web/blob/master/LICENSE)
 | 
			
		||||
[]()
 | 
			
		||||
[](https://github.com/janeczku/calibre-web/releases)
 | 
			
		||||
[](https://pypi.org/project/calibreweb/)
 | 
			
		||||
[](https://pypi.org/project/calibreweb/)
 | 
			
		||||
[](https://discord.gg/h2VsJ2NEfB)
 | 
			
		||||
 | 
			
		||||
*This software is a fork of [library](https://github.com/mutschler/calibreserver) and licensed under the GPL v3 License.*
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1148,11 +1148,15 @@ def edit_list_book(param):
 | 
			
		|||
                                   'newValue':  ' & '.join([author.replace('|',',') for author in input_authors])}),
 | 
			
		||||
                       mimetype='application/json')
 | 
			
		||||
    book.last_modified = datetime.utcnow()
 | 
			
		||||
    calibre_db.session.commit()
 | 
			
		||||
    # revert change for sort if automatic fields link is deactivated
 | 
			
		||||
    if param == 'title' and vals.get('checkT') == "false":
 | 
			
		||||
        book.sort = sort
 | 
			
		||||
    try:
 | 
			
		||||
        calibre_db.session.commit()
 | 
			
		||||
        # revert change for sort if automatic fields link is deactivated
 | 
			
		||||
        if param == 'title' and vals.get('checkT') == "false":
 | 
			
		||||
            book.sort = sort
 | 
			
		||||
            calibre_db.session.commit()
 | 
			
		||||
    except (OperationalError, IntegrityError) as e:
 | 
			
		||||
        calibre_db.session.rollback()
 | 
			
		||||
        log.error("Database error: %s", e)
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1224,3 +1228,43 @@ def merge_list_book():
 | 
			
		|||
                    delete_book(from_book.id,"", True)
 | 
			
		||||
                    return json.dumps({'success': True})
 | 
			
		||||
    return ""
 | 
			
		||||
 | 
			
		||||
@editbook.route("/ajax/xchange", methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
@edit_required
 | 
			
		||||
def table_xchange_author_title():
 | 
			
		||||
    vals = request.get_json().get('xchange')
 | 
			
		||||
    if vals:
 | 
			
		||||
        for val in vals:
 | 
			
		||||
            modif_date = False
 | 
			
		||||
            book = calibre_db.get_book(val)
 | 
			
		||||
            authors = book.title
 | 
			
		||||
            entries = calibre_db.order_authors(book)
 | 
			
		||||
            author_names = []
 | 
			
		||||
            for authr in entries.authors:
 | 
			
		||||
                author_names.append(authr.name.replace('|', ','))
 | 
			
		||||
 | 
			
		||||
            title_change = handle_title_on_edit(book, " ".join(author_names))
 | 
			
		||||
            input_authors, authorchange = handle_author_on_edit(book, authors)
 | 
			
		||||
            if authorchange or title_change:
 | 
			
		||||
                edited_books_id = book.id
 | 
			
		||||
                modif_date = True
 | 
			
		||||
 | 
			
		||||
            if config.config_use_google_drive:
 | 
			
		||||
                gdriveutils.updateGdriveCalibreFromLocal()
 | 
			
		||||
 | 
			
		||||
            if edited_books_id:
 | 
			
		||||
                helper.update_dir_stucture(edited_books_id, config.config_calibre_dir, input_authors[0])
 | 
			
		||||
            if modif_date:
 | 
			
		||||
                book.last_modified = datetime.utcnow()
 | 
			
		||||
            try:
 | 
			
		||||
                calibre_db.session.commit()
 | 
			
		||||
            except (OperationalError, IntegrityError) as e:
 | 
			
		||||
                calibre_db.session.rollback()
 | 
			
		||||
                log.error("Database error: %s", e)
 | 
			
		||||
                return json.dumps({'success': False})
 | 
			
		||||
 | 
			
		||||
            if config.config_use_google_drive:
 | 
			
		||||
                gdriveutils.updateGdriveCalibreFromLocal()
 | 
			
		||||
        return json.dumps({'success': True})
 | 
			
		||||
    return ""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,9 +46,14 @@ $(function() {
 | 
			
		|||
            if (selections.length < 1) {
 | 
			
		||||
                $("#delete_selection").addClass("disabled");
 | 
			
		||||
                $("#delete_selection").attr("aria-disabled", true);
 | 
			
		||||
                $("#table_xchange").addClass("disabled");
 | 
			
		||||
                $("#table_xchange").attr("aria-disabled", true);
 | 
			
		||||
            } else {
 | 
			
		||||
                $("#delete_selection").removeClass("disabled");
 | 
			
		||||
                $("#delete_selection").attr("aria-disabled", false);
 | 
			
		||||
                $("#table_xchange").removeClass("disabled");
 | 
			
		||||
                $("#table_xchange").attr("aria-disabled", false);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    $("#delete_selection").click(function() {
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +91,20 @@ $(function() {
 | 
			
		|||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#table_xchange").click(function() {
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            method:"post",
 | 
			
		||||
            contentType: "application/json; charset=utf-8",
 | 
			
		||||
            dataType: "json",
 | 
			
		||||
            url: window.location.pathname + "/../../ajax/xchange",
 | 
			
		||||
            data: JSON.stringify({"xchange":selections}),
 | 
			
		||||
            success: function success() {
 | 
			
		||||
                $("#books-table").bootstrapTable("refresh");
 | 
			
		||||
                $("#books-table").bootstrapTable("uncheckAll");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var column = [];
 | 
			
		||||
    $("#books-table > thead > tr > th").each(function() {
 | 
			
		||||
        var element = {};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,17 +20,20 @@
 | 
			
		|||
{% block body %}
 | 
			
		||||
<h2 class="{{page}}">{{_(title)}}</h2>
 | 
			
		||||
      <div class="col-xs-12 col-sm-6">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
        <div class="row form-group">
 | 
			
		||||
          <div class="btn btn-default disabled" id="merge_books" data-toggle="modal" data-target="#mergeModal" aria-disabled="true">{{_('Merge selected books')}}</div>
 | 
			
		||||
          <div class="btn btn-default disabled" id="delete_selection" aria-disabled="true">{{_('Remove Selections')}}</div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row form-group">
 | 
			
		||||
            <div class="btn btn-default disabled" id="table_xchange" ><span class="glyphicon glyphicon-arrow-up"></span><span class="glyphicon glyphicon-arrow-down"></span>{{_('Exchange author and title')}}</div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
     <div class="col-xs-12 col-sm-6">
 | 
			
		||||
      <div class="row">
 | 
			
		||||
     <div class="filterheader col-xs-12 col-sm-6">
 | 
			
		||||
      <div class="row form-group">
 | 
			
		||||
        <input type="checkbox" id="autoupdate_titlesort" name="autoupdate_titlesort" checked>
 | 
			
		||||
        <label for="autoupdate_titlesort">{{_('Update Title Sort automatically')}}</label>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
      <div class="row form-group">
 | 
			
		||||
        <input type="checkbox" id="autoupdate_authorsort" name="autoupdate_authorsort" checked>
 | 
			
		||||
        <label for="autoupdate_authorsort">{{_('Update Author Sort automatically')}}</label>
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1211,7 +1211,7 @@ def extend_search_term(searchterm,
 | 
			
		|||
    for key, db_element in elements.items():
 | 
			
		||||
        tag_names = calibre_db.session.query(db_element).filter(db_element.id.in_(tags['include_' + key])).all()
 | 
			
		||||
        searchterm.extend(tag.name for tag in tag_names)
 | 
			
		||||
        tag_names = calibre_db.session.query(db_element).filter(db.Tags.id.in_(tags['exclude_' + key])).all()
 | 
			
		||||
        tag_names = calibre_db.session.query(db_element).filter(db_element.id.in_(tags['exclude_' + key])).all()
 | 
			
		||||
        searchterm.extend(tag.name for tag in tag_names)
 | 
			
		||||
    language_names = calibre_db.session.query(db.Languages). \
 | 
			
		||||
        filter(db.Languages.id.in_(tags['include_language'])).all()
 | 
			
		||||
| 
						 | 
				
			
			@ -1327,7 +1327,11 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
 | 
			
		|||
            q = q.filter(db.Books.comments.any(func.lower(db.Comments.text).ilike("%" + description + "%")))
 | 
			
		||||
 | 
			
		||||
        # search custom culumns
 | 
			
		||||
        q = adv_search_custom_columns(cc, term, q)
 | 
			
		||||
        try:
 | 
			
		||||
            q = adv_search_custom_columns(cc, term, q)
 | 
			
		||||
        except AttributeError as ex:
 | 
			
		||||
            log.debug_or_exception(ex)
 | 
			
		||||
            flash(_("Error on search for custom columns, please restart Calibre-Web"), category="error")
 | 
			
		||||
 | 
			
		||||
    q = q.order_by(*order).all()
 | 
			
		||||
    flask_session['query'] = json.dumps(term)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user