Merge remote-tracking branch 'djvu/read-djvu' into master
This commit is contained in:
commit
2451605033
|
@ -22,7 +22,7 @@ Calibre-Web is a web app providing a clean interface for browsing, reading and d
|
|||
- Support for public user registration
|
||||
- Send eBooks to Kindle devices with the click of a button
|
||||
- Sync your Kobo devices through Calibre-Web with your Calibre library
|
||||
- Support for reading eBooks directly in the browser (.txt, .epub, .pdf, .cbr, .cbt, .cbz)
|
||||
- Support for reading eBooks directly in the browser (.txt, .epub, .pdf, .cbr, .cbt, .cbz, .djvu)
|
||||
- Upload new books in many formats, including audio formats (.mp3, .m4a, .m4b)
|
||||
- Support for Calibre Custom Columns
|
||||
- Ability to hide content based on categories and Custom Column content per user
|
||||
|
|
|
@ -187,7 +187,7 @@ def check_send_to_kindle(entry):
|
|||
# Check if a reader is existing for any of the book formats, if not, return empty list, otherwise return
|
||||
# list with supported formats
|
||||
def check_read_formats(entry):
|
||||
EXTENSIONS_READER = {'TXT', 'PDF', 'EPUB', 'CBZ', 'CBT', 'CBR'}
|
||||
EXTENSIONS_READER = {'TXT', 'PDF', 'EPUB', 'CBZ', 'CBT', 'CBR', 'DJVU'}
|
||||
bookformats = list()
|
||||
if len(entry.data):
|
||||
for ele in iter(entry.data):
|
||||
|
|
194
cps/static/js/libs/djvu_html5/Djvu_html5.css
Normal file
194
cps/static/js/libs/djvu_html5/Djvu_html5.css
Normal file
|
@ -0,0 +1,194 @@
|
|||
body {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#djvuContainer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-top: 10px;
|
||||
|
||||
transform: translate(0, 0);
|
||||
-webkit-transform: translate(0, 0);
|
||||
-ms-transform: translate(0, 0);
|
||||
transition: transform 0.3s;
|
||||
-webkit-transition: -webkit-transform 0.3s;
|
||||
}
|
||||
|
||||
.toolbarHidden {
|
||||
transform: translate(0, -100%);
|
||||
-webkit-transform: translate(0, -100%);
|
||||
-ms-transform: translate(0, -100%);
|
||||
transition: transform 1s;
|
||||
-webkit-transition: transform 1s;
|
||||
}
|
||||
|
||||
.toolbarSquareButton {
|
||||
float: left;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-image: url("img/toolbar-buttons.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 500% 300%;
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
position: absolute;
|
||||
border-radius: 6px;
|
||||
opacity: 0.6;
|
||||
box-shadow: inset 0 0 0 1px black, inset 0 0 0 2px white, inset 0 0 0 10px #BBB;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.scrollbar:hover {
|
||||
box-shadow: inset 0 0 0 1px black, inset 0 0 0 2px white, inset 0 0 0 10px #999;
|
||||
}
|
||||
.scrollbarClicked, .scrollbarClicked:hover {
|
||||
box-shadow: inset 0 0 0 1px black, inset 0 0 0 2px white, inset 0 0 0 10px #777;
|
||||
}
|
||||
.scrollbarHidden {
|
||||
opacity: 0;
|
||||
transition: opacity 0.6s;
|
||||
}
|
||||
|
||||
.scrollbarVertical {
|
||||
right: 0px;
|
||||
border-right: 1px solid transparent;
|
||||
width: 13px;
|
||||
}
|
||||
|
||||
.scrollbarHorizontal {
|
||||
bottom: 0px;
|
||||
border-bottom: 1px solid transparent;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.textLayer {
|
||||
position: absolute;
|
||||
height: 120%;
|
||||
width: 120%;
|
||||
overflow: scroll;
|
||||
text-align: left;
|
||||
}
|
||||
_:-ms-lang(x), .textLayer {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
.textPage {
|
||||
margin-top: 100vh;
|
||||
margin-bottom: 100vh;
|
||||
padding-right: 100vw;
|
||||
}
|
||||
.textPage span {
|
||||
font-family: sans-serif;
|
||||
color: #000;
|
||||
color: rgba(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.visibleTextPage span {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
/* border: 1px solid red; /* for easy debug */
|
||||
}
|
||||
|
||||
.buttonZoomIn {
|
||||
background-position: 25% 0;
|
||||
}
|
||||
.buttonZoomIn:hover {
|
||||
background-position: 25% 50%;
|
||||
}
|
||||
.buttonZoomIn:disabled {
|
||||
background-position: 25% 100%;
|
||||
}
|
||||
|
||||
.buttonZoomOut {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.buttonZoomOut:hover {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
.buttonZoomOut:disabled {
|
||||
background-position: 0 100%;
|
||||
}
|
||||
|
||||
.buttonPagePrev {
|
||||
background-position: 50% 0;
|
||||
}
|
||||
.buttonPagePrev:hover {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
.buttonPagePrev:disabled {
|
||||
background-position: 50% 100%;
|
||||
}
|
||||
|
||||
.buttonPageNext {
|
||||
background-position: 75% 0;
|
||||
}
|
||||
.buttonPageNext:hover {
|
||||
background-position: 75% 50%;
|
||||
}
|
||||
.buttonPageNext:disabled {
|
||||
background-position: 75% 100%;
|
||||
}
|
||||
|
||||
.toolbarItem {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.comboBox {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.comboBoxSelection {
|
||||
width: 8.25ex;
|
||||
margin: 10px 12px 0px 12px;
|
||||
}
|
||||
|
||||
.comboBoxText {
|
||||
width: 5ex;
|
||||
border: none;
|
||||
padding: 0px;
|
||||
outline: none;
|
||||
|
||||
position: absolute;
|
||||
margin: 10px 0px 0px 12px;
|
||||
top: 2px;
|
||||
left: 3px;
|
||||
}
|
||||
|
||||
.statusImage {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
margin: -72px 0 0 -64px;
|
||||
background-image: url("img/status.png");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.blankImage {
|
||||
background-image: url("img/blank.jpg");
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
cps/static/js/libs/djvu_html5/djvu_html5/clear.cache.gif
Normal file
BIN
cps/static/js/libs/djvu_html5/djvu_html5/clear.cache.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 B |
|
@ -0,0 +1,16 @@
|
|||
091ECB3AE852C68866FBC86AA8FCDB1F.cache.js
|
||||
user.agent ie8
|
||||
|
||||
1A420474460884E73E3288F783AD7024.cache.js
|
||||
user.agent ie10
|
||||
|
||||
3CFDA9D9AFA2798299BBAE243DB2E9B5.cache.js
|
||||
user.agent safari
|
||||
|
||||
564CB406D925C79CCD67EB98CA5AD4EF.cache.js
|
||||
user.agent gecko1_8
|
||||
|
||||
A8305F17E026239876FCBC730B035A55.cache.js
|
||||
user.agent ie9
|
||||
|
||||
Devmode:devmode.js
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,26 @@
|
|||
function djvu_html5(){var O='bootstrap',P='begin',Q='gwt.codesvr.djvu_html5=',R='gwt.codesvr=',S='djvu_html5',T='startup',U='DUMMY',V=0,W=1,X='iframe',Y='javascript:""',Z='position:absolute; width:0; height:0; border:none; left: -1000px;',$=' top: -1000px;',_='CSS1Compat',ab='<!doctype html>',bb='',cb='<html><head><\/head><body><\/body><\/html>',db='undefined',eb='readystatechange',fb=10,gb='Chrome',hb='eval("',ib='");',jb='script',kb='javascript',lb='moduleStartup',mb='moduleRequested',nb='Failed to load ',ob='head',pb='meta',qb='name',rb='djvu_html5::',sb='::',tb='gwt:property',ub='content',vb='=',wb='gwt:onPropertyErrorFn',xb='Bad handler "',yb='" for "gwt:onPropertyErrorFn"',zb='gwt:onLoadErrorFn',Ab='" for "gwt:onLoadErrorFn"',Bb='#',Cb='?',Db='/',Eb='img',Fb='clear.cache.gif',Gb='baseUrl',Hb='djvu_html5.nocache.js',Ib='base',Jb='//',Kb='user.agent',Lb='webkit',Mb='safari',Nb='msie',Ob=11,Pb='ie10',Qb=9,Rb='ie9',Sb=8,Tb='ie8',Ub='gecko',Vb='gecko1_8',Wb=2,Xb=3,Yb=4,Zb='selectingPermutation',$b='djvu_html5.devmode.js',_b='091ECB3AE852C68866FBC86AA8FCDB1F',ac='1A420474460884E73E3288F783AD7024',bc='3CFDA9D9AFA2798299BBAE243DB2E9B5',cc='564CB406D925C79CCD67EB98CA5AD4EF',dc='A8305F17E026239876FCBC730B035A55',ec=':',fc='.cache.js',gc='loadExternalRefs',hc='end',ic='http:',jc='file:',kc='_gwt_dummy_',lc='__gwtDevModeHook:djvu_html5',mc='Ignoring non-whitelisted Dev Mode URL: ',nc=':moduleBase';var o=window;var p=document;r(O,P);function q(){var a=o.location.search;return a.indexOf(Q)!=-1||a.indexOf(R)!=-1}
|
||||
function r(a,b){if(o.__gwtStatsEvent){o.__gwtStatsEvent({moduleName:S,sessionId:o.__gwtStatsSessionId,subSystem:T,evtGroup:a,millis:(new Date).getTime(),type:b})}}
|
||||
djvu_html5.__sendStats=r;djvu_html5.__moduleName=S;djvu_html5.__errFn=null;djvu_html5.__moduleBase=U;djvu_html5.__softPermutationId=V;djvu_html5.__computePropValue=null;djvu_html5.__getPropMap=null;djvu_html5.__installRunAsyncCode=function(){};djvu_html5.__gwtStartLoadingFragment=function(){return null};djvu_html5.__gwt_isKnownPropertyValue=function(){return false};djvu_html5.__gwt_getMetaProperty=function(){return null};var s=null;var t=o.__gwt_activeModules=o.__gwt_activeModules||{};t[S]={moduleName:S};djvu_html5.__moduleStartupDone=function(e){var f=t[S].bindings;t[S].bindings=function(){var a=f?f():{};var b=e[djvu_html5.__softPermutationId];for(var c=V;c<b.length;c++){var d=b[c];a[d[V]]=d[W]}return a}};var u;function v(){w();return u}
|
||||
function w(){if(u){return}var a=p.createElement(X);a.src=Y;a.id=S;a.style.cssText=Z+$;a.tabIndex=-1;p.body.appendChild(a);u=a.contentDocument;if(!u){u=a.contentWindow.document}u.open();var b=document.compatMode==_?ab:bb;u.write(b+cb);u.close()}
|
||||
function A(k){function l(a){function b(){if(typeof p.readyState==db){return typeof p.body!=db&&p.body!=null}return /loaded|complete/.test(p.readyState)}
|
||||
var c=b();if(c){a();return}function d(){if(!c){if(!b()){return}c=true;a();if(p.removeEventListener){p.removeEventListener(eb,d,false)}if(e){clearInterval(e)}}}
|
||||
if(p.addEventListener){p.addEventListener(eb,d,false)}var e=setInterval(function(){d()},fb)}
|
||||
function m(c){function d(a,b){a.removeChild(b)}
|
||||
var e=v();var f=e.body;var g;if(navigator.userAgent.indexOf(gb)>-1&&window.JSON){var h=e.createDocumentFragment();h.appendChild(e.createTextNode(hb));for(var i=V;i<c.length;i++){var j=window.JSON.stringify(c[i]);h.appendChild(e.createTextNode(j.substring(W,j.length-W)))}h.appendChild(e.createTextNode(ib));g=e.createElement(jb);g.language=kb;g.appendChild(h);f.appendChild(g);d(f,g)}else{for(var i=V;i<c.length;i++){g=e.createElement(jb);g.language=kb;g.text=c[i];f.appendChild(g);d(f,g)}}}
|
||||
djvu_html5.onScriptDownloaded=function(a){l(function(){m(a)})};r(lb,mb);var n=p.createElement(jb);n.src=k;if(djvu_html5.__errFn){n.onerror=function(){djvu_html5.__errFn(S,new Error(nb+code))}}p.getElementsByTagName(ob)[V].appendChild(n)}
|
||||
djvu_html5.__startLoadingFragment=function(a){return D(a)};djvu_html5.__installRunAsyncCode=function(a){var b=v();var c=b.body;var d=b.createElement(jb);d.language=kb;d.text=a;c.appendChild(d);c.removeChild(d)};function B(){var c={};var d;var e;var f=p.getElementsByTagName(pb);for(var g=V,h=f.length;g<h;++g){var i=f[g],j=i.getAttribute(qb),k;if(j){j=j.replace(rb,bb);if(j.indexOf(sb)>=V){continue}if(j==tb){k=i.getAttribute(ub);if(k){var l,m=k.indexOf(vb);if(m>=V){j=k.substring(V,m);l=k.substring(m+W)}else{j=k;l=bb}c[j]=l}}else if(j==wb){k=i.getAttribute(ub);if(k){try{d=eval(k)}catch(a){alert(xb+k+yb)}}}else if(j==zb){k=i.getAttribute(ub);if(k){try{e=eval(k)}catch(a){alert(xb+k+Ab)}}}}}__gwt_getMetaProperty=function(a){var b=c[a];return b==null?null:b};s=d;djvu_html5.__errFn=e}
|
||||
function C(){function e(a){var b=a.lastIndexOf(Bb);if(b==-1){b=a.length}var c=a.indexOf(Cb);if(c==-1){c=a.length}var d=a.lastIndexOf(Db,Math.min(c,b));return d>=V?a.substring(V,d+W):bb}
|
||||
function f(a){if(a.match(/^\w+:\/\//)){}else{var b=p.createElement(Eb);b.src=a+Fb;a=e(b.src)}return a}
|
||||
function g(){var a=__gwt_getMetaProperty(Gb);if(a!=null){return a}return bb}
|
||||
function h(){var a=p.getElementsByTagName(jb);for(var b=V;b<a.length;++b){if(a[b].src.indexOf(Hb)!=-1){return e(a[b].src)}}return bb}
|
||||
function i(){var a=p.getElementsByTagName(Ib);if(a.length>V){return a[a.length-W].href}return bb}
|
||||
function j(){var a=p.location;return a.href==a.protocol+Jb+a.host+a.pathname+a.search+a.hash}
|
||||
var k=g();if(k==bb){k=h()}if(k==bb){k=i()}if(k==bb&&j()){k=e(p.location.href)}k=f(k);return k}
|
||||
function D(a){if(a.match(/^\//)){return a}if(a.match(/^[a-zA-Z]+:\/\//)){return a}return djvu_html5.__moduleBase+a}
|
||||
function F(){var f=[];var g=V;function h(a,b){var c=f;for(var d=V,e=a.length-W;d<e;++d){c=c[a[d]]||(c[a[d]]=[])}c[a[e]]=b}
|
||||
var i=[];var j=[];function k(a){var b=j[a](),c=i[a];if(b in c){return b}var d=[];for(var e in c){d[c[e]]=e}if(s){s(a,d,b)}throw null}
|
||||
j[Kb]=function(){var a=navigator.userAgent.toLowerCase();var b=p.documentMode;if(function(){return a.indexOf(Lb)!=-1}())return Mb;if(function(){return a.indexOf(Nb)!=-1&&(b>=fb&&b<Ob)}())return Pb;if(function(){return a.indexOf(Nb)!=-1&&(b>=Qb&&b<Ob)}())return Rb;if(function(){return a.indexOf(Nb)!=-1&&(b>=Sb&&b<Ob)}())return Tb;if(function(){return a.indexOf(Ub)!=-1||b>=Ob}())return Vb;return bb};i[Kb]={'gecko1_8':V,'ie10':W,'ie8':Wb,'ie9':Xb,'safari':Yb};__gwt_isKnownPropertyValue=function(a,b){return b in i[a]};djvu_html5.__getPropMap=function(){var a={};for(var b in i){if(i.hasOwnProperty(b)){a[b]=k(b)}}return a};djvu_html5.__computePropValue=k;o.__gwt_activeModules[S].bindings=djvu_html5.__getPropMap;r(O,Zb);if(q()){return D($b)}var l;try{h([Tb],_b);h([Pb],ac);h([Mb],bc);h([Vb],cc);h([Rb],dc);l=f[k(Kb)];var m=l.indexOf(ec);if(m!=-1){g=parseInt(l.substring(m+W),fb);l=l.substring(V,m)}}catch(a){}djvu_html5.__softPermutationId=g;return D(l+fc)}
|
||||
function G(){if(!o.__gwt_stylesLoaded){o.__gwt_stylesLoaded={}}r(gc,P);r(gc,hc)}
|
||||
B();djvu_html5.__moduleBase=C();t[S].moduleBase=djvu_html5.__moduleBase;var H=F();if(o){var I=!!(o.location.protocol==ic||o.location.protocol==jc);o.__gwt_activeModules[S].canRedirect=I;function J(){var b=kc;try{o.sessionStorage.setItem(b,b);o.sessionStorage.removeItem(b);return true}catch(a){return false}}
|
||||
if(I&&J()){var K=lc;var L=o.sessionStorage[K];if(!/^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/.*$/.test(L)){if(L&&(window.console&&console.log)){console.log(mc+L)}L=bb}if(L&&!o[K]){o[K]=true;o[K+nc]=C();var M=p.createElement(jb);M.src=L;var N=p.getElementsByTagName(ob)[V];N.insertBefore(M,N.firstElementChild||N.children[V]);return false}}}G();r(O,hc);A(H);return true}
|
||||
djvu_html5.succeeded=djvu_html5();
|
File diff suppressed because one or more lines are too long
BIN
cps/static/js/libs/djvu_html5/djvu_worker/clear.cache.gif
Normal file
BIN
cps/static/js/libs/djvu_html5/djvu_worker/clear.cache.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 B |
|
@ -0,0 +1,2 @@
|
|||
self.$wnd=self;self.$doc=self;function djvu_worker(){var c='81EB501BD7AB47786C30D3175CE1EA2B',d='.cache.js',e='djvu_worker',f='';var b;try{b=c}catch(a){return}importScripts(b+d);gwtOnLoad(undefined,e,f)}
|
||||
djvu_worker();
|
BIN
cps/static/js/libs/djvu_html5/img/blank.jpg
Normal file
BIN
cps/static/js/libs/djvu_html5/img/blank.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
cps/static/js/libs/djvu_html5/img/status.png
Normal file
BIN
cps/static/js/libs/djvu_html5/img/status.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
cps/static/js/libs/djvu_html5/img/toolbar-buttons.png
Normal file
BIN
cps/static/js/libs/djvu_html5/img/toolbar-buttons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
35
cps/templates/readdjvu.html
Normal file
35
cps/templates/readdjvu.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='js/libs/djvu_html5/Djvu_html5.css') }}">
|
||||
|
||||
<title>Djvu HTML5 browser demo</title>
|
||||
|
||||
<script type="text/javascript" language="javascript"
|
||||
src="{{ url_for('static', filename='js/libs/djvu_html5/djvu_html5/djvu_html5.nocache.js') }}"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
|
||||
<noscript>
|
||||
<div
|
||||
style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
|
||||
Your web browser must have JavaScript enabled in order for this
|
||||
application to display correctly.</div>
|
||||
</noscript>
|
||||
|
||||
<div id="djvuContainer" file="{{ url_for('web.serve_book', book_id=djvufile,book_format='djvu') }}"></div>
|
||||
<script type="text/javascript">
|
||||
var DJVU_CONTEXT = {
|
||||
background: "#666",
|
||||
uiHideDelay: 1500,
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1609,6 +1609,9 @@ def read_book(book_id, book_format):
|
|||
elif book_format.lower() == "txt":
|
||||
log.debug(u"Start txt reader for %d", book_id)
|
||||
return render_title_template('readtxt.html', txtfile=book_id, title=_(u"Read a Book"))
|
||||
elif book_format.lower() == "djvu":
|
||||
log.debug(u"Start djvu reader for %d", book_id)
|
||||
return render_title_template('readdjvu.html', djvufile=book_id, title=_(u"Read a Book"))
|
||||
else:
|
||||
for fileExt in constants.EXTENSIONS_AUDIO:
|
||||
if book_format.lower() == fileExt:
|
||||
|
|
Loading…
Reference in New Issue
Block a user