From 741d7d9efc5da5b0d2ced897a9585d3965d9d003 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 25 Feb 2016 18:43:58 +0530 Subject: [PATCH] CS: Port /mobile Useful for legacy devices that dont support html 5 --- resources/content-server/calibre.png | Bin 0 -> 16326 bytes resources/content-server/mobile.css | 105 +++++++++++++ src/calibre/srv/legacy.py | 218 ++++++++++++++++++++++++++- 3 files changed, 317 insertions(+), 6 deletions(-) create mode 100644 resources/content-server/calibre.png create mode 100644 resources/content-server/mobile.css diff --git a/resources/content-server/calibre.png b/resources/content-server/calibre.png new file mode 100644 index 0000000000000000000000000000000000000000..a9a531de8f81cc8355c5c52eaa103c0a9c0090d2 GIT binary patch literal 16326 zcmV;%KRLjOP)1o%xAz(D_{OSwHFQXd={U@XCXiYYG4Sg1E-GI0`i%A#DBEsf8*xObgpAUg(g*c^5?J+aq3^D4zx_S0d-BmQIU|7IInG*>$Vh4y zUQq~GC8RCL87u<@+7*~VaS(?_1y?6F0^;C8DTbFq>;36bpMk`Sgv&S1G}2%Bnvs^b zo*TfKR`%P*57(#cZ%sH{-{9c%n1detr{B*5k33!dyQ{-D{XEd$NzRJXIcqwz&oSpE z0+rBRZ?Z22`j348b zfBSpvvG;^sfg5#&j>h!4BQ83cs^;+ejCML;SvPbWV^UR>laWjD_0zH6QO-)jS>R+7 zs7C>5g|0IC+VNJQ3Q#ww7znrsK?T1hmJ^FZ=dfp}73y5r(ZtTKG;#f_zTSBe@DIMj zoAKsF)JBl|rAjI_UGyfb38HKhz{-!k?`z`>m)mIkM)z+1>;p`QfO zK(RJpgMc!a-}U!?l}`t!-uHI} zI3fzjm%jY0es{IyfB5u)J-eTL=kP=N!@qLE*2|^5682^tK{LUWeB*#Y5LWdm2HkV) zH7$ejfHbZcJhATEyE1(o$ajiZ=n=)S069Wx16C`c6-pbR5lRiJLaBsa1xXN#Lm!X= zWl;#NVG-O5;1H#j_(N z<2gWbVo(fl7c4o!AX)(fFOC!=x`P0?i~R-Uy636ymwVTU7iaZgqWx51s~DRhFa-wd zm7VAdqAiacmQaT3ZB_bdjGPbf>g9^fW#-CuWVyagwYg&MJSN^;hzv|1v z8=t+{JoV`M=xnm9(m^)@lD1~H(Re}X5#X*FE;l*yd z$pk4*EJkqva8T#or}*wSS)K?Xuq1tx9a5SSwrb0k4! zf-O4Aja}mQh_M>0B-A_i(LVQK^6&(U-8sYc35&L|t)_c!bf=1?00^1XRf-r^ zjMdF0Q*qkK0DIyR@5V9ujAgeUfRx*$(? zI3fVx?r_vRyvcI8S3OQOj3tdzVciU`6dVwaI+P$L)FNP+5-LOrrkQMs*C>Vt4_`LNFmLjId|K0~i~8EyW?|iaM;& zkPyiz1&tYz0^&Fs!2ttraFmiqm{0InuX4KB6@Ii16f;x=2Z}&3r#4635eESfh$56_ zkM7T@cQ)up4e7!u((Ed-y@@_|jls(yiwV+G=AQ`iW zd1SR*C-oV%HAFYMY@>~aY(mo+7Ahzi%T6sI0*IkF?g9wbC-U_Lqn8B^2Sd~xlOCIn z@SAg@M9Sufy{fjmfc8#FgD$WPLaLQK3iMOR!$8+Kr4_stQiz0s(6x#OLBv5Kw#?8K z;z9{A(ajPgg&M>WO=#%RutMXC5Ld+dQ)eSq3sjsK5)d#q%oQ^sdnD%uh=^$Kw4&_e zXmWClXf{fA#wr+qLMV>8;$A2zk!~!R=FF9`(%)R7g8|*%9(v&fyP|}XBlZVPImhwS zPW~D1EC6v_00C3M1XOMvC_$liJVL0Q0(gchg49A^1P~$+L=X|cF;pESp`j3~C9zr& zqfxapLNH=AM@3Ktkxb4tDG#apL=KrO=8mUAZH1x=bs!)ZP;gWLRk8~zLIFg;&Dh^v zGBv|T6;+rp?~PJNx?xLgg}6DUpA0wwOg@vu(*J|A1V_|yaS+FX;PH0(a}`__QH7wG z3&Dln0>vVg212;~9#sKA5fKz8C1G$Np6~X~3Gq8fPK$#Py5Y!P2 zbIFB}9m63iDu4*)pyp@>L7)i16^(+Y!u)W>q%Ww%TWp6z26f9+mCB(^M=Y9#3fKe! ze{sl*J}Gu^Kpg^tsSp*i2#8QJkRiHYG2=B95v)K^&_8x0fH+5oM2P#egG-DimsnfB z!f0}ZD$W@VJKO_70|$p=X7drt#Tw~W%$b0!p(4qUsE7eUz#MQgP>NHFfIIR>b1wmR zr<*Ma2TST{!%PFE5<)B#6T}kMR;YTl$9U@C-;#$LmWd1MyG|UD8U>NKmZ&E2Y1D6K;NB0d_w8ZG21^NR6Q~F z1U1|tTcqSbpN8ag0<#L-5b^AIrRdVY!L{HR#hsj-CI&JE!B8NWfP&2y^!q)73qzuH z7>*Xm2n9!CL$$L`ULS?~Z;sEm%O~Et{O3<*`Gd(P^fjA@27k-A_C37)cis|y?q9!6 zp88#yXW}=lKNIh}Ykqk4fxNbTfw=boqwN#3SU>tBB6tDo3;m5b!&ygp^l@T>7;1D7 zsW0qsxPAh*ChRrZ-?f_kVFfSaJLC5ozx?a=)*t!K@PS9acksmUdq*Fdvw6+F=sxOm zuR`1Vygt9q=>7rI^TOhzW4h~OYfr?kd+L?n_0N9z;)@~{pblc7M4~CD9=@CZdg*b# zAymvByo>kx9(OO6oFBAY?h{s^?gdLmT?`DI+f*C}0-%^g&?W8>v;(gZ=@73driiRS z3T7<;$7_MH7@j{x$1yx|)Ty8pV-S^9F2tj9?HVYS$$epYbH;iQ;{A7XkSfZ}1AMuQ z$4E*&gY6;Lo0>E1JvM&jYqt)XgD)Oj$=%u|?mL}_>krY5UV)xD&)Uv}%?F&}j-fjp zqJ5J$ui35r!cde#Ae#{}OufxB>nU+K=gLDrzCBVmoTPESxJ1}9m;SmGEW zJ$QW-ECLRIA&8+~%v==w}qE~>m{@b zcv;c=f~|Xo%swu|{X>vJ=><)nA2*(xnc-#UIp!f>1AR4J-AyjkRThI*N0FH2UL=45;EGSY5 za%i`OiVn+yk*QTcK-|GWqF}keqNm)PF*P#)-HYmJIjf&ps!MdQOzW;8l0O{*AwJ^4;J1orjm8hX`!Dfz(`^pk^0nzdz3XTB>cuWo4`>ovKi-vc z0RaF4AUFX8Kyj29mIQT-C5i$Ok%XldD-rhy1cU&X8`fvC02w?ek_&E5R>3-_9R&6% zv_Y^Ul$?<&P^Zl5$~9uShb$E_45$vC;bfUJd+-9$lr$Z1IBaHlmY0#VHzeMdkWzun z=q`=Ovl^yXXvPcDGIIJ&A4IBx;DlQ6kg2CDN{X~6PCa^Kef!{@A9|vF^Q-c2zT-Ot z@aOgECIF7-Ho1V%F!_S>{Px@5%Gb|t(7gF;c*pq-4u0jQ`11J;CK<>XQ%6M5KfAPr z0g8~p15N;k;uVz|b!~V#3Lh>==#eZSj=KU5sEb%Oa&|m}hvQCB1l*i9K*CW#RKW#z zqqxx>_DqWt%aX;_eLNfe-h$ja_0S2^G2KSB=&zDo?LYhLfB4t_-FE)LulQ1b-pe51 zM=XHgSgYu>SJ?QSkMYnTqK~ZzIn!Rh%=YG#`Mo0+%Uznnk%I&W-2ZHTIo{lJ0xp6^ zCt6K!0^+D9O0IDf!4RC=a2GA+C6_|Uf(JnW1Pm~98V3w21XZCbicz2x(ju|h!vJM5 z@5tjCD<_agK0$uyA)4WUd~%q(Pwc0b?nWTZRxgSeA%$V==cujKk0-pqdp zhBi|?C;VVeIy0bt$G_ySbct*Y1~f;#+;I$!L&kC4c0(m&rKjXbC50j##T+j!5)?H7 z7aYY!aCN-cs+ZzZr!s;G{wa!J;#l87)lg+ay#OHMr~x@s=1VwS5l=+og|q0@XUWM4 zhdt%mie{^(+aBaOH}@NsS7BkWQH*Z1px#QvZKDo7anzwrCQ#5)s60@K!!lx9JrzRl z3m?4no~ye*y7`{p{zo@nkQEHSP4U|esf1j$=<+;Km-SbNDwEPlZ%nlh)NXIf{Wq~_|fOZaJOOgfYgUa)*lh|Lfw6_G*_A#fXZL;)N}0RTZT@IcUrljsr@ONgux zX>gR|`+(!?6daf1I1k{$kzh(mM(wxVmJvk3i&KD{3Oef;RTD;LqIMvM7$(K9l=oyjRn^NUeTu-4GXG}8SKoMKeNI1Yty{_ zyqEmKyMFAw&wCjJ{C}kj(mB=|TtQ3$c%2#Nz73wA7w3kYNZ|0CxL7y|BCc50ODV0!dFh+_z; z%cT7UqY@dc4p}T=ur#`EhRA?}+!8m}SgnOUofmcN@`MzhL;Hj_LJ-4Epac-X3Wyk1 z0znc<0+L!r5A5;W@2xX9xwOHVyPrA9+K*rM#q*a2|5P^x#0B*z^>X3qfrmNx{5SIc zr=H@>m1h`z*&BG;52>F$1@C_!uM9m>91VqDAUKFR#}FLc@B$tTb3t4v7OAU>sDjXd zDaiy&N-lCFiQw)azLaP=_q_^k1s4ZZTn$N%cO5YZmLRxO5C8_#{9P$RU%167D+5-aG$Ge8qOmyy7)neg7|W z;fYVkbmM~eCtLOodNxzirC<%Xq6EuC__Y6fFc-fj$4J9f$MQj zmC}ov8`%Q5;Rpht0tS{6wbra~j{OOafC>4qXV~}XctqN2sID!rXP(6uhb)^lhLf5y zZ5AuaO@#{!W*?g{c^Y0QYi!IL8O`r^-8{oAeT+~$ zrE0A15_%+y*zxs_MH4Z&MF)!@<)|I-5D*G(^|8oO06E?prKpe{6mX7whfn}b1 zcQ?T51qc{NP!CR_bol50C1$VwJo~lWQPoPN;*QfdL*#A$g4fS)vh0J1saHp~5(JKC zNd%za9>6Q`3?vW`$+!rDVAg;nphm>N_1GP5I9Zfj92McnTZjmDRDJ#&21-2V+9q)_k#+b_Mz$A9KL@lq?}SDb2h*SCQE=d%pD8|DfQ zP9ckHu4>cwy^n`}<|n9!5f4R+;8s_z!-{1Q_H4vh%tJ|tI|Snx$Igfx$9Kofp(v^~ z;u$OU$IfyI2#N#lep?VXDVBT4wV=sy7mkNpM>|JJh(mF~#SwR0fRb6xmXuj0o&X-d z%=GM(e%z2&iIE2ugBI3Cq`JSfTuNz)t#k9kEvG(r!QkWpmRhQ~@zOsbtm#{Ny zEKj$@AXMuE%1Ca`_ZL?x+7l}dADeRa^&RKmbe(RQ&^p5ko_hQJq~(HgbDMj<^5b0p z-G}LRpJuR`$OLvCxXF``ZTsdMR!e{B+4b>9Yasuf&9^>(+xh|~VD6NZ#Ovt82kzs^ zXP2_R>{+UU08vEGZFqn9B+@SlW?CGp{b(&qVF;PD~X|KKd$?lzPAFR}Z< z9oD}139=2@c*QtFEJcgQb2aq80+%K_98am)iAECy*@ ze*5>z_D}s7gLX&|&{|0m%GL?$w)K8FBdd!vc!+{{K(zdcz;aaP4D9IHi;^M{WqTObAZ3cLmc2ZRh5xPz5kaDfb{IpI?Tia5s;aHWWny&w**kP$*q=Ce6f zUxd4)<2`tM@Q|bw|E3!B%5pT~IQ8HZ&A+FT}|q zv&YZSzwt>lI=dH7uzmV6Rm`kEc%9wfKZ~A8yNgq&-}#zs~ijN`Y zw}?PVi9&-96=Fa%qIDL&_OEs~9{reXJoX5F7^qWrF^3}`Imd8><0T}K4l{5Ua$X~Z z8l?PjWH$uF5f|JekN^WI2qr={M-6Is3^3$);}bw23*bU2}Xd4<7F}wh^`^Fd9HIys%nGJOHu~Z}LYPfs_!S9MocRqi+M5^>J?KFV3Q@?Lit&k7HyKIyNx z5mh%L^ZetSZ$DX1TI%%;#`|MtCz-D5V|7GBpc(eC(K@p3r+zqj?U?m%?9rY?x&xuU z;)Jfy2BVIN$tyc_x2_O-#~fbo6GxfbUs&V9x7JZmuH^L6>s*jPkwQ_&Kw|kdsrxf;r>!>$v9c(*FV}b;FW=evuOOz zw||y{-+G+cTif)vPPp+K&oJA2i?xe0s(~Q&F|`fRt;e4K%=+5T|N5^hpZc%^{HCfy-S`OGZ+-*eg5pOT zG$k`0OzCw(7Y*G=T)b$^_QsS~E>L~P3&_buj$c@#`K}3QVf{*?+mEb2b}_Pk?S0?( z;;X%xq_0KP-C*(lpShr7u|IG2?=U&JDLun;rAQ2j0$Vj!rnuA$CDJR2P>jYvomEfE z6}$pE@PHx6>C-Vh{ENv3oPC>|$_XOFP68;KWNUipvTLhrf%$mN|#|H_2p7dNRMDR13=?1>+l z|JbkpRSvtaS-43YM_ffrL`lE#>%{3Hz0#2fN+ALR2GZ7Cxz>f_SM@~tRy&vj=BR_i zDx@q2zg(o%U&7iUb@^6$y+C$HLm_C5h~Nmg0&)fc1Oti+ML1vfKyaYoR4xFBLTAu- zK)|`DlSnN`2d6yM8anDTeWK6tTPF6^Uz@4uawfBZYy{@Wj?+A;FSBEx4}kIz2$ zk?nspCptH6ZGOmMrQnCaHtLry=D#B88AC(xUAE6K98Mb zsCvv_8Njn+iYqk{uK-Epy>%qd7#~C~JvV0f#6IoY>jadz9*NsVy4lcsPo4Gg_kCvL zuY4Y8zuINc1prI~v1(k$$6@vZf2It-?VFB=&pk$Z`v&<}|GS)g{&Q}g$aC|FMMBAB zb7~wA+*w^(UBDGA;F=fFyc)=e4jJ_hDAvbZ7TK!RC2*0r#1(ZyDCW3A$FlCj77$-L zi_sljTvG$wh(WM<;`BJNl@h1Vze>!R>0pa`oPcAh-EC&OLyjW(5wnwDC5;aV*Df); zzR4^f6LWwO{eom-uFYt z|E~FJ$?_G_LMhDWuDPnbdG0Ft_<5iF(2rJnWy7*t3Hx`NS=F?$n?TbelpZm)m^r~@ z>0qB>nLuPgWyC_l^AT2*iR}`rh^QghGPUx+i)4tF#gdmCz!BjLXV(D$b7=*kjN2a>QQq9(iSIh5(a&LC;pU8R+q5QLPMep_)tg5VC; zb{yP3V%MFxxlVljh`~FrlGfKL+kGmHR6A=-1{IG;Zaw;~>sh)#fK8m~n?ttWH^;1? z2_zV1O02->ICvwl_5L0gzjdFKY7#>4T8C<(ygj6TqMGQn$G&Iw##?~>*u42YG1g ziI=oWI-so51Olt(sw?Id?h%m=rva~U4A6UUUmWGU5J$*B79smGODyW3kX;ZHR2)G#Tbj=mj{MaC|Z$G=b{k2E7>RZ}-oVj~)~T4P01b(vRt}a&%*l$@LrbRXCkH zvsXumI%J_tYrKnis)>3Ry@s{N3eAN99))poWv1|7BdU+sB-&MWnLBk#b1baJjSXjhc07rWW({kq)Qh)?%&e7!}Cns1QeEw z*cp7Kqr^#oAPQ0v2$-!SGRGM#5*r3CI1wnT)g0~=ff9tY@(jaK6^h??$nPDa8je%p zSaHmps#5ZJu19;vHhk|z_Ee}!;Uq$hQXz;cY>$}Kfky^Ca^dKD8~An-^Sfm2(tG?4 z8WhP&36K=xcFX1mZo_awI!#o=hGAvo4w_NIcTQ-pucMp&>GAeszw{s0U%c@5K3~4l z4UHEE$bts*QW@!;*Q9qmRx0f@g2h5nH7!{)P*35;uMw=7RL(n zL`@`FL(aQsD3ns8$}&7fSZTt`MsZSWKp8`71QJE$B83tfo;)Nx*|*2R+ItpskTxu;`?=V(00O<5vd^b~p9p!jlK5)8607YcrsH zC0!)4;+J$Diq@4^hZAR(NfLr5H6ywnXA3{@p04@r&xVASs0BlCu?6A2Bz{GYDNqoE zVu_R;kxWx(R5M6ix_T6l)fu`Pzs!~>I9Y@WrL6c_>fl|0*pOl*dcei=z3>{T zAx`&-H_v^r__uwB_kZ>md+TK7+i{! z^@etHgF!e7JDbPh)3>kOc!m7IOQ;I7*GKf8OL(i87$O0!04Fn@f5^A_bH2i?Jt$~=7IEHc&)_m z`UYvf_d`DaSO1#%Nj4iP9(wdVop+B2z5r)9I|Bp&cO_^h>X3QqK#wsWqOJ%AI8MP= zXQ}(@%u1OO0=Wo?o;N=vpb>@aNK{%?qA%_ukR2$Fi6i4VB`2z3A7;kIQJ<5;G3#9> z=5p38!{(3@f9biJlLa#22XvVPKvv0GRNW>40AFd?b9b~Or$pJsZoN&S##1^o zzKcS@$QvWNo~O&t-~PBhdL_R_+J6&&^l3_}NMoZO1hQw`BcM=(-sY6?E7$1moKlTi zL=CSqbV}7LXk}O~^Y+Sne}4UQYkwa(`tr$I4y*VX79(TiU|6rhVr7*SNs60BLaYcV zY8eyb!ALs*=h1TkHv)z1Z=z*{+5quW@C%@hxZwnNz(85OrzsSHaC3ZHBFF{1cyL)LTO@5195MXeMuOl81rq!wY5f$noaU_58-C zihbQTKJ~!GN?9c z%GvIX?R{qNXPzH-Cx$l0Y_G>=XLvioqC#GT z$9jUU&6&SF;^;FqgGUajH#)2hNDRdFj`kqZR6E^K{n$VIrT2Xf=)PP(YiVRSuAo8j zAmCtKM8wgecx_lOfhq1z?Cyto6b1DERF#bgIELCT=8;$*E*j~U#b+XAc@MGGS$dzW zxm2m-QdrnwmM{kaEJElsn$l5MSa(Va4M7BaQA`s9K5u0{>AW^a>p*&Rhe=y#_6`U~ z9XTISZC#*kq78kLF07SjUmEV7-Wcy4zQyQ~OSA`lteaDkpsgUm5D$n5g9~%=;TkRn z;00?VPKM&dQKEE0JyM?zpZomIKmEv;Lzb&T5R`@HFtGdPt_Tvqn~oxiM8jPu(+V}f z1#?^I3CB+v$%P0+gs6q?a00WIa5zP_cj;Nhd^%_NTc2R^Akqf+kVY% z_b&e3^`GbcbVu*B$1gB?>`BT|$9%sdkA&EQi-3X{i@L$rNt$qtSf}`6a?7A2Bqy)6 z^san^MK*!)m$6kiJ#iu+Zq%KjGsVyU02%}rPy-b_Ivxscf&yN^5`;NaGovofyPaDD z1O#wFq>suI#CSr8M~Dm%!pgoG%lzeozLqIuk@I?tDBunTEV@oiazd=oYM=*1_eD0` z2?iQXCPx#=rxOoeA+sa$V8Ea%OxCxMFTBj~1Mk5$`sj9FFY$rrdr$r5#qqEBolloC z`F^rN`%a*GB9Pq)l_3Svz4#Ae6%@k+0L&eCkeFatNKl8Uz5zfPw{(0L1|jP(Z+45O>U3glT}}Xjcej<=*e=fDE`4s=7jThK3;__<0`+ z=V_D(zG4kJtAv?Z&PGuon-dXK<=i6+!A$0b(pP-0h=Yq#-6yj+u@0oeQ&Lyxt@XH5 z7xLjDQk4F1gbi!j*_^@J0O?70p`9N0Mu$ImRLQ@6t)#9`)q5+B+ zVvZV=#VAra;8-@iRl;V0H)`UjqPg;+Km63*XMp)X{-tLG@c8?ws|b?_ZBOV80=cK; zAe0EcKvF}4;Hr3lB7&M@#R(a_2w`s2S*hlQUO^lLa0OcsriP0kD!B9z3hp4Tm;)}j z8CW?_*sQjZbB1D_ zijv>6zELP5WDyF!I&(3BIw;aP^IRAP#VL#Q%A%iZvA<0jx6JOG&=;pFnc@}wa*SQt zV(x;(KCvGeSFvoDz4`ET`+u-~DI6Xi&R=$GKM2-ma?_~RG8z^2K$)yV=zxG1!Loor zvw4b0Ac$j42SJb-_|_A@ef#3YkN@0nAMAeLmVGJttmQ^qLQ#dFNTv8)m_)Q3U(;=!3^mJ4a|5LNJ1i!%t7iR89}AQXhk9R*wfoC=dF zxf~u(>9r7=HLCRy_V{J8DTAX!sxBd0o8(@PHP2!F)2}!3?H>wV9ma1^@)6XTa`Z)y2VqW+aFQpLP-Jb&nVL#VMA=*y#M*}+x17Q_iz_qyt>J4 zsWA$8((_jwb6f?fz}&IoxPUvT3%DS{A~Rc7Q!Xwbj)X+0Csg&Ax|!1SPpPUIG0X`H z$s@VkMK_>yBPPc+Ir-`gTy>61OyzW{^Zv*jkcC--fB^(0ni{i?GVD_X8V9={p~;}Z zEST0O$H%4D&Zrxht#1=zLFbunxJi9$pS59+@gUNZ)NH(9FUN2Dv(wgo%-^ItyoGLE zMD{mGM;$tJtV^Vmb+k7ly( z(}*QeXAr~{FFkB#%-f1?GQe~b#8D}z8nFuCh84j}Am;%P0bQ+UJi|giEnb!)f;)g? z0s+7wvRZHG_-eq{9IA?5ph>5*+3a{mqaeMC9BVoWSkr^LqVob0*_)YP>gvP(FORvn<00+8Ogc(5Pa37|W2r(bCwB!A0jrQWKf6|kjC;aGu^j29N;wIX!^q_N z0I5C|L-W$!{?q<$r+77f7l6j0HVEdB4eh`TLKGxIQK-~$3{lAVxl!T>VxYzGNg;NQ z+A>-Z$(AXprW8R@L@O|`T)+(|aNgRZ;7Tb2iuEv$I1chC`1^n<(8qjprh1{I5`t1@ z%jUUUpbP{Nkj(2V`^8@?ANcfd_%os9a_ShwLKq12 zfXj~GbYw52uRF{<^V+}Mi@h5MUE7vIb$ragwrQtMci5x1mB^`3H8VsV-0*n?xgk$# zx-oR86CAsGsyrRvJZaiO7b2DAlS9(@Nl>R7SA@F5vSRnj)F`t+KJ~kpV#fz+ z$2TRNyukeM`H`eIpK9_+dP--9Bk4vrf`795pXU(_0eZmBf~01Fb%$YrC{STkNhsYi zGzo%G7Gy0gL0oVLaX}rVI3yuD00i6=I}gYfTnrZwaU5GFJeQgd5X>U(6<#9B1eoCn z5CQe`I>Iv&+OEUgsR3M>HO3UD!==VNj4CV@23^9k;i5o=1jRMjA=&M~;SCq-ipNtE zCgw~X<|2$mlDNJmAva!Z3)fQBB^EzEuYajoUCPfQSAN*0>IJY-dngShy(t+HRA)vr7Smzoa4NJa{v^U;jvU<-Lzw_ z32vSu<``f>DFY?7SyMmcc`~-WvyLt!iM>pa1J#_F0Wj_v%@NOCxV|OXJ*KJ zVpWpXMLdUsM4z|0JEc_K2IY2n<>ZjnuuUJ>UReTbpaIqv*EbgDRYZc|0Z@?OpnyKO z^QQxXFR!`b;?OLf7kJRQeJ}(3pg1rG4uKP34gjbKAqY*S)Iq3E)AIYu{k`5B3uJbh zGDsO87fNU1;-NUX013!I0Jee4z!VrSp4BaoR{pOo;EQ7*jy9=>YhshrN~dE>Hpz*} z>UYnuJb&=M%X_y#5r7q46;`)defLZQ0#PGQ0Kzi(?q}yX0a=jesG0-?y-$h(hU==i z&1#(RLBeE-2goZc10-kAN-8;3{|!JV_5?Ep$`YkcEPa2d{}fqs>5BnXRj# zvb^%lvO>%%$^up^zTV)uB6|pVHnr5Xp5H}6Im7+)2jMF~cu?g3w1r&|)lt<~$0d1D zK?HL(TyPU#4!Sx>_M+x~er@%5hSl>2!RqHPat%P%YC>_Cl?s8f)C3fQ#uN_nX%7Q_L#}59C8=#zxROqlB@^2Emw*8Qh)Am+Cf`^SC8;%8A6#Z z+o7cb>HD?K6M3|Oqb$6Byz5VO7kDEcGydj2{N~G!KQMs)#g^sYPtX47k0XEmS_E+Z zKbD8`P#(%dc_ 1: + for t,s in [('First', 1), ('Previous', max(start-num,1))]: + left_buttons.append(E.a(t, href='%s&start=%d'%(url_base, s))) + + if total > start + num: + for t,s in [('Next', start+num), ('Last', total-num+1)]: + right_buttons.append(E.a(t, href='%s&start=%d'%(url_base, s))) + + buttons = E.table( + E.tr(left_buttons, right_buttons), + class_='buttons') + return E.div(tagline, buttons, class_='navigation') + + # }}} + +def build_index(books, num, search, sort, order, start, total, url_base, field_metadata, ctx): # {{{ + logo = E.div(E.img(src=ctx.url_for('/static', what='calibre.png'), alt=__appname__), id='logo') + + search_box = build_search_box(num, search, sort, order, ctx, field_metadata) + navigation = build_navigation(start, num, total, url_base) + navigation2 = build_navigation(start, num, total, url_base) + books_table = E.table(id='listing') + + body = E.body( + logo, + search_box, + navigation, + E.hr(class_='spacer'), + books_table, + E.hr(class_='spacer'), + navigation2 + ) + + for book in books: + thumbnail = E.td( + E.img(type='image/jpeg', border='0', src=ctx.url_for('/get', what='thumb', book_id=book.id), + class_='thumbnail') + ) + + data = E.td() + for fmt in book.formats or (): + if not fmt or fmt.lower().startswith('original_'): + continue + s = E.span( + E.a( + fmt.lower(), + href=ctx.url_for('/get', what=fmt, book_id=book.id) + ), + class_='button') + s.tail = u'' + data.append(s) + + div = E.div(class_='data-container') + data.append(div) + + series = ('[%s - %s]'%(book.series, book.series_index)) if book.series else '' + tags = ('Tags=[%s]'%', '.join(book.tags)) if book.tags else '' + + ctext = '' + for key in filter(ctx.is_field_displayable, field_metadata.ignorable_field_keys()): + fm = field_metadata[key] + if fm['datatype'] == 'comments': + continue + name, val = book.format_field(key) + if val: + ctext += '%s=[%s] '%(name, val) + + first = E.span(u'\u202f%s %s by %s' % (book.title, series, + authors_to_string(book.authors)), class_='first-line') + div.append(first) + second = E.span(u'%s %s %s' % (strftime('%d %b, %Y', t=dt_as_local(book.timestamp).timetuple()), + tags, ctext), class_='second-line') + div.append(second) + + books_table.append(E.tr(thumbnail, data)) + + body.append(E.div( + E.a(_('Switch to the full interface (non-mobile interface)'), + href=ctx.url_for(None), + style="text-decoration: none; color: blue", + title=_('The full interface gives you many more features, ' + 'but it may not work well on a small screen')), + style="text-align:center")) + return E.html( + E.head( + E.title(__appname__ + ' Library'), + E.link(rel='icon', href=ctx.url_for('/favicon.png'), type='image/png'), + E.link(rel='stylesheet', type='text/css', href=ctx.url_for('/static', what='mobile.css')), + E.link(rel='apple-touch-icon', href=ctx.url_for("/static", what='calibre.png')), + E.meta(name="robots", content="noindex") + ), # End head + body + ) # End html +# }}} + +@endpoint('/mobile', postprocess=html) +def mobile(ctx, rd): + db, library_id, library_map, default_library = get_library_data(ctx, rd) + try: + start = max(1, int(rd.query.get('start', 1))) + except ValueError: + raise HTTPBadRequest('start is not an integer') + try: + num = max(0, int(rd.query.get('num', 25))) + except ValueError: + raise HTTPBadRequest('num is not an integer') + search = rd.query.get('search') or '' + with db.safe_read_lock: + book_ids = ctx.search(rd, db, search) + total = len(book_ids) + ascending = rd.query.get('order', '').lower().strip() == 'ascending' + sort_by = sanitize_sort_field_name(db.field_metadata, rd.query.get('sort') or 'date') + try: + book_ids = db.multisort([(sort_by, ascending)], book_ids) + except Exception: + sort_by = 'date' + book_ids = db.multisort([(sort_by, ascending)], book_ids) + books = [db.get_metadata(book_id) for book_id in book_ids[(start-1):(start-1)+num]] + rd.outheaders['Last-Modified'] = http_date(timestampfromdt(db.last_modified())) + order = 'ascending' if ascending else 'descending' + q = {b'search':search.encode('utf-8'), b'order':bytes(order), b'sort':sort_by.encode('utf-8'), b'num':bytes(num)} + url_base = ctx.url_for('/mobile') + '?' + urlencode(q) + return build_index(books, num, search, sort_by, order, start, total, url_base, db.field_metadata, ctx) +# }}} @endpoint('/browse/{+rest=""}') def browse(ctx, rd, rest): raise HTTPRedirect(ctx.url_for(None)) -@endpoint('/mobile/{+rest=""}') -def mobile(ctx, rd, rest): - raise HTTPRedirect(ctx.url_for(None)) - @endpoint('/stanza/{+rest=""}') def stanza(ctx, rd, rest): raise HTTPRedirect(ctx.url_for('/opds'))