Save ePub bookmarks to database
Save ePub bookmark to database. Also use library's built-in restore feature to restore all information from localStorage.
This commit is contained in:
parent
193605df4a
commit
374b5f4c6e
38
cps/static/js/reading/epub.js
Normal file
38
cps/static/js/reading/epub.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* global $, calibre, EPUBJS, ePubReader */
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
EPUBJS.filePath = calibre.filePath;
|
||||
EPUBJS.cssPath = calibre.cssPath;
|
||||
|
||||
var reader = ePubReader(calibre.bookUrl, {
|
||||
restore: true,
|
||||
bookmarks: [calibre.bookmark]
|
||||
});
|
||||
reader.on("reader:bookmarked", updateBookmark.bind(reader, "add"));
|
||||
reader.on("reader:unbookmarked", updateBookmark.bind(reader, "remove"));
|
||||
|
||||
/**
|
||||
* @param {string} action - Add or remove bookmark
|
||||
* @param {string|int} location - Location or zero
|
||||
*/
|
||||
function updateBookmark(action, location) {
|
||||
// Remove other bookmarks (there can only be one)
|
||||
if (action === "add") {
|
||||
this.settings.bookmarks.filter(function (bookmark) {
|
||||
return bookmark !== location;
|
||||
}).map(function (bookmark) {
|
||||
this.removeBookmark(bookmark);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
// Save to database
|
||||
$.ajax(calibre.bookmarkUrl, {
|
||||
method: "post",
|
||||
data: { bookmark: location || "" }
|
||||
}).fail(function (xhr, status, error) {
|
||||
alert(error);
|
||||
});
|
||||
}
|
||||
})();
|
|
@ -11,59 +11,6 @@
|
|||
<link rel="stylesheet" href="{{ url_for('static', filename='css/libs/normalize.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/popup.css') }}">
|
||||
<script src="{{ url_for('static', filename='js/libs/jquery.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/libs/zip.min.js') }}"></script>
|
||||
|
||||
<!-- Full Screen -->
|
||||
<script src="{{ url_for('static', filename='js/libs/screenfull.min.js') }}"></script>
|
||||
|
||||
<!-- Render -->
|
||||
<script src="{{ url_for('static', filename='js/libs/epub.min.js') }}"></script>
|
||||
|
||||
<!-- Hooks -->
|
||||
<script src="{{ url_for('static', filename='js/libs/hooks.min.js') }}"></script>
|
||||
|
||||
<!-- Reader -->
|
||||
<script src="{{ url_for('static', filename='js/libs/reader.min.js') }}"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
document.onreadystatechange = function () {
|
||||
if (document.readyState == "complete") {
|
||||
EPUBJS.filePath = "{{ url_for('static', filename='js/libs/') }}";
|
||||
EPUBJS.cssPath = "{{ url_for('static', filename='css/') }}";
|
||||
|
||||
window.reader = ePubReader("{{ url_for('static', filename=bookid) }}/");
|
||||
//keybind
|
||||
/*$(document).keydown(function(event){
|
||||
if(event.keyCode == 37){
|
||||
//window.reader.book.prevPage();
|
||||
event.preventDefault();
|
||||
}
|
||||
if(event.keyCode == 39){
|
||||
//swindow.reader.book.nextPage();
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
//bind mouse
|
||||
$(window).bind('DOMMouseScroll mousewheel', function(event) {
|
||||
var delta = 0;
|
||||
if (event.originalEvent.wheelDelta) {
|
||||
delta = event.originalEvent.wheelDelta;
|
||||
}else if (event.originalEvent.detail) {
|
||||
delta = event.originalEvent.detail*-1;
|
||||
}
|
||||
if (delta >= 0) {
|
||||
window.reader.book.prevPage();
|
||||
}
|
||||
else {
|
||||
window.reader.book.nextPage();
|
||||
}
|
||||
});*/
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="sidebar">
|
||||
|
@ -129,5 +76,22 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.calibre = {
|
||||
filePath: "{{ url_for('static', filename='js/libs/') }}",
|
||||
cssPath: "{{ url_for('static', filename='css/') }}",
|
||||
bookUrl: "{{ url_for('static', filename=bookid) }}/",
|
||||
bookmarkUrl: "{{ url_for('bookmark', book_id=bookid, book_format='EPUB') }}",
|
||||
bookmark: "{{ bookmark.bookmark_key if bookmark != None }}"
|
||||
};
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/libs/jquery.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/libs/zip.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/libs/screenfull.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/libs/epub.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/libs/hooks.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/libs/reader.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/reading/epub.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
19
cps/ub.py
19
cps/ub.py
|
@ -212,15 +212,26 @@ class BookShelf(Base):
|
|||
def __repr__(self):
|
||||
return '<Book %r>' % self.id
|
||||
|
||||
|
||||
class ReadBook(Base):
|
||||
__tablename__ = 'book_read_link'
|
||||
|
||||
id=Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True)
|
||||
book_id = Column(Integer, unique=False)
|
||||
user_id =Column(Integer, ForeignKey('user.id'), unique=False)
|
||||
user_id = Column(Integer, ForeignKey('user.id'), unique=False)
|
||||
is_read = Column(Boolean, unique=False)
|
||||
|
||||
|
||||
class Bookmark(Base):
|
||||
__tablename__ = 'bookmark'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
user_id = Column(Integer, ForeignKey('user.id'))
|
||||
book_id = Column(Integer)
|
||||
format = Column(String(collation='NOCASE'))
|
||||
bookmark_key = Column(String)
|
||||
|
||||
|
||||
# Baseclass representing Downloads from calibre-web in app.db
|
||||
class Downloads(Base):
|
||||
__tablename__ = 'downloads'
|
||||
|
@ -396,7 +407,9 @@ class Config:
|
|||
# rows with SQL commands
|
||||
def migrate_Database():
|
||||
if not engine.dialect.has_table(engine.connect(), "book_read_link"):
|
||||
ReadBook.__table__.create(bind = engine)
|
||||
ReadBook.__table__.create(bind=engine)
|
||||
if not engine.dialect.has_table(engine.connect(), "bookmark"):
|
||||
Bookmark.__table__.create(bind=engine)
|
||||
|
||||
try:
|
||||
session.query(exists().where(User.locale)).scalar()
|
||||
|
|
102
cps/web.py
102
cps/web.py
|
@ -1354,6 +1354,26 @@ def show_book(book_id):
|
|||
return redirect(url_for("index"))
|
||||
|
||||
|
||||
@app.route("/ajax/bookmark/<int:book_id>/<book_format>", methods=['POST'])
|
||||
@login_required
|
||||
def bookmark(book_id, book_format):
|
||||
bookmark_key = request.form["bookmark"]
|
||||
ub.session.query(ub.Bookmark).filter(ub.and_(ub.Bookmark.user_id == int(current_user.id),
|
||||
ub.Bookmark.book_id == book_id,
|
||||
ub.Bookmark.format == book_format)).delete()
|
||||
if not bookmark_key:
|
||||
ub.session.commit()
|
||||
return "", 204
|
||||
|
||||
bookmark = ub.Bookmark(user_id=current_user.id,
|
||||
book_id=book_id,
|
||||
format=book_format,
|
||||
bookmark_key=bookmark_key)
|
||||
ub.session.merge(bookmark)
|
||||
ub.session.commit()
|
||||
return "", 201
|
||||
|
||||
|
||||
@app.route("/admin")
|
||||
@login_required
|
||||
def admin_forbidden():
|
||||
|
@ -1794,49 +1814,51 @@ def unread_books(page):
|
|||
@login_required_if_no_ano
|
||||
def read_book(book_id, book_format):
|
||||
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
if book:
|
||||
book_dir = os.path.join(config.get_main_dir, "cps", "static", str(book_id))
|
||||
if not os.path.exists(book_dir):
|
||||
os.mkdir(book_dir)
|
||||
if book_format.lower() == "epub":
|
||||
# check if mimetype file is exists
|
||||
mime_file = str(book_id) + "/mimetype"
|
||||
if not os.path.exists(mime_file):
|
||||
epub_file = os.path.join(config.config_calibre_dir, book.path, book.data[0].name) + ".epub"
|
||||
if not os.path.isfile(epub_file):
|
||||
raise ValueError('Error opening eBook. File does not exist: ', epub_file)
|
||||
zfile = zipfile.ZipFile(epub_file)
|
||||
for name in zfile.namelist():
|
||||
(dirName, fileName) = os.path.split(name)
|
||||
newDir = os.path.join(book_dir, dirName)
|
||||
if not os.path.exists(newDir):
|
||||
try:
|
||||
os.makedirs(newDir)
|
||||
except OSError as exception:
|
||||
if not exception.errno == errno.EEXIST:
|
||||
raise
|
||||
if fileName:
|
||||
fd = open(os.path.join(newDir, fileName), "wb")
|
||||
fd.write(zfile.read(name))
|
||||
fd.close()
|
||||
zfile.close()
|
||||
return render_title_template('read.html', bookid=book_id, title=_(u"Read a Book"))
|
||||
elif book_format.lower() == "pdf":
|
||||
return render_title_template('readpdf.html', pdffile=book_id, title=_(u"Read a Book"))
|
||||
elif book_format.lower() == "txt":
|
||||
return render_title_template('readtxt.html', txtfile=book_id, title=_(u"Read a Book"))
|
||||
elif book_format.lower() == "cbr":
|
||||
all_name = str(book_id) + "/" + book.data[0].name + ".cbr"
|
||||
tmp_file = os.path.join(book_dir, book.data[0].name) + ".cbr"
|
||||
if not os.path.exists(all_name):
|
||||
cbr_file = os.path.join(config.config_calibre_dir, book.path, book.data[0].name) + ".cbr"
|
||||
copyfile(cbr_file, tmp_file)
|
||||
return render_title_template('readcbr.html', comicfile=all_name, title=_(u"Read a Book"))
|
||||
|
||||
else:
|
||||
if not book:
|
||||
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
book_dir = os.path.join(config.get_main_dir, "cps", "static", str(book_id))
|
||||
if not os.path.exists(book_dir):
|
||||
os.mkdir(book_dir)
|
||||
bookmark = ub.session.query(ub.Bookmark).filter(ub.and_(ub.Bookmark.user_id == int(current_user.id),
|
||||
ub.Bookmark.book_id == book_id,
|
||||
ub.Bookmark.format == book_format.upper())).first()
|
||||
if book_format.lower() == "epub":
|
||||
# check if mimetype file is exists
|
||||
mime_file = str(book_id) + "/mimetype"
|
||||
if not os.path.exists(mime_file):
|
||||
epub_file = os.path.join(config.config_calibre_dir, book.path, book.data[0].name) + ".epub"
|
||||
if not os.path.isfile(epub_file):
|
||||
raise ValueError('Error opening eBook. File does not exist: ', epub_file)
|
||||
zfile = zipfile.ZipFile(epub_file)
|
||||
for name in zfile.namelist():
|
||||
(dirName, fileName) = os.path.split(name)
|
||||
newDir = os.path.join(book_dir, dirName)
|
||||
if not os.path.exists(newDir):
|
||||
try:
|
||||
os.makedirs(newDir)
|
||||
except OSError as exception:
|
||||
if not exception.errno == errno.EEXIST:
|
||||
raise
|
||||
if fileName:
|
||||
fd = open(os.path.join(newDir, fileName), "wb")
|
||||
fd.write(zfile.read(name))
|
||||
fd.close()
|
||||
zfile.close()
|
||||
return render_title_template('read.html', bookid=book_id, title=_(u"Read a Book"), bookmark=bookmark)
|
||||
elif book_format.lower() == "pdf":
|
||||
return render_title_template('readpdf.html', pdffile=book_id, title=_(u"Read a Book"))
|
||||
elif book_format.lower() == "txt":
|
||||
return render_title_template('readtxt.html', txtfile=book_id, title=_(u"Read a Book"))
|
||||
elif book_format.lower() == "cbr":
|
||||
all_name = str(book_id) + "/" + book.data[0].name + ".cbr"
|
||||
tmp_file = os.path.join(book_dir, book.data[0].name) + ".cbr"
|
||||
if not os.path.exists(all_name):
|
||||
cbr_file = os.path.join(config.config_calibre_dir, book.path, book.data[0].name) + ".cbr"
|
||||
copyfile(cbr_file, tmp_file)
|
||||
return render_title_template('readcbr.html', comicfile=all_name, title=_(u"Read a Book"))
|
||||
|
||||
|
||||
@app.route("/download/<int:book_id>/<book_format>")
|
||||
@login_required_if_no_ano
|
||||
|
|
Loading…
Reference in New Issue
Block a user