Commit c1be9a72 authored by Jan B's avatar Jan B

Merge pull request #5 from cervinko/master

Fixes for editing Authors and adds Typeahead for Author input, Fix changing password from admin
parents e8b2ea87 cb2ac4d1
...@@ -88,7 +88,7 @@ class Authors(Base): ...@@ -88,7 +88,7 @@ class Authors(Base):
def __init__(self, name, sort, link): def __init__(self, name, sort, link):
self.name = name self.name = name
self.sort = sort self.sort = sort
self.sort = link self.link = link
def __repr__(self): def __repr__(self):
return u"<Authors('{0},{1}{2}')>".format(self.name, self.sort, self.link) return u"<Authors('{0},{1}{2}')>".format(self.name, self.sort, self.link)
......
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.
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
{% if book %} {% 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="col-sm-3 col-lg-3 col-xs-12">
<div class="cover"> <div class="cover">
{% if book.has_cover is defined %} {% if book.has_cover is defined %}
...@@ -21,7 +41,7 @@ ...@@ -21,7 +41,7 @@
<p>{{author.name.join(" & ")}}</p> <p>{{author.name.join(" & ")}}</p>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<input type="text" class="form-control" name="author_name" id="bookAuthor" value="{{book.authors[0].name}}"> <input type="text" data-provide="typeahead" class="form-control typeahead" name="author_name" id="bookAuthor" autocomplete="off" value="{{book.authors[0].name}}">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="description">Description</label> <label for="description">Description</label>
......
...@@ -18,6 +18,17 @@ ...@@ -18,6 +18,17 @@
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]--> <![endif]-->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<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>
</head> </head>
<body> <body>
<!-- Static navbar --> <!-- Static navbar -->
...@@ -127,14 +138,5 @@ ...@@ -127,14 +138,5 @@
</div> </div>
</div> </div>
</div> </div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<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/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>
</body> </body>
</html> </html>
...@@ -19,6 +19,7 @@ from werkzeug.security import generate_password_hash, check_password_hash ...@@ -19,6 +19,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
from functools import wraps from functools import wraps
import base64 import base64
from sqlalchemy.sql import * from sqlalchemy.sql import *
import json
app = (Flask(__name__)) app = (Flask(__name__))
...@@ -223,6 +224,14 @@ def get_opds_download_link(book_id, format): ...@@ -223,6 +224,14 @@ def get_opds_download_link(book_id, format):
response = make_response(send_from_directory(os.path.join(config.DB_ROOT, book.path), data.name + "." +format)) response = make_response(send_from_directory(os.path.join(config.DB_ROOT, book.path), data.name + "." +format))
response.headers["Content-Disposition"] = "attachment; filename=%s.%s" % (data.name, format) response.headers["Content-Disposition"] = "attachment; filename=%s.%s" % (data.name, format)
return response return response
@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])
@app.route("/", defaults={'page': 1}) @app.route("/", defaults={'page': 1})
@app.route('/page/<int:page>') @app.route('/page/<int:page>')
...@@ -628,7 +637,7 @@ def edit_user(user_id): ...@@ -628,7 +637,7 @@ def edit_user(user_id):
return redirect(url_for('user_list')) return redirect(url_for('user_list'))
else: else:
if to_save["password"]: if to_save["password"]:
content.password == generate_password_hash(to_save["password"]) content.password = generate_password_hash(to_save["password"])
if "admin_user" in to_save and content.role != 1: if "admin_user" in to_save and content.role != 1:
content.role = 1 content.role = 1
elif not "admin_user" in to_save and content.role == 1: elif not "admin_user" in to_save and content.role == 1:
...@@ -655,7 +664,25 @@ def edit_book(book_id): ...@@ -655,7 +664,25 @@ def edit_book(book_id):
if request.method == 'POST': if request.method == 'POST':
to_save = request.form.to_dict() to_save = request.form.to_dict()
book.title = to_save["book_title"] book.title = to_save["book_title"]
book.authors[0].name = to_save["author_name"]
author_id = book.authors[0].id
is_author = db.session.query(db.Authors).filter(db.Authors.name == to_save["author_name"].strip()).first()
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()
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": if to_save["cover_url"] and os.path.splitext(to_save["cover_url"])[1].lower() == ".jpg":
img = requests.get(to_save["cover_url"]) img = requests.get(to_save["cover_url"])
...@@ -693,7 +720,7 @@ def edit_book(book_id): ...@@ -693,7 +720,7 @@ def edit_book(book_id):
new_rating = db.Ratings(rating=int(to_save["rating"].strip())) new_rating = db.Ratings(rating=int(to_save["rating"].strip()))
book.ratings[0] = new_rating book.ratings[0] = new_rating
db.session.commit() db.session.commit()
if to_save["detail_view"]: if "detail_view" in to_save:
return redirect(url_for('show_book', id=book.id)) return redirect(url_for('show_book', id=book.id))
else: else:
return render_template('edit_book.html', book=book) return render_template('edit_book.html', book=book)
......
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