Commit a9801371 authored by Cervinko Cera's avatar Cervinko Cera

show 'better author and tags editing; partly copied from...

show 'better author and tags editing; partly copied from https://bitbucket.org/SpeedProg/calibreserver
parent 1d295eb9
span.twitter-typeahead .tt-menu,
span.twitter-typeahead .tt-dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
list-style: none;
font-size: 14px;
text-align: left;
background-color: #ffffff;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
}
span.twitter-typeahead .tt-suggestion {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.42857143;
color: #333333;
white-space: nowrap;
}
span.twitter-typeahead .tt-suggestion.tt-cursor,
span.twitter-typeahead .tt-suggestion:hover,
span.twitter-typeahead .tt-suggestion:focus {
color: #ffffff;
text-decoration: none;
outline: 0;
background-color: #337ab7;
}
.input-group.input-group-lg span.twitter-typeahead .form-control {
height: 46px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
.input-group.input-group-sm span.twitter-typeahead .form-control {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
span.twitter-typeahead {
width: 100%;
}
.input-group span.twitter-typeahead {
display: block !important;
height: 34px;
}
.input-group span.twitter-typeahead .tt-menu,
.input-group span.twitter-typeahead .tt-dropdown-menu {
top: 32px !important;
}
.input-group span.twitter-typeahead:not(:first-child):not(:last-child) .form-control {
border-radius: 0;
}
.input-group span.twitter-typeahead:first-child .form-control {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group span.twitter-typeahead:last-child .form-control {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.input-group.input-group-sm span.twitter-typeahead {
height: 30px;
}
.input-group.input-group-sm span.twitter-typeahead .tt-menu,
.input-group.input-group-sm span.twitter-typeahead .tt-dropdown-menu {
top: 30px !important;
}
.input-group.input-group-lg span.twitter-typeahead {
height: 46px;
}
.input-group.input-group-lg span.twitter-typeahead .tt-menu,
.input-group.input-group-lg span.twitter-typeahead .tt-dropdown-menu {
top: 46px !important;
}
This diff is collapsed.
......@@ -11,9 +11,14 @@
</div>
<div class="col-sm-9 col-lg-9 book-meta">
<h2>{{entry.title}}</h2>
<p class="author"><a href="{{url_for('author', name=entry.authors[0].name) }}">{{entry.authors[0].name}}</a>
</p>
<p class="author">
{% for author in entry.authors %}
<a href="{{url_for('author', name=author.name) }}">{{author.name}}</a>
{% if not loop.last %}
&amp;
{% endif %}
{% endfor %}
</p>
{% if entry.ratings.__len__() > 0 %}
<div class="rating">
<p>
......
{% extends "layout.html" %}
{% block body %}
{% if book %}
<script type="text/javascript">
$(document).ready(function(){
$('input.typeahead').typeahead({
name: 'accounts',
source: function (query, process) {
$.ajax({
url: '{{ url_for('get_authors_json') }} ',
type: 'POST',
dataType: 'JSON',
data: 'query=' + query,
success: function(data) {
console.log(data);
process(data);
}
});
}
});
});
</script>
<div class="col-sm-3 col-lg-3 col-xs-12">
<div class="cover">
{% if book.has_cover is defined %}
......@@ -36,12 +16,7 @@ $(document).ready(function(){
</div>
<div class="form-group">
<label for="bookAuthor">Author</label>
{% if book.authors|length > 1 %}
{% for author in book.authors %}
<p>{{author.name.join(" & ")}}</p>
{% endfor %}
{% endif %}
<input type="text" data-provide="typeahead" class="form-control typeahead" name="author_name" id="bookAuthor" autocomplete="off" value="{{book.authors[0].name}}">
<input type="text" class="form-control typeahead" name="author_name" id="bookAuthor" value="{{' & '.join(authors)}}" autocomplete="off">
</div>
<div class="form-group">
<label for="description">Description</label>
......@@ -78,3 +53,11 @@ $(document).ready(function(){
</div>
{% endif %}
{% endblock %}
{% block js %}
<script src="{{ url_for('static', filename='js/typeahead.bundle.js') }}"></script>
<script src="{{ url_for('static', filename='js/edit_books.js') }}"></script>
{% endblock %}
{% block header %}
<link href="{{ url_for('static', filename='css/typeahead.css') }}" rel="stylesheet" media="screen">
{% endblock %}
......@@ -50,7 +50,14 @@
</div>
<div class="meta">
<p class="title">{{entry.title|shortentitle}}</p>
<p class="author"><a href="{{url_for('author', name=entry.authors[0].name) }}">{{entry.authors[0].name}}</a></p>
<p class="author">
{% for author in entry.authors %}
<a href="{{url_for('author', name=author.name) }}">{{author.name}}</a>
{% if not loop.last %}
&amp;
{% endif %}
{% endfor %}
</p>
{% if entry.ratings.__len__() > 0 %}
<div class="rating">
{% for number in range((entry.ratings[0].rating/2)|int(2)) %}
......
......@@ -23,12 +23,12 @@
<script src="https://code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/bootstrap3-typeahead.js') }}"></script>
<script src="{{ url_for('static', filename='js/underscore.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/intention.js') }}"></script>
<script src="{{ url_for('static', filename='js/context.js') }}"></script>
<script src="{{ url_for('static', filename='js/plugins.js') }}"></script>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
{% block header %}{% endblock %}
</head>
<body>
<script>
......@@ -154,5 +154,6 @@
</div>
</div>
</div>
{% block js %}{% endblock %}
</body>
</html>
......@@ -22,7 +22,14 @@
</div>
<div class="meta">
<p class="title">{{entry.title|shortentitle}}</p>
<p class="author"><a href="{{url_for('author', name=entry.authors[0].name) }}">{{entry.authors[0].name}}</a></p>
<p class="author">
{% for author in entry.authors %}
<a href="{{url_for('author', name=author.name) }}">{{author.name}}</a>
{% if not loop.last %}
&amp;
{% endif %}
{% endfor %}
</p>
{% if entry.ratings.__len__() > 0 %}
<div class="rating">
{% for number in range((entry.ratings[0].rating/2)|int(2)) %}
......
......@@ -244,11 +244,27 @@ def get_opds_download_link(book_id, format):
@app.route("/get_authors_json", methods = ['GET', 'POST'])
def get_authors_json():
if request.method == "POST":
form = request.form.to_dict()
entries = db.session.execute("select name from authors where name like '%" + form['query'] + "%'")
return json.dumps([dict(r) for r in entries])
if request.method == "GET":
query = request.args.get('q')
entries = db.session.execute("select name from authors where name like '%" + query + "%'")
json_dumps = json.dumps([dict(r) for r in entries])
return json_dumps
@app.route("/get_tags_json", methods = ['GET', 'POST'])
def get_tags_json():
if request.method == "GET":
query = request.args.get('q')
entries = db.session.execute("select name from tags where name like '%" + query + "%'")
json_dumps = json.dumps([dict(r) for r in entries])
return json_dumps
@app.route("/get_series_json", methods = ['GET', 'POST'])
def get_series_json():
if request.method == "GET":
query = request.args.get('q')
entries = db.session.execute("select name from series where name like '%" + query + "%'")
json_dumps = json.dumps([dict(r) for r in entries])
return json_dumps
@app.route("/", defaults={'page': 1})
@app.route('/page/<int:page>')
......@@ -678,34 +694,61 @@ def edit_book(book_id):
## create the function for sorting...
db.session.connection().connection.connection.create_function("title_sort",1,db.title_sort)
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
author_names = []
for author in book.authors:
author_names.append(author.name)
if request.method == 'POST':
edited_books_id = set()
to_save = request.form.to_dict()
if book.title != to_save["book_title"]:
book.title = to_save["book_title"]
edited_books_id.add(book.id)
author_id = book.authors[0].id
if book.authors[0].name != to_save["author_name"].strip():
is_author = db.session.query(db.Authors).filter(db.Authors.name == to_save["author_name"].strip()).first()
input_authors = to_save["author_name"].split('&')
input_authors = map(lambda it: it.strip(), input_authors)
# we have all author names now
author0_before_edit = book.authors[0].name
# 1. search for authors to remove
del_authors = []
for c_author in book.authors:
found = False
for inp_author in input_authors:
if inp_author == c_author.name:
found = True
break;
# if the author was not found in the new list, add him to remove list
if not found:
del_authors.append(c_author)
# 2. search for authors that need to be added
add_authors = []
for inp_author in input_authors:
found = False
for c_author in book.authors:
if inp_author == c_author.name:
found = True
break;
if not found:
add_authors.append(inp_author)
# if there are authors to remove, we remove them now
if len(del_authors) > 0:
for del_author in del_authors:
book.authors.remove(del_author)
authors_books_count = db.session.query(db.Books).filter(db.Books.authors.any(db.Authors.id.is_(del_author.id))).count()
if authors_books_count == 0:
db.session.query(db.Authors).filter(db.Authors.id == del_author.id).delete()
# if there are authors to add, we add them now!
if len(add_authors) > 0:
for add_author in add_authors:
# check if an author with that name exists
t_author = db.session.query(db.Authors).filter(db.Authors.name == add_author).first();
# if no author is found add it
if t_author == None:
new_author = db.Authors(add_author, add_author, "")
db.session.add(new_author)
t_author = db.session.query(db.Authors).filter(db.Authors.name == add_author).first();
# add author to book
book.authors.append(t_author)
if author0_before_edit != book.authors[0].name:
edited_books_id.add(book.id)
if book.authors[0].name not in ("Unknown", "Unbekannt", "", " "):
if is_author:
book.authors.append(is_author)
book.authors.remove(db.session.query(db.Authors).get(book.authors[0].id))
authors_books_count = db.session.query(db.Books).filter(db.Books.authors.any(db.Authors.id.is_(author_id))).count()
if authors_books_count == 0:
db.session.query(db.Authors).filter(db.Authors.id == author_id).delete()
else:
book.authors[0].name = to_save["author_name"].strip()
for linked_book in db.session.query(db.Books).filter(db.Books.authors.any(db.Authors.id.is_(author_id))).all():
edited_books_id.add(linked_book.id)
else:
if is_author:
book.authors.append(is_author)
else:
book.authors.append(db.Authors(to_save["author_name"].strip(), "", ""))
book.authors.remove(db.session.query(db.Authors).get(book.authors[0].id))
if to_save["cover_url"] and os.path.splitext(to_save["cover_url"])[1].lower() == ".jpg":
img = requests.get(to_save["cover_url"])
......@@ -720,14 +763,50 @@ def edit_book(book_id):
else:
book.comments.append(db.Comments(text=to_save["description"], book=book.id))
for tag in to_save["tags"].split(","):
if tag.strip():
is_tag = db.session.query(db.Tags).filter(db.Tags.name.like('%' + tag.strip() + '%')).first()
if is_tag:
book.tags.append(is_tag)
else:
new_tag = db.Tags(name=tag.strip())
book.tags.append(new_tag)
input_tags = to_save["tags"].split(',')
input_tags = map(lambda it: it.strip(), input_tags)
input_tags = [x for x in input_tags if x != '']
# we have all author names now
# 1. search for tags to remove
del_tags = []
for c_tag in book.tags:
found = False
for inp_tag in input_tags:
if inp_tag == c_tag.name:
found = True
break;
# if the tag was not found in the new list, add him to remove list
if not found:
del_tags.append(c_tag)
# 2. search for tags that need to be added
add_tags = []
for inp_tag in input_tags:
found = False
for c_tag in book.tags:
if inp_tag == c_tag.name:
found = True
break;
if not found:
add_tags.append(inp_tag)
# if there are tags to remove, we remove them now
if len(del_tags) > 0:
for del_tag in del_tags:
book.tags.remove(del_tag)
if len(del_tag.books) == 0:
db.session.delete(del_tag)
# if there are tags to add, we add them now!
if len(add_tags) > 0:
for add_tag in add_tags:
# check if a tag with that name exists
new_tag = db.session.query(db.Tags).filter(db.Tags.name == add_tag).first();
# if no tag is found add it
if new_tag == None:
new_tag = db.Tags(add_tag)
db.session.add(new_tag)
new_tag = db.session.query(db.Tags).filter(db.Tags.name == add_tag).first();
# add tag to book
book.tags.append(new_tag)
if to_save["series"].strip():
is_series = db.session.query(db.Series).filter(db.Series.name.like('%' + to_save["series"].strip() + '%')).first()
if is_series:
......@@ -743,14 +822,17 @@ def edit_book(book_id):
new_rating = db.Ratings(rating=int(to_save["rating"].strip()))
book.ratings[0] = new_rating
db.session.commit()
author_names = []
for author in book.authors:
author_names.append(author.name)
for b in edited_books_id:
helper.update_dir_stucture(b)
if "detail_view" in to_save:
return redirect(url_for('show_book', id=book.id))
else:
return render_template('edit_book.html', book=book)
return render_template('edit_book.html', book=book, authors=author_names)
else:
return render_template('edit_book.html', book=book)
return render_template('edit_book.html', book=book, authors=author_names)
@app.route("/upload", methods = ["GET", "POST"])
@login_required
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment