Commit d45b1b8e authored by Ozzieisaacs's avatar Ozzieisaacs

Fix #937

logviewerintegrated
Code cosmetics
parent 26949970
...@@ -33,8 +33,8 @@ Calibre-Web is a web app providing a clean interface for browsing, reading and d ...@@ -33,8 +33,8 @@ Calibre-Web is a web app providing a clean interface for browsing, reading and d
1. Install dependencies by running `pip install --target vendor -r requirements.txt`. 1. Install dependencies by running `pip install --target vendor -r requirements.txt`.
2. Execute the command: `python cps.py` (or `nohup python cps.py` - recommended if you want to exit the terminal window) 2. Execute the command: `python cps.py` (or `nohup python cps.py` - recommended if you want to exit the terminal window)
3. Point your browser to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog 3. Point your browser to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog
4. Set `Location of Calibre database` to the path of the folder where your Calibre library (metadata.db) lives, push "submit" button 4. Set `Location of Calibre database` to the path of the folder where your Calibre library (metadata.db) lives, push "submit" button\
optionally a google drive can be used to host the calibre library (-> Using Google Drive integration) Optionally a Google Drive can be used to host the calibre library [-> Using Google Drive integration](https://github.com/janeczku/calibre-web/wiki/Configuration#using-google-drive-integration)
5. Go to Login page 5. Go to Login page
**Default admin login:**\ **Default admin login:**\
...@@ -50,26 +50,35 @@ Python 2.7+, python 3.x+ ...@@ -50,26 +50,35 @@ Python 2.7+, python 3.x+
Optionally, to enable on-the-fly conversion from one ebook format to another when using the send-to-kindle feature, or during editing of ebooks metadata: Optionally, to enable on-the-fly conversion from one ebook format to another when using the send-to-kindle feature, or during editing of ebooks metadata:
[Download and install](https://calibre-ebook.com/download) the Calibre desktop program for your platform and enter the folder including programm name (normally /opt/calibre/ebook-convert, or c:\prgogram files\calibre\ebook-convert.exe) in the field "calibre's converter tool" on the setup page. [Download and install](https://calibre-ebook.com/download) the Calibre desktop program for your platform and enter the folder including programm name (normally /opt/calibre/ebook-convert, or C:\Program Files\calibre\ebook-convert.exe) in the field "calibre's converter tool" on the setup page.
\*** DEPRECATED \*** Support will be removed in future releases \*** DEPRECATED \*** Support will be removed in future releases
Optionally, to enable on-the-fly conversion from EPUB to MOBI when using the send-to-kindle feature:
[Download Kindlegen](http://www.amazon.com/gp/feature.html?docId=1000765211) Amazon's KindleGen tool for your platform and place the binary named as `kindlegen` in the `vendor` folder. [Download](http://www.amazon.com/gp/feature.html?docId=1000765211) Amazon's KindleGen tool for your platform and place the binary named as `kindlegen` in the `vendor` folder.
## Docker images ## Docker Images
Pre-built Docker images based on Alpine Linux are available in these Docker Hub repositories: Pre-built Docker images are available in these Docker Hub repositories:
**x64** #### **Technosoft2000 - x64**
+ **technosoft2000** at [technosoft2000/calibre-web](https://hub.docker.com/r/technosoft2000/calibre-web/). If you want the option to convert/download ebooks in multiple formats, use this image as it includes Calibre's ebook-convert binary. The "path to convertertool" should be set to /opt/calibre/ebook-convert. + Docker Hub - [https://hub.docker.com/r/technosoft2000/calibre-web/](https://hub.docker.com/r/technosoft2000/calibre-web/)
+ **linuxserver.io** at [linuxserver/calibre-web](https://hub.docker.com/r/linuxserver/calibre-web/). Cannot convert between ebook formats. + Github - [https://github.com/Technosoft2000/docker-calibre-web](https://github.com/Technosoft2000/docker-calibre-web)
**armhf** Includes the Calibre `ebook-convert` binary.
+ **linuxserver.io** at [lsioarmhf/calibre-web](https://hub.docker.com/r/lsioarmhf/calibre-web/) + The "path to convertertool" should be set to `/opt/calibre/ebook-convert`
**aarch64** #### **LinuxServer - x64, armhf, aarch64**
+ **linuxserver.io** at [lsioarmhf/calibre-web-aarch64](https://hub.docker.com/r/lsioarmhf/calibre-web-aarch64) + Docker Hub - [https://hub.docker.com/r/linuxserver/calibre-web/](https://hub.docker.com/r/linuxserver/calibre-web/)
+ Github - [https://github.com/linuxserver/docker-calibre-web](https://github.com/linuxserver/docker-calibre-web)
+ Github - (Optional Calibre layer) - [https://github.com/linuxserver/docker-calibre-web/tree/calibre](https://github.com/linuxserver/docker-calibre-web/tree/calibre)
This image has the option to pull in an extra docker manifest layer to include the Calibre `ebook-convert` binary. Just include the environmental variable `DOCKER_MODS=linuxserver/calibre-web:calibre` in your docker run/docker compose file. **(x64 only)**
If you do not need this functionality then this can be omitted, keeping the image as lightweight as possible.
Both the Calibre-Web and Calibre-Mod images are rebuilt automatically on new releases of Calibre-Web and Calibre respectively, and on updates to any included base image packages on a weekly basis if required.
+ The "path to convertertool" should be set to `/usr/bin/ebook-convert`
+ The "path to unrar" should be set to `/usr/bin/unrar`
# Wiki # Wiki
......
...@@ -26,6 +26,8 @@ import os ...@@ -26,6 +26,8 @@ import os
import json import json
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
# import uuid
import random
try: try:
from imp import reload from imp import reload
except ImportError: except ImportError:
...@@ -33,7 +35,7 @@ except ImportError: ...@@ -33,7 +35,7 @@ except ImportError:
from babel import Locale as LC from babel import Locale as LC
from babel.dates import format_datetime from babel.dates import format_datetime
from flask import Blueprint, flash, redirect, url_for, abort, request, make_response from flask import Blueprint, flash, redirect, url_for, abort, request, make_response, send_from_directory
from flask_login import login_required, current_user, logout_user from flask_login import login_required, current_user, logout_user
from flask_babel import gettext as _ from flask_babel import gettext as _
from sqlalchemy import and_ from sqlalchemy import and_
...@@ -542,6 +544,9 @@ def new_user(): ...@@ -542,6 +544,9 @@ def new_user():
to_save = request.form.to_dict() to_save = request.form.to_dict()
content.default_language = to_save["default_language"] content.default_language = to_save["default_language"]
content.mature_content = "Show_mature_content" in to_save content.mature_content = "Show_mature_content" in to_save
dat = datetime.strptime("1.1.2019", "%d.%m.%Y")
content.id = int(time.time()*100)
# val= int(uuid.uuid4())
if "locale" in to_save: if "locale" in to_save:
content.locale = to_save["locale"] content.locale = to_save["locale"]
...@@ -551,6 +556,7 @@ def new_user(): ...@@ -551,6 +556,7 @@ def new_user():
val += int(key[5:]) val += int(key[5:])
content.sidebar_view = val content.sidebar_view = val
if "show_detail_random" in to_save: if "show_detail_random" in to_save:
content.sidebar_view |= constants.DETAIL_RANDOM content.sidebar_view |= constants.DETAIL_RANDOM
...@@ -758,6 +764,25 @@ def reset_password(user_id): ...@@ -758,6 +764,25 @@ def reset_password(user_id):
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))
@admi.route("/admin/logfile")
@login_required
@admin_required
def view_logfile():
perpage_p = {0:"30",1:"40",2:"100"}
for key, value in perpage_p.items():
print(key)
print(value)
return render_title_template("logviewer.html",title=_(u"Logfile viewer"), perpage_p=perpage_p, perpage = 30,
page="logfile")
@admi.route("/ajax/accesslog")
@login_required
@admin_required
def send_logfile():
return send_from_directory(constants.BASE_DIR,"access.log")
@admi.route("/get_update_status", methods=['GET']) @admi.route("/get_update_status", methods=['GET'])
@login_required_if_no_ano @login_required_if_no_ano
def get_update_status(): def get_update_status():
......
...@@ -88,8 +88,8 @@ def setup(log_file, log_level=None, logger=None): ...@@ -88,8 +88,8 @@ def setup(log_file, log_level=None, logger=None):
log_file = os.path.join(_BASE_DIR, log_file) log_file = os.path.join(_BASE_DIR, log_file)
log_file = os.path.abspath(log_file) log_file = os.path.abspath(log_file)
else: else:
# log_file = LOG_TO_STDERR log_file = LOG_TO_STDERR
log_file = default_file # log_file = default_file
# print ('%r -- %r' % (log_level, log_file)) # print ('%r -- %r' % (log_level, log_file))
if logger != "access" and logger != "tornado.access": if logger != "access" and logger != "tornado.access":
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
* Copyright(c) 2011 Google Inc. * Copyright(c) 2011 Google Inc.
* Copyright(c) 2011 antimatter15 * Copyright(c) 2011 antimatter15
*/ */
/* global bitjs, Uint8Array */
var bitjs = bitjs || {}; var bitjs = bitjs || {};
bitjs.io = bitjs.io || {}; bitjs.io = bitjs.io || {};
...@@ -30,20 +33,20 @@ bitjs.io = bitjs.io || {}; ...@@ -30,20 +33,20 @@ bitjs.io = bitjs.io || {};
* @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array.
* @param {boolean} rtl Whether the stream reads bits from the byte starting * @param {boolean} rtl Whether the stream reads bits from the byte starting
* from bit 7 to 0 (true) or bit 0 to 7 (false). * from bit 7 to 0 (true) or bit 0 to 7 (false).
* @param {Number} opt_offset The offset into the ArrayBuffer * @param {Number} optOffset The offset into the ArrayBuffer
* @param {Number} opt_length The length of this BitStream * @param {Number} optLength The length of this BitStream
*/ */
bitjs.io.BitStream = function(ab, rtl, opt_offset, opt_length) { bitjs.io.BitStream = function(ab, rtl, optOffset, optLength) {
if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") { if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") {
throw "Error! BitArray constructed with an invalid ArrayBuffer object"; throw "Error! BitArray constructed with an invalid ArrayBuffer object";
} }
var offset = opt_offset || 0; var offset = optOffset || 0;
var length = opt_length || ab.byteLength; var length = optLength || ab.byteLength;
this.bytes = new Uint8Array(ab, offset, length); this.bytes = new Uint8Array(ab, offset, length);
this.bytePtr = 0; // tracks which byte we are on this.bytePtr = 0; // tracks which byte we are on
this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7) this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7)
this.peekBits = rtl ? this.peekBits_rtl : this.peekBits_ltr; this.peekBits = rtl ? this.peekBitsRtl : this.peekBitsLtr;
}; };
...@@ -57,8 +60,8 @@ bitjs.io = bitjs.io || {}; ...@@ -57,8 +60,8 @@ bitjs.io = bitjs.io || {};
* @param {boolean=} movePointers Whether to move the pointer, defaults false. * @param {boolean=} movePointers Whether to move the pointer, defaults false.
* @return {number} The peeked bits, as an unsigned number. * @return {number} The peeked bits, as an unsigned number.
*/ */
bitjs.io.BitStream.prototype.peekBits_ltr = function(n, movePointers) { bitjs.io.BitStream.prototype.peekBitsLtr = function(n, movePointers) {
if (n <= 0 || typeof n != typeof 1) { if (n <= 0 || typeof n !== typeof 1) {
return 0; return 0;
} }
...@@ -77,12 +80,13 @@ bitjs.io = bitjs.io || {}; ...@@ -77,12 +80,13 @@ bitjs.io = bitjs.io || {};
if (bytePtr >= bytes.length) { if (bytePtr >= bytes.length) {
throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" +
bytes.length + ", bitPtr=" + bitPtr; bytes.length + ", bitPtr=" + bitPtr;
return -1; // return -1;
} }
var numBitsLeftInThisByte = (8 - bitPtr); var numBitsLeftInThisByte = (8 - bitPtr);
var mask;
if (n >= numBitsLeftInThisByte) { if (n >= numBitsLeftInThisByte) {
var mask = (BITMASK[numBitsLeftInThisByte] << bitPtr); mask = (BITMASK[numBitsLeftInThisByte] << bitPtr);
result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn);
bytePtr++; bytePtr++;
...@@ -90,7 +94,7 @@ bitjs.io = bitjs.io || {}; ...@@ -90,7 +94,7 @@ bitjs.io = bitjs.io || {};
bitsIn += numBitsLeftInThisByte; bitsIn += numBitsLeftInThisByte;
n -= numBitsLeftInThisByte; n -= numBitsLeftInThisByte;
} else { } else {
var mask = (BITMASK[n] << bitPtr); mask = (BITMASK[n] << bitPtr);
result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn);
bitPtr += n; bitPtr += n;
...@@ -118,8 +122,8 @@ bitjs.io = bitjs.io || {}; ...@@ -118,8 +122,8 @@ bitjs.io = bitjs.io || {};
* @param {boolean=} movePointers Whether to move the pointer, defaults false. * @param {boolean=} movePointers Whether to move the pointer, defaults false.
* @return {number} The peeked bits, as an unsigned number. * @return {number} The peeked bits, as an unsigned number.
*/ */
bitjs.io.BitStream.prototype.peekBits_rtl = function(n, movePointers) { bitjs.io.BitStream.prototype.peekBitsRtl = function(n, movePointers) {
if (n <= 0 || typeof n != typeof 1) { if (n <= 0 || typeof n !== typeof 1) {
return 0; return 0;
} }
...@@ -138,7 +142,7 @@ bitjs.io = bitjs.io || {}; ...@@ -138,7 +142,7 @@ bitjs.io = bitjs.io || {};
if (bytePtr >= bytes.length) { if (bytePtr >= bytes.length) {
throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" +
bytes.length + ", bitPtr=" + bitPtr; bytes.length + ", bitPtr=" + bitPtr;
return -1; // return -1;
} }
var numBitsLeftInThisByte = (8 - bitPtr); var numBitsLeftInThisByte = (8 - bitPtr);
...@@ -198,19 +202,19 @@ bitjs.io = bitjs.io || {}; ...@@ -198,19 +202,19 @@ bitjs.io = bitjs.io || {};
* @return {Uint8Array} The subarray. * @return {Uint8Array} The subarray.
*/ */
bitjs.io.BitStream.prototype.peekBytes = function(n, movePointers) { bitjs.io.BitStream.prototype.peekBytes = function(n, movePointers) {
if (n <= 0 || typeof n != typeof 1) { if (n <= 0 || typeof n !== typeof 1) {
return 0; return 0;
} }
// from http://tools.ietf.org/html/rfc1951#page-11 // from http://tools.ietf.org/html/rfc1951#page-11
// "Any bits of input up to the next byte boundary are ignored." // "Any bits of input up to the next byte boundary are ignored."
while (this.bitPtr != 0) { while (this.bitPtr !== 0) {
this.readBits(1); this.readBits(1);
} }
var movePointers = movePointers || false; var movePointers = movePointers || false;
var bytePtr = this.bytePtr, var bytePtr = this.bytePtr;
bitPtr = this.bitPtr; // bitPtr = this.bitPtr;
var result = this.bytes.subarray(bytePtr, bytePtr + n); var result = this.bytes.subarray(bytePtr, bytePtr + n);
...@@ -230,4 +234,4 @@ bitjs.io = bitjs.io || {}; ...@@ -230,4 +234,4 @@ bitjs.io = bitjs.io || {};
return this.peekBytes(n, true); return this.peekBytes(n, true);
}; };
})(); })();
\ No newline at end of file
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
* Copyright(c) 2011 Google Inc. * Copyright(c) 2011 Google Inc.
* Copyright(c) 2011 antimatter15 * Copyright(c) 2011 antimatter15
*/ */
/* global bitjs, Uint8Array */
var bitjs = bitjs || {}; var bitjs = bitjs || {};
bitjs.io = bitjs.io || {}; bitjs.io = bitjs.io || {};
...@@ -20,7 +23,7 @@ bitjs.io = bitjs.io || {}; ...@@ -20,7 +23,7 @@ bitjs.io = bitjs.io || {};
* @constructor * @constructor
*/ */
bitjs.io.ByteBuffer = function(numBytes) { bitjs.io.ByteBuffer = function(numBytes) {
if (typeof numBytes != typeof 1 || numBytes <= 0) { if (typeof numBytes !== typeof 1 || numBytes <= 0) {
throw "Error! ByteBuffer initialized with '" + numBytes + "'"; throw "Error! ByteBuffer initialized with '" + numBytes + "'";
} }
this.data = new Uint8Array(numBytes); this.data = new Uint8Array(numBytes);
...@@ -55,14 +58,14 @@ bitjs.io = bitjs.io || {}; ...@@ -55,14 +58,14 @@ bitjs.io = bitjs.io || {};
*/ */
bitjs.io.ByteBuffer.prototype.writeNumber = function(num, numBytes) { bitjs.io.ByteBuffer.prototype.writeNumber = function(num, numBytes) {
if (numBytes < 1) { if (numBytes < 1) {
throw 'Trying to write into too few bytes: ' + numBytes; throw "Trying to write into too few bytes: " + numBytes;
} }
if (num < 0) { if (num < 0) {
throw 'Trying to write a negative number (' + num + throw "Trying to write a negative number (" + num +
') as an unsigned number to an ArrayBuffer'; ") as an unsigned number to an ArrayBuffer";
} }
if (num > (Math.pow(2, numBytes * 8) - 1)) { if (num > (Math.pow(2, numBytes * 8) - 1)) {
throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; throw "Trying to write " + num + " into only " + numBytes + " bytes";
} }
// Roll 8-bits at a time into an array of bytes. // Roll 8-bits at a time into an array of bytes.
...@@ -85,12 +88,12 @@ bitjs.io = bitjs.io || {}; ...@@ -85,12 +88,12 @@ bitjs.io = bitjs.io || {};
*/ */
bitjs.io.ByteBuffer.prototype.writeSignedNumber = function(num, numBytes) { bitjs.io.ByteBuffer.prototype.writeSignedNumber = function(num, numBytes) {
if (numBytes < 1) { if (numBytes < 1) {
throw 'Trying to write into too few bytes: ' + numBytes; throw "Trying to write into too few bytes: " + numBytes;
} }
var HALF = Math.pow(2, (numBytes * 8) - 1); var HALF = Math.pow(2, (numBytes * 8) - 1);
if (num >= HALF || num < -HALF) { if (num >= HALF || num < -HALF) {
throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; throw "Trying to write " + num + " into only " + numBytes + " bytes";
} }
// Roll 8-bits at a time into an array of bytes. // Roll 8-bits at a time into an array of bytes.
...@@ -112,10 +115,10 @@ bitjs.io = bitjs.io || {}; ...@@ -112,10 +115,10 @@ bitjs.io = bitjs.io || {};
for (var i = 0; i < str.length; ++i) { for (var i = 0; i < str.length; ++i) {
var curByte = str.charCodeAt(i); var curByte = str.charCodeAt(i);
if (curByte < 0 || curByte > 255) { if (curByte < 0 || curByte > 255) {
throw 'Trying to write a non-ASCII string!'; throw "Trying to write a non-ASCII string!";
} }
this.insertByte(curByte); this.insertByte(curByte);
} }
}; };
})(); })();
\ No newline at end of file
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
* Copyright(c) 2011 Google Inc. * Copyright(c) 2011 Google Inc.
* Copyright(c) 2011 antimatter15 * Copyright(c) 2011 antimatter15
*/ */
/* global bitjs, Uint8Array */
var bitjs = bitjs || {}; var bitjs = bitjs || {};
bitjs.io = bitjs.io || {}; bitjs.io = bitjs.io || {};
...@@ -19,13 +22,13 @@ bitjs.io = bitjs.io || {}; ...@@ -19,13 +22,13 @@ bitjs.io = bitjs.io || {};
* out of an ArrayBuffer. In this buffer, everything must be byte-aligned. * out of an ArrayBuffer. In this buffer, everything must be byte-aligned.
* *
* @param {ArrayBuffer} ab The ArrayBuffer object. * @param {ArrayBuffer} ab The ArrayBuffer object.
* @param {number=} opt_offset The offset into the ArrayBuffer * @param {number=} optOffset The offset into the ArrayBuffer
* @param {number=} opt_length The length of this BitStream * @param {number=} optLength The length of this BitStream
* @constructor * @constructor
*/ */
bitjs.io.ByteStream = function(ab, opt_offset, opt_length) { bitjs.io.ByteStream = function(ab, optOffset, optLength) {
var offset = opt_offset || 0; var offset = optOffset || 0;
var length = opt_length || ab.byteLength; var length = optLength || ab.byteLength;
this.bytes = new Uint8Array(ab, offset, length); this.bytes = new Uint8Array(ab, offset, length);
this.ptr = 0; this.ptr = 0;
}; };
...@@ -40,8 +43,9 @@ bitjs.io = bitjs.io || {}; ...@@ -40,8 +43,9 @@ bitjs.io = bitjs.io || {};
*/ */
bitjs.io.ByteStream.prototype.peekNumber = function(n) { bitjs.io.ByteStream.prototype.peekNumber = function(n) {
// TODO: return error if n would go past the end of the stream? // TODO: return error if n would go past the end of the stream?
if (n <= 0 || typeof n != typeof 1) if (n <= 0 || typeof n !== typeof 1) {
return -1; return -1;
}
var result = 0; var result = 0;
// read from last byte to first byte and roll them in // read from last byte to first byte and roll them in
...@@ -105,7 +109,7 @@ bitjs.io = bitjs.io || {}; ...@@ -105,7 +109,7 @@ bitjs.io = bitjs.io || {};
* @return {Uint8Array} The subarray. * @return {Uint8Array} The subarray.
*/ */
bitjs.io.ByteStream.prototype.peekBytes = function(n, movePointers) { bitjs.io.ByteStream.prototype.peekBytes = function(n, movePointers) {
if (n <= 0 || typeof n != typeof 1) { if (n <= 0 || typeof n !== typeof 1) {
return null; return null;
} }
...@@ -135,7 +139,7 @@ bitjs.io = bitjs.io || {}; ...@@ -135,7 +139,7 @@ bitjs.io = bitjs.io || {};
* @return {string} The next n bytes as a string. * @return {string} The next n bytes as a string.
*/ */
bitjs.io.ByteStream.prototype.peekString = function(n) { bitjs.io.ByteStream.prototype.peekString = function(n) {
if (n <= 0 || typeof n != typeof 1) { if (n <= 0 || typeof n !== typeof 1) {
return ""; return "";
} }
......
This diff is collapsed.
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h2>{{_('Administration')}}</h2> <h2>{{_('Administration')}}</h2>
<div class="btn btn-default"><a id="logfile" href="{{url_for('admin.view_logfile')}}">{{_('View Logfile')}}</a></div>
<div class="btn btn-default" id="restart_database">{{_('Reconnect to Calibre DB')}}</div> <div class="btn btn-default" id="restart_database">{{_('Reconnect to Calibre DB')}}</div>
<div class="btn btn-default" id="admin_restart" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-Web')}}</div> <div class="btn btn-default" id="admin_restart" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-Web')}}</div>
<div class="btn btn-default" id="admin_stop" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-Web')}}</div> <div class="btn btn-default" id="admin_stop" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-Web')}}</div>
......
{% extends "layout.html" %}
{% block body %}
{% block header %}
<style>
html, body {
margin: 0;
height: 100%;
overflow-y: hidden
}
div.log {
font-family: Courier New;
font-size: 12px;
box-sizing: border-box;
height: 500px;
overflow-y: scroll;
border-style: solid;
}
div.log {
white-space: nowrap;
padding: 0.5em;
}
div.lhl {
background-color: #ffd;
}
div.thread {
background: #fdd;
}
div.persistent,
div.persistents,
div.hint {
display: inline;
cursor: pointer;
}
div.hint,
div.persistent {
font-family: Arial;
font-size: 12px;
padding: 2px;
margin: 1px;
}
div.hint {
color: gray;
font-style: italic;
}
div.button,
div.button2,
div.button_right {
display: inline;
font-weight: bold;
font-family: Arial;
font-size: 12px;
padding: 2px;
cursor: pointer;
color: #3ad;
_text-decoration: underline;
}
div.button2 {
border: solid 1px gray;
border-radius: 4px;
color: black;
text-decoration: none;
}
div.button_right {
margin-right: 1em;
float: right;
}
div.nounder {
text-decoration: none;
}
input.filebtn {
float: right;
position: relative;
}
</style>
{% endblock %}
<!--body onload="load()"-->
<div id="toobar" class="toobar">
<input class="search" id="search" type="text" onmousedown="selectfilter(0)"></input>
<div class="button2" onclick="highlight()" title="apply changes in the search box">apply</div>
<div class="button_right" onclick="flipfilter(event)" title="disable/enable selected filters">filters on</div>
<br/>
<div class="button" onclick="filter()" title="show only lines containing the phrase">filter</div>
<div class="hint" onclick="repaint()" id="hint"></div>
<div class="hint" onclick="repaint()" id="position"></div>
</div>
<div class="clear"></div>
<div class="logpaginator"><a href="{{'/logs/1'}}"><span class="glyphicon glyphicon-fast-backward"></span></a> <a href="{{ "/logs/"}}"><span class="glyphicon glyphicon-step-backward"></span></a> <a href="{{ '/logs/' }}"><span class="glyphicon glyphicon-step-forward"></span></a> <a href="{{'/logs/'}}"><span class="glyphicon glyphicon-fast-forward"></span></a></div>
<div class="logperpage">
<form id="logform1" action="" method="POST">
<label for="reversed">{{_('Reversed')}}:</label>
<input type="checkbox" name="reversed" id="reversed" onchange="this.form.submit();" {% if reversed %} checked="checked" {% endif %} />&nbsp;
<label for="perpage">{{_('Lines per page')}}:</label>
<select name="perpage" id ="perpage" onchange="this.form.submit();">
{% for key, value in perpage_p.items() %}
<option value="{{key}}"{% if value== perpage %} selected="selected" {% endif %}>{{value}}</option>
{% endfor %}
</select>
</form>
</div>
<div class="logwarn">{{warning}}</div>
<div class="clear"></div>
<div class="logdiv">
<table class="logtable" cellpadding="0" cellspacing="0">
<div id="renderer" class="log" onmouseup="mouseup(event)"><div>nothing loaded</div></div>
{% for line in log %}
<tr><td class="logline">{{line.line}}</td><td>{{line.date}}</td><td class="loglevel">{{line.level}}</td><td>{{line.message}}</td></tr>
{% endfor %}
</table>
</div>
<div class="logform">
<form id="logform2" action="" method="POST" style="width: auto">
<label for="from" style="display: inline-block; float: left; margin-right: 5px; height: 34px; line-height: 34px;">{{_('Jump to time:')}}</label>
<input style="display: inline-block; text-align: center; float: left; width: 155px;" class="form-control" type="text" name="from" id="from" size="15" value="{{from}}"/>
<input style="display: inline-block; float: left; margin-left: 5px;" class="btn btn-default" type="submit" value="{{_('Go')}}" />
</form>
</div>
{% endblock %}
{% block js %}
<script src="{{ url_for('static', filename='js/logviewer.js') }}"></script>
<script>
$(function(){
init('access.log');
});
</script>
{% endblock %}
...@@ -3,7 +3,6 @@ universal = 1 ...@@ -3,7 +3,6 @@ universal = 1
[metadata] [metadata]
name = calibreweb name = calibreweb
version= 0.6.3
url = https://github.com/janeczku/calibre-web url = https://github.com/janeczku/calibre-web
project_urls = project_urls =
Bug Tracker = https://github.com/janeczku/calibre-web/issues Bug Tracker = https://github.com/janeczku/calibre-web/issues
...@@ -38,8 +37,6 @@ console_scripts = ...@@ -38,8 +37,6 @@ console_scripts =
cps = calibreweb:main cps = calibreweb:main
[options] [options]
python_requires = >=2.6 python_requires = >=2.6
package_dir=
=src
include_package_data = True include_package_data = True
zip_safe = False zip_safe = False
install_requires = install_requires =
......
...@@ -20,6 +20,25 @@ ...@@ -20,6 +20,25 @@
# """Calibre-web distribution package setuptools installer.""" # """Calibre-web distribution package setuptools installer."""
from setuptools import setup from setuptools import setup
import os
import re
import codecs
here = os.path.abspath(os.path.dirname(__file__))
def read(*parts):
with codecs.open(os.path.join(here, *parts), 'r') as fp:
return fp.read()
def find_version(*file_paths):
version_file = read(*file_paths)
version_match = re.search(r"^STABLE_VERSION\s+=\s+{['\"]version['\"]:\s*['\"](.*)['\"]}",
version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
setup( setup(
package_dir = {'': 'src'}) package_dir = {'': 'src'},
version=find_version("src", "calibreweb", "cps", "constants.py")
)
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