mirror of
https://github.com/evilhero/mylar
synced 2024-12-25 01:01:47 +00:00
IMP: WebViewer 1.0
This commit is contained in:
parent
85f295976d
commit
a834df2179
8 changed files with 1924 additions and 0 deletions
330
data/css/webviewerstyle.css
Normal file
330
data/css/webviewerstyle.css
Normal file
|
@ -0,0 +1,330 @@
|
||||||
|
html {
|
||||||
|
}
|
||||||
|
header,
|
||||||
|
main,
|
||||||
|
footer {
|
||||||
|
background: #757575;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color: #FFFFFF;
|
||||||
|
background: #757575;
|
||||||
|
}
|
||||||
|
#breadcrumbs {
|
||||||
|
top: 0;
|
||||||
|
background: #BDBDBD;
|
||||||
|
}
|
||||||
|
#comic-info {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#dash_dashboard {
|
||||||
|
padding-left: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#dash_library {
|
||||||
|
padding-left: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#dash_settings {
|
||||||
|
padding-left: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#directory-card-content {
|
||||||
|
display:flex;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: #BDBDBD;
|
||||||
|
text-position: center;
|
||||||
|
}
|
||||||
|
#footer {
|
||||||
|
background: #757575;
|
||||||
|
}
|
||||||
|
#theme-settings .dropdown-content li>a, .dropdown-content li>span, .select-dropdown li.disabled, .select-dropdown li.disabled>span, .select-dropdown li.optgroup {
|
||||||
|
background: #757575;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#log-modal {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#logo-wrapper {
|
||||||
|
background: #757575;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#nav-dropdown {
|
||||||
|
background-color: #BDBDBD;
|
||||||
|
}
|
||||||
|
#nav-dropdown a {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#page-settings-text {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#page-settings-right-text i {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#page-settings-left-text i {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#pagination-num a {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#pagination-num.active {
|
||||||
|
background-color: #BDBDBD;
|
||||||
|
}
|
||||||
|
#read-link {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#search-modal {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#search-modal input {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
#settings-arrow {
|
||||||
|
color: #BDBDBD;
|
||||||
|
}
|
||||||
|
#settings-button {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#settings-help {
|
||||||
|
position: absolute;
|
||||||
|
z-index:5000;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background: #BDBDBD;
|
||||||
|
}
|
||||||
|
#size-height-button {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#size-width-button {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#size-normal-button {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#summary-pane {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
#tab-row {
|
||||||
|
background: #757575;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.btn-flat {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
background-color: #BDBDBD;
|
||||||
|
box-shadow: 1px 1px 10px 1px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
.card-image {
|
||||||
|
position: relative;
|
||||||
|
height: 350px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.card-image img {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.card-content {
|
||||||
|
height: auto;
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.card-content a {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.center-cols > .col {
|
||||||
|
float:none; /* disable the float */
|
||||||
|
display: inline-block; /* make blocks inline-block */
|
||||||
|
text-align: initial; /* restore text-align to default */
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.dimmed {
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
.dropdown-button {
|
||||||
|
background-color: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.input-field {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.input-field label {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.input-field input[type=text]:focus + label {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.input-field input[type=text]:focus {
|
||||||
|
border-bottom: 1px solid #FFFFFF;
|
||||||
|
box-shadow: 0 1px 0 0 #FFFFFF;
|
||||||
|
}
|
||||||
|
.input-field input[type=password]:focus + label {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.input-field input[type=password]:focus {
|
||||||
|
border-bottom: 1px solid #FFFFFF;
|
||||||
|
box-shadow: 0 1px 0 0 #FFFFFF;
|
||||||
|
}
|
||||||
|
.nav-wrapper .input-field input[type="search"] {
|
||||||
|
height: auto;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background: #BDBDBD;
|
||||||
|
}
|
||||||
|
.nav-wrapper .input-field input[type="search"]:focus {
|
||||||
|
background: #BDBDBD;
|
||||||
|
color: #FFFFFF;
|
||||||
|
box-shadow: 0 1px 0 0 #BDBDBD;
|
||||||
|
}
|
||||||
|
.nav-wrapper .input-field input[type="search"]:focus ~ .material-icons.icon-close {
|
||||||
|
right: 2rem;
|
||||||
|
}
|
||||||
|
.nav-wrapper .dropdown-button {
|
||||||
|
position:absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.overlay-settings {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
color: #000;
|
||||||
|
z-index:4000;
|
||||||
|
min-height: 1px;
|
||||||
|
}
|
||||||
|
.overlay-settings-text {
|
||||||
|
color: #FFFFFF;
|
||||||
|
height: 900px;
|
||||||
|
line-height: 900px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.page-left {
|
||||||
|
position: fixed;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
height: 100%;
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
.page-settings {
|
||||||
|
position: fixed;
|
||||||
|
left: 33.33%;
|
||||||
|
top: 0px;
|
||||||
|
height: 100%;
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
.page-right {
|
||||||
|
position: fixed;
|
||||||
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
|
height: 100%;
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
.reader-overlay {
|
||||||
|
position: absolute;
|
||||||
|
background-color:#757575;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
top:0px;
|
||||||
|
left:0px;
|
||||||
|
z-index:1000;
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
|
.reader-page-wide {
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
.reader-page-high {
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100%;
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
|
.reader-page-norm {
|
||||||
|
position: absolute;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
|
.settings-span-left {
|
||||||
|
display: inline-block;
|
||||||
|
left: 0px;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
.settings-span-center {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
.settings-span-right {
|
||||||
|
display: inline-block;
|
||||||
|
right: 0px;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
.tabs .tab a {
|
||||||
|
background: #757575;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.tabs .tab a:hover {
|
||||||
|
color: #BDBDBD;
|
||||||
|
}
|
||||||
|
.tabs .indicator {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 601px) and (max-width : 1260px) {
|
||||||
|
.toast {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 1261px) {
|
||||||
|
.toast {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 601px) and (max-width : 1260px) {
|
||||||
|
#toast-container {
|
||||||
|
bottom: 0;
|
||||||
|
top: 90%;
|
||||||
|
right: 50%;
|
||||||
|
transform: translate(50%, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 1261px) {
|
||||||
|
#toast-container {
|
||||||
|
bottom: 0;
|
||||||
|
top: 90%;
|
||||||
|
right: 50%;
|
||||||
|
transform: translate(50%, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -431,6 +431,7 @@
|
||||||
%>
|
%>
|
||||||
%if linky:
|
%if linky:
|
||||||
<a href="downloadthis?pathfile=${linky |u}"><img src="interfaces/default/images/download_icon.png" height="25" width="25" title="Download the Issue" class="highqual" /></a>
|
<a href="downloadthis?pathfile=${linky |u}"><img src="interfaces/default/images/download_icon.png" height="25" width="25" title="Download the Issue" class="highqual" /></a>
|
||||||
|
<a href="read_comic?ish_id=${issue['IssueID']}&page_num=0&size=high"><img src="interfaces/default/images/readabook.png" height="25" width="25" title="Read the Issue in your Browser" class="highqual" /></a>
|
||||||
%if linky.endswith('.cbz'):
|
%if linky.endswith('.cbz'):
|
||||||
<a href="#issue-box" onclick="return runMetaIssue('${linky |u}', '${comic['ComicName']| u}', '${issue['Issue_Number']}', '${issue['IssueDate']}', '${issue['IssueName'] |u}');" class="issue-window"><img src="interfaces/default/images/issueinfo.png" height="25" width="25" title="View Issue Details" class="highqual" /></a>
|
<a href="#issue-box" onclick="return runMetaIssue('${linky |u}', '${comic['ComicName']| u}', '${issue['Issue_Number']}', '${issue['IssueDate']}', '${issue['IssueName'] |u}');" class="issue-window"><img src="interfaces/default/images/issueinfo.png" height="25" width="25" title="View Issue Details" class="highqual" /></a>
|
||||||
<div id="issue-box" class="issue-popup">
|
<div id="issue-box" class="issue-popup">
|
||||||
|
|
16
data/interfaces/default/header.html
Normal file
16
data/interfaces/default/header.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<%page args="jscolor=False"/>
|
||||||
|
<head>
|
||||||
|
<title>Mylar WebViewer</title>
|
||||||
|
<meta name="description" content="Mylar Web Viewer">
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/webviewerstyle.css">
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/js/materialize.min.js"></script>
|
||||||
|
% if jscolor is True:
|
||||||
|
<script src="js/jscolor.min.js"></script>
|
||||||
|
% endif
|
||||||
|
</head>
|
114
data/interfaces/default/read.html
Normal file
114
data/interfaces/default/read.html
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
<%!
|
||||||
|
import mylar
|
||||||
|
%>
|
||||||
|
<%
|
||||||
|
now_page = pages[current_page]
|
||||||
|
%>
|
||||||
|
<!doctype html>
|
||||||
|
<html class="whole-page">
|
||||||
|
<%include file="header.html" />
|
||||||
|
|
||||||
|
<body class="inner-page">
|
||||||
|
<div class="reader-whole">
|
||||||
|
% if (current_page + 1) == 1:
|
||||||
|
<a class="btn btn-floating btn-large pulse tooltipped" id="settings-help" data-position="bottom" data-delay="50" data-tooltip="Click the center to bring up settings. Click the left and right sides of the page to change pages."><i class="material-icons">help_outline</i></a>
|
||||||
|
% endif
|
||||||
|
<div class="col s12 overlay-settings">
|
||||||
|
<div class="overlay-settings-text">
|
||||||
|
<div class="page-left">
|
||||||
|
<span class="settings-span-left">
|
||||||
|
<h4 style="display: none;" id="page-settings-left-text">
|
||||||
|
<i class="large material-icons" id="settings-arrow">arrow_back</i>
|
||||||
|
</h4>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="page-settings">
|
||||||
|
<span class="settings-span-center">
|
||||||
|
<p style="display: none;" id="page-settings-text">
|
||||||
|
<a class="waves-effect waves-light btn-large" id="settings-button" href="index">Home</a>
|
||||||
|
</br>
|
||||||
|
</br>
|
||||||
|
<b>On Page ${current_page + 1} of ${nop} Pages</b>
|
||||||
|
</br>
|
||||||
|
</br>
|
||||||
|
<a class="waves-effect waves-light btn-large" id="settings-button" action="action" value="Back" onclick="window.history.go(-1); return false">Close Book</a>
|
||||||
|
</br>
|
||||||
|
</br>
|
||||||
|
<b>Fit Comic to Height/Width/No Fit</b>
|
||||||
|
</br>
|
||||||
|
</br>
|
||||||
|
<a class="waves-effect waves-light btn-large" id="size-width-button" href="#!">Width</a>
|
||||||
|
<a class="waves-effect waves-light btn-large" id="size-height-button" href="#!">Height</a>
|
||||||
|
<a class="waves-effect waves-light btn-large" id="size-normal-button" href="#!">No Fit</a>
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="page-right">
|
||||||
|
<span class="settings-span-right">
|
||||||
|
<h4 style="display: none;" id="page-settings-right-text"><i class="large material-icons" id="settings-arrow">arrow_forward</i></h4>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row reader-overlay">
|
||||||
|
% if size == "wide":
|
||||||
|
<img class="reader-page-wide" src="${now_page}"/>
|
||||||
|
% elif size == "high":
|
||||||
|
<img class="reader-page-high" src="${now_page}"/>
|
||||||
|
% elif size == "norm":
|
||||||
|
<img class="reader-page-norm" src="${now_page}"/>
|
||||||
|
% else:
|
||||||
|
<img class="reader-page-wide" src="${now_page}"/>
|
||||||
|
% endif:
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('.modal-trigger').leanModal();
|
||||||
|
$(".page-settings").click(function() {
|
||||||
|
$(".page-settings").toggleClass( "dimmed" );
|
||||||
|
$(".page-left").toggleClass( "dimmed" );
|
||||||
|
$(".page-right").toggleClass( "dimmed" );
|
||||||
|
$("#page-settings-text").toggle();
|
||||||
|
$("#page-settings-left-text").toggle();
|
||||||
|
$("#page-settings-right-text").toggle();
|
||||||
|
});
|
||||||
|
$(".page-right").click(function() {
|
||||||
|
$(".whole-page").load("${mylar.CONFIG.HTTP_ROOT}read_comic?ish_id=${ish_id}&page_num=${np}&size=${size}");
|
||||||
|
});
|
||||||
|
$(".page-left").click(function() {
|
||||||
|
$(".whole-page").load("${mylar.CONFIG.HTTP_ROOT}read_comic?ish_id=${ish_id}&page_num=${pp}&size=${size}");
|
||||||
|
});
|
||||||
|
$(document).one("keyup", function(e) {
|
||||||
|
if (e.which == 39) {
|
||||||
|
$(".whole-page").load("${mylar.CONFIG.HTTP_ROOT}read_comic?ish_id=${ish_id}&page_num=${np}&size=${size}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(document).one("keyup", function(e) {
|
||||||
|
if (e.which == 37) {
|
||||||
|
$(".whole-page").load("${mylar.CONFIG.HTTP_ROOT}read_comic?ish_id=${ish_id}&page_num=${pp}&size=${size}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$("#size-width-button").click(function() {
|
||||||
|
$(".reader-overlay").html("<img class='reader-page-wide' src='${now_page}'/>");
|
||||||
|
// $.ajax({
|
||||||
|
// url: "up_size_pref?pref=wide"
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
$("#size-height-button").click(function() {
|
||||||
|
$(".reader-overlay").html("<img class='reader-page-high' src='${now_page}'/>");
|
||||||
|
// $.ajax({
|
||||||
|
// url: "up_size_pref?pref=high"
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
$("#size-normal-button").click(function() {
|
||||||
|
$(".reader-overlay").html("<img class='reader-page-norm' src='${now_page}'/>");
|
||||||
|
// $.ajax({
|
||||||
|
// url: "up_size_pref?pref=norm"
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</html>
|
10
data/js/jscolor.min.js
vendored
Normal file
10
data/js/jscolor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1279
lib/pathlib.py
Normal file
1279
lib/pathlib.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -6426,3 +6426,14 @@ class WebInterface(object):
|
||||||
|
|
||||||
download_specific_release.exposed = True
|
download_specific_release.exposed = True
|
||||||
|
|
||||||
|
def read_comic(self, ish_id, page_num, size):
|
||||||
|
from mylar.webviewer import WebViewer
|
||||||
|
wv = WebViewer()
|
||||||
|
page_num = int(page_num)
|
||||||
|
#cherrypy.session['ishid'] = ish_id
|
||||||
|
data = wv.read_comic(ish_id, page_num, size)
|
||||||
|
#data = wv.read_comic(ish_id)
|
||||||
|
return data
|
||||||
|
read_comic.exposed = True
|
||||||
|
|
||||||
|
|
163
mylar/webviewer.py
Normal file
163
mylar/webviewer.py
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import cherrypy
|
||||||
|
import stat
|
||||||
|
import zipfile
|
||||||
|
from lib.rarfile import rarfile
|
||||||
|
|
||||||
|
import mylar
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
from mylar import logger, db, importer, mb, search, filechecker, helpers, updater, parseit, weeklypull, librarysync, moveit, Failed, readinglist, config
|
||||||
|
from mylar.webserve import serve_template
|
||||||
|
|
||||||
|
class WebViewer(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.ish_id = None
|
||||||
|
self.page_num = None
|
||||||
|
self.kwargs = None
|
||||||
|
self.data = None
|
||||||
|
|
||||||
|
if not os.path.exists(os.path.join(mylar.DATA_DIR, 'sessions')):
|
||||||
|
os.makedirs(os.path.abspath(os.path.join(mylar.DATA_DIR, 'sessions')))
|
||||||
|
|
||||||
|
updatecherrypyconf = {
|
||||||
|
'tools.gzip.on': True,
|
||||||
|
'tools.gzip.mime_types': ['text/*', 'application/*', 'image/*'],
|
||||||
|
'tools.sessions.timeout': 1440,
|
||||||
|
'tools.sessions.storage_class': cherrypy.lib.sessions.FileSession,
|
||||||
|
'tools.sessions.storage_path': os.path.join(mylar.DATA_DIR, "sessions"),
|
||||||
|
'request.show_tracebacks': False,
|
||||||
|
}
|
||||||
|
if mylar.CONFIG.HTTP_PASSWORD is None:
|
||||||
|
updatecherrypyconf.update({
|
||||||
|
'tools.sessions.on': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
cherrypy.config.update(updatecherrypyconf)
|
||||||
|
cherrypy.engine.signals.subscribe()
|
||||||
|
cherrypy.engine.timeout_monitor.unsubscribe()
|
||||||
|
|
||||||
|
def read_comic(self, ish_id = None, page_num = None, size = None):
|
||||||
|
logger.debug("WebReader Requested, looking for ish_id %s and page_num %s" % (ish_id, page_num))
|
||||||
|
if size == None:
|
||||||
|
user_size_pref = 'wide'
|
||||||
|
else:
|
||||||
|
user_size_pref = size
|
||||||
|
|
||||||
|
try:
|
||||||
|
ish_id
|
||||||
|
except:
|
||||||
|
logger.warn("WebReader: ish_id not set!")
|
||||||
|
|
||||||
|
myDB = db.DBConnection()
|
||||||
|
comic = myDB.selectone('select comics.ComicLocation, issues.Location from comics, issues where comics.comicid = issues.comicid and issues.issueid = ?' , [ish_id]).fetchone()
|
||||||
|
if comic is None:
|
||||||
|
logger.warn("WebReader: ish_id %s requested but not in the database!" % ish_id)
|
||||||
|
raise cherrypy.HTTPRedirect("home")
|
||||||
|
# cherrypy.config.update()
|
||||||
|
comic_path = os.path.join(comic['ComicLocation'], comic['Location'])
|
||||||
|
logger.debug("WebReader found ish_id %s at %s" % (ish_id, comic_path))
|
||||||
|
|
||||||
|
# cherrypy.session['ish_id'].load()
|
||||||
|
# if 'sizepref' not in cherrypy.session:
|
||||||
|
# cherrypy.session['sizepref'] = user_size_pref
|
||||||
|
# user_size_pref = cherrypy.session['sizepref']
|
||||||
|
# logger.debug("WebReader setting user_size_pref to %s" % user_size_pref)
|
||||||
|
|
||||||
|
scanner = ComicScanner()
|
||||||
|
image_list = scanner.reading_images(ish_id)
|
||||||
|
logger.debug("Image list contains %s pages" % (len(image_list)))
|
||||||
|
if len(image_list) == 0:
|
||||||
|
logger.debug("Unpacking ish_id %s from comic_path %s" % (ish_id, comic_path))
|
||||||
|
scanner.user_unpack_comic(ish_id, comic_path)
|
||||||
|
else:
|
||||||
|
logger.debug("ish_id %s already unpacked." % ish_id)
|
||||||
|
|
||||||
|
num_pages = len(image_list)
|
||||||
|
logger.debug("Found %s pages for ish_id %s from comic_path %s" % (num_pages, ish_id, comic_path))
|
||||||
|
|
||||||
|
if num_pages == 0:
|
||||||
|
image_list = ['images/skipped_icon.png']
|
||||||
|
|
||||||
|
cookie_comic = re.sub(r'\W+', '', comic_path)
|
||||||
|
cookie_comic = "wv_" + cookie_comic.decode('unicode_escape')
|
||||||
|
logger.debug("about to drop a cookie for " + cookie_comic + " which represents " + comic_path)
|
||||||
|
cookie_check = cherrypy.request.cookie
|
||||||
|
if cookie_comic not in cookie_check:
|
||||||
|
logger.debug("Cookie Creation")
|
||||||
|
cookie_path = '/'
|
||||||
|
cookie_maxage = '2419200'
|
||||||
|
cookie_set = cherrypy.response.cookie
|
||||||
|
cookie_set['cookie_comic'] = 0
|
||||||
|
cookie_set['cookie_comic']['path'] = cookie_path.decode('unicode_escape')
|
||||||
|
cookie_set['cookie_comic']['max-age'] = cookie_maxage.decode('unicode_escape')
|
||||||
|
next_page = page_num + 1
|
||||||
|
prev_page = page_num - 1
|
||||||
|
else:
|
||||||
|
logger.debug("Cookie Read")
|
||||||
|
page_num = int(cherrypy.request.cookie['cookie_comic'].value)
|
||||||
|
logger.debug("Cookie Set To %d" % page_num)
|
||||||
|
next_page = page_num + 1
|
||||||
|
prev_page = page_num - 1
|
||||||
|
|
||||||
|
logger.info("Reader Served")
|
||||||
|
logger.debug("Serving comic " + comic['Location'] + " page number " + str(page_num))
|
||||||
|
|
||||||
|
return serve_template(templatename="read.html", pages=image_list, current_page=page_num, np=next_page, pp=prev_page, nop=num_pages, size=user_size_pref, cc=cookie_comic, comicpath=comic_path, ish_id=ish_id)
|
||||||
|
|
||||||
|
def up_size_pref(self, pref):
|
||||||
|
cherrypy.session.load()
|
||||||
|
cherrypy.session['sizepref'] = pref
|
||||||
|
cherrypy.session.save()
|
||||||
|
return
|
||||||
|
|
||||||
|
class ComicScanner(object):
|
||||||
|
|
||||||
|
# This method will handle scanning the directories and returning a list of them all.
|
||||||
|
def dir_scan(self):
|
||||||
|
logger.debug("Dir Scan Requested")
|
||||||
|
full_paths = []
|
||||||
|
full_paths.append(mylar.CONFIG.DESTINATION_DIR)
|
||||||
|
for root, dirs, files in os.walk(mylar.CONFIG.DESTINATION_DIR):
|
||||||
|
full_paths.extend(os.path.join(root, d) for d in dirs)
|
||||||
|
|
||||||
|
logger.info("Dir Scan Completed")
|
||||||
|
logger.info("%i Dirs Found" % (len(full_paths)))
|
||||||
|
return full_paths
|
||||||
|
|
||||||
|
def user_unpack_comic(self, ish_id, comic_path):
|
||||||
|
logger.info("%s unpack requested" % comic_path)
|
||||||
|
for root, dirs, files in os.walk(os.path.join(mylar.CONFIG.CACHE_DIR, "webviewer", ish_id), topdown=False):
|
||||||
|
for f in files:
|
||||||
|
os.chmod(os.path.join(root, f), stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777
|
||||||
|
os.remove(os.path.join(root, f))
|
||||||
|
for root, dirs, files in os.walk(os.path.join(mylar.CONFIG.CACHE_DIR, "webviewer", ish_id), topdown=False):
|
||||||
|
for d in dirs:
|
||||||
|
os.chmod(os.path.join(root, d), stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777
|
||||||
|
os.rmdir(os.path.join(root, d))
|
||||||
|
if comic_path.endswith(".cbr"):
|
||||||
|
opened_rar = rarfile.RarFile(comic_path)
|
||||||
|
opened_rar.extractall(os.path.join(mylar.CONFIG.CACHE_DIR, "webviewer", ish_id))
|
||||||
|
elif comic_path.endswith(".cbz"):
|
||||||
|
opened_zip = zipfile.ZipFile(comic_path)
|
||||||
|
opened_zip.extractall(os.path.join(mylar.CONFIG.CACHE_DIR, "webviewer", ish_id))
|
||||||
|
return
|
||||||
|
|
||||||
|
# This method will return a list of .jpg files in their numberical order to be fed into the reading view.
|
||||||
|
def reading_images(self, ish_id):
|
||||||
|
logger.debug("Image List Requested")
|
||||||
|
image_list = []
|
||||||
|
image_src = os.path.join(mylar.CONFIG.CACHE_DIR, "webviewer", ish_id)
|
||||||
|
image_loc = os.path.join(mylar.CONFIG.HTTP_ROOT, 'cache', "webviewer", ish_id)
|
||||||
|
for root, dirs, files in os.walk(image_src):
|
||||||
|
for f in files:
|
||||||
|
if f.endswith((".png", ".gif", ".bmp", ".dib", ".jpg", ".jpeg", ".jpe", ".jif", ".jfif", ".jfi", ".tiff", ".tif")):
|
||||||
|
image_list.append( os.path.join(image_loc, f) )
|
||||||
|
image_list.sort()
|
||||||
|
logger.debug("Image List Created")
|
||||||
|
return image_list
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue