1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 18:47:23 +00:00

Working for pip and "normal" start for python3 and python2

This commit is contained in:
Ozzieisaacs 2019-06-02 09:33:19 +02:00
parent f5b335e8e9
commit bb0d5c5538
27 changed files with 114 additions and 91 deletions

View File

@ -1 +1 @@
graft src/cps
graft src/calibreweb

View File

@ -73,4 +73,4 @@ Pre-built Docker images based on Alpine Linux are available in these Docker Hub
# Wiki
For further informations, How To's and FAQ please check the ![Wiki](https://github.com/janeczku/calibre-web/wiki)
For further informations, How To's and FAQ please check the [Wiki](https://github.com/janeczku/calibre-web/wiki)

View File

View File

@ -20,6 +20,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__all__ =['app']
import mimetypes
from flask import Flask, request, g
@ -71,7 +72,7 @@ lm.anonymous_user = ub.Anonymous
ub.init_db()
config = Config()
import db
from . import db
try:
with open(os.path.join(config.get_main_dir, 'cps/translations/iso639.pickle'), 'rb') as f:
@ -83,10 +84,10 @@ except cPickle.UnpicklingError as error:
searched_ids = {}
from worker import WorkerThread
from .worker import WorkerThread
global_WorkerThread = WorkerThread()
from server import server
from .server import server
Server = server()
babel = Babel()
@ -142,5 +143,5 @@ def get_timezone():
if user is not None:
return user.timezone
from updater import Updater
from .updater import Updater
updater_thread = Updater()

View File

@ -23,9 +23,9 @@
from flask import Blueprint
from flask_login import login_required
from cps import db
from . import db
import sys
import uploader
from .uploader import get_versions
from babel import __version__ as babelVersion
from sqlalchemy import __version__ as sqlalchemyVersion
from flask_principal import __version__ as flask_principalVersion
@ -34,11 +34,11 @@ from pytz import __version__ as pytzVersion
from flask import __version__ as flaskVersion
from werkzeug import __version__ as werkzeugVersion
from jinja2 import __version__ as jinja2Version
import converter
from .converter import versioncheck
from flask_babel import gettext as _
from cps import Server
import requests
from web import render_title_template
from .web import render_title_template
try:
from flask_login import __version__ as flask_loginVersion
@ -55,7 +55,7 @@ def stats():
authors = db.session.query(db.Authors).count()
categorys = db.session.query(db.Tags).count()
series = db.session.query(db.Series).count()
versions = uploader.get_versions()
versions = get_versions()
versions['Babel'] = 'v' + babelVersion
versions['Sqlalchemy'] = 'v' + sqlalchemyVersion
versions['Werkzeug'] = 'v' + werkzeugVersion
@ -69,7 +69,7 @@ def stats():
versions['Requests'] = 'v' + requests.__version__
versions['pySqlite'] = 'v' + db.engine.dialect.dbapi.version
versions['Sqlite'] = 'v' + db.engine.dialect.dbapi.sqlite_version
versions.update(converter.versioncheck())
versions.update(versioncheck())
versions.update(Server.getNameVersion())
versions['Python'] = sys.version
return render_title_template('stats.html', bookcounter=counter, authorcounter=authors, versions=versions,

View File

@ -25,9 +25,9 @@ import os
from flask import Blueprint, flash, redirect, url_for
from flask import abort, request, make_response
from flask_login import login_required, current_user, logout_user
from web import admin_required, render_title_template, before_request, unconfigured, \
from .web import admin_required, render_title_template, before_request, unconfigured, \
login_required_if_no_ano
from cps import db, ub, Server, get_locale, config, app, updater_thread, babel
from . import db, ub, Server, get_locale, config, app, updater_thread, babel
import json
from datetime import datetime, timedelta
import time
@ -35,9 +35,9 @@ from babel.dates import format_datetime
from flask_babel import gettext as _
from babel import Locale as LC
from sqlalchemy.exc import IntegrityError
from gdriveutils import is_gdrive_ready, gdrive_support, downloadFile, deleteDatabaseOnChange, listRootFolders
import helper
from helper import speaking_language, check_valid_domain
from .gdriveutils import is_gdrive_ready, gdrive_support, downloadFile, deleteDatabaseOnChange, listRootFolders
from .helper import speaking_language, check_valid_domain, check_unrar, send_test_mail, generate_random_password, \
send_registration_mail
from werkzeug.security import generate_password_hash
try:
from imp import reload
@ -467,7 +467,7 @@ def configuration_helper(origin):
# Rarfile Content configuration
if "config_rarfile_location" in to_save and to_save['config_rarfile_location'] is not u"":
check = helper.check_unrar(to_save["config_rarfile_location"].strip())
check = check_unrar(to_save["config_rarfile_location"].strip())
if not check[0] :
content.config_rarfile_location = to_save["config_rarfile_location"].strip()
else:
@ -486,7 +486,6 @@ def configuration_helper(origin):
flash(_(u"Calibre-Web configuration updated"), category="success")
config.loadSettings()
app.logger.setLevel(config.config_log_level)
# logging.getLogger("uploader").setLevel(config.config_log_level)
except Exception as e:
flash(e, category="error")
return render_title_template("config_edit.html", config=config, origin=origin,
@ -602,7 +601,7 @@ def edit_mailsettings():
flash(e, category="error")
if "test" in to_save and to_save["test"]:
if current_user.kindle_mail:
result = helper.send_test_mail(current_user.kindle_mail, current_user.nickname)
result = send_test_mail(current_user.kindle_mail, current_user.nickname)
if result is None:
flash(_(u"Test e-mail successfully send to %(kindlemail)s", kindlemail=current_user.kindle_mail),
category="success")
@ -725,11 +724,11 @@ def reset_password(user_id):
abort(404)
if current_user is not None and current_user.is_authenticated:
existing_user = ub.session.query(ub.User).filter(ub.User.id == user_id).first()
password = helper.generate_random_password()
password = generate_random_password()
existing_user.password = generate_password_hash(password)
try:
ub.session.commit()
helper.send_registration_mail(existing_user.email, existing_user.nickname, password, True)
send_registration_mail(existing_user.email, existing_user.nickname, password, True)
flash(_(u"Password for user %(user)s reset", user=existing_user.nickname), category="success")
except Exception:
ub.session.rollback()

View File

@ -26,8 +26,10 @@ parser = argparse.ArgumentParser(description='Calibre Web is a web app'
' providing a interface for browsing, reading and downloading eBooks\n', prog='cps.py')
parser.add_argument('-p', metavar='path', help='path and name to settings db, e.g. /opt/cw.db')
parser.add_argument('-g', metavar='path', help='path and name to gdrive db, e.g. /opt/gd.db')
parser.add_argument('-c', metavar='path', help='path and name to SSL certfile, e.g. /opt/test.cert, works only in combination with keyfile')
parser.add_argument('-k', metavar='path', help='path and name to SSL keyfile, e.g. /opt/test.key, works only in combination with certfile')
parser.add_argument('-c', metavar='path',
help='path and name to SSL certfile, e.g. /opt/test.cert, works only in combination with keyfile')
parser.add_argument('-k', metavar='path',
help='path and name to SSL keyfile, e.g. /opt/test.key, works only in combination with certfile')
parser.add_argument('-v', action='store_true', help='shows version number and exits Calibre-web')
args = parser.parse_args()

View File

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from cps import uploader
from constants import BookMeta
from cps import app
from iso639 import languages as isoLanguages
@ -94,7 +94,7 @@ def get_comic_info(tmp_file_path, original_file_name, original_file_extension):
else:
loadedMetadata.language = ""
return uploader.BookMeta(
return BookMeta(
file_path=tmp_file_path,
extension=original_file_extension,
title=loadedMetadata.title or original_file_name,
@ -107,7 +107,7 @@ def get_comic_info(tmp_file_path, original_file_name, original_file_extension):
languages=loadedMetadata.language)
else:
return uploader.BookMeta(
return BookMeta(
file_path=tmp_file_path,
extension=original_file_extension,
title=original_file_name,

26
cps/constants.py Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
# Copyright (C) 2019 OzzieIsaacs
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from collections import namedtuple
"""
:rtype: BookMeta
"""
BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, '
'series_id, languages')

View File

@ -24,7 +24,7 @@ import ub
import re
from flask_babel import gettext as _
from subproc_wrapper import process_open
from cps import config
from . import config
def versionKindle():

View File

@ -24,7 +24,7 @@ from sqlalchemy.orm import *
import os
import re
import ast
from cps import config
from . import config
import ub
import sys
import unidecode

View File

@ -22,7 +22,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# opds routing functions
from cps import config, language_table, get_locale, app, ub, global_WorkerThread, db
from . import config, language_table, get_locale, app, ub, global_WorkerThread, db
from flask import request, flash, redirect, url_for, abort, Markup, Response
from flask import Blueprint
import datetime
@ -30,14 +30,14 @@ import os
import json
from flask_babel import gettext as _
from uuid import uuid4
import helper
from helper import order_authors, common_filters
from . import helper
from .helper import order_authors, common_filters
from flask_login import current_user
from web import login_required_if_no_ano, render_title_template, edit_required, \
from .web import login_required_if_no_ano, render_title_template, edit_required, \
upload_required, login_required, EXTENSIONS_UPLOAD
import gdriveutils
from . import gdriveutils
from shutil import move, copyfile
import uploader
from . import uploader
from iso639 import languages as isoLanguages
editbook = Blueprint('editbook', __name__)

View File

@ -20,7 +20,7 @@
import zipfile
from lxml import etree
import os
import uploader
from .constants import BookMeta
import isoLanguages

View File

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from lxml import etree
import uploader
from .constants import BookMeta
def get_fb2_info(tmp_file_path, original_file_extension):
@ -66,7 +66,7 @@ def get_fb2_info(tmp_file_path, original_file_extension):
else:
description = u''
return uploader.BookMeta(
return BookMeta(
file_path=tmp_file_path,
extension=original_file_extension,
title=title.decode('utf-8'),

View File

@ -22,17 +22,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from flask import Blueprint
import gdriveutils
from . import gdriveutils
from flask import flash, request, redirect, url_for, abort
from flask_babel import gettext as _
from cps import app, config, ub, db
from . import app, config, ub, db
from flask_login import login_required
import json
from uuid import uuid4
from time import time
import tempfile
from shutil import move, copyfile
from web import admin_required
from .web import admin_required
try:
from googleapiclient.errors import HttpError

View File

@ -27,7 +27,7 @@ except ImportError:
gdrive_support = False
import os
from cps import config, app
from . import config, app
import cli
import shutil
from flask import Response, stream_with_context

View File

@ -19,7 +19,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from cps import config, global_WorkerThread, get_locale, db, mimetypes
from . import config, global_WorkerThread, get_locale, db, mimetypes
from flask import current_app as app
from tempfile import gettempdir
import sys
@ -27,7 +27,8 @@ import io
import os
import re
import unicodedata
import worker
from .worker import STAT_WAITING, STAT_FAIL, STAT_STARTED, STAT_FINISH_SUCCESS, TASK_EMAIL, TASK_CONVERT, TASK_UPLOAD, \
TASK_CONVERT_ANY
import time
from flask import send_from_directory, make_response, redirect, abort
from flask_babel import gettext as _
@ -610,26 +611,26 @@ def render_task_status(tasklist):
# localize the task status
if isinstance( task['stat'], int ):
if task['stat'] == worker.STAT_WAITING:
if task['stat'] == STAT_WAITING:
task['status'] = _(u'Waiting')
elif task['stat'] == worker.STAT_FAIL:
elif task['stat'] == STAT_FAIL:
task['status'] = _(u'Failed')
elif task['stat'] == worker.STAT_STARTED:
elif task['stat'] == STAT_STARTED:
task['status'] = _(u'Started')
elif task['stat'] == worker.STAT_FINISH_SUCCESS:
elif task['stat'] == STAT_FINISH_SUCCESS:
task['status'] = _(u'Finished')
else:
task['status'] = _(u'Unknown Status')
# localize the task type
if isinstance( task['taskType'], int ):
if task['taskType'] == worker.TASK_EMAIL:
if task['taskType'] == TASK_EMAIL:
task['taskMessage'] = _(u'E-mail: ') + task['taskMess']
elif task['taskType'] == worker.TASK_CONVERT:
elif task['taskType'] == TASK_CONVERT:
task['taskMessage'] = _(u'Convert: ') + task['taskMess']
elif task['taskType'] == worker.TASK_UPLOAD:
elif task['taskType'] == TASK_UPLOAD:
task['taskMessage'] = _(u'Upload: ') + task['taskMess']
elif task['taskType'] == worker.TASK_CONVERT_ANY:
elif task['taskType'] == TASK_CONVERT_ANY:
task['taskMessage'] = _(u'Convert: ') + task['taskMess']
else:
task['taskMessage'] = _(u'Unknown Task: ') + task['taskMess']

View File

@ -26,9 +26,10 @@
from flask import Blueprint, request, url_for
import datetime
import re
from cps import mimetypes
from . import mimetypes, app
from babel.dates import format_date
from flask_babel import get_locale
from flask_login import current_user
jinjia = Blueprint('jinjia', __name__)
@ -78,7 +79,8 @@ def formatdate_filter(val):
formatdate = datetime.datetime.strptime(conformed_timestamp[:15], "%Y%m%d %H%M%S")
return format_date(formatdate, format='medium', locale=get_locale())
except AttributeError as e:
app.logger.error('Babel error: %s, Current user locale: %s, Current User: %s' % (e, current_user.locale, current_user.nickname))
app.logger.error('Babel error: %s, Current user locale: %s, Current User: %s' %
(e, current_user.locale, current_user.nickname))
return formatdate
@jinjia.app_template_filter('formatdateinput')

View File

@ -22,7 +22,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# opds routing functions
from cps import config, db
from . import config, db
from flask import request, render_template, Response, g, make_response
from pagination import Pagination
from flask import Blueprint
@ -30,11 +30,10 @@ import datetime
import ub
from flask_login import current_user
from functools import wraps
from web import login_required_if_no_ano, common_filters, get_search_results, render_read_books, download_required
from .web import login_required_if_no_ano, common_filters, get_search_results, render_read_books, download_required
from sqlalchemy.sql.expression import func, text
import helper
from werkzeug.security import check_password_hash
from helper import fill_indexpage
from .helper import fill_indexpage, get_download_link, get_book_cover
import sys
opds = Blueprint('opds', __name__)
@ -253,7 +252,7 @@ def feed_shelf(book_id):
@requires_basic_auth_if_no_ano
@download_required
def opds_download_link(book_id, book_format):
return helper.get_download_link(book_id,book_format)
return get_download_link(book_id,book_format)
@opds.route("/ajax/book/<string:uuid>")
@ -308,7 +307,7 @@ def render_xml_template(*args, **kwargs):
@opds.route("/opds/cover/<book_id>")
@requires_basic_auth_if_no_ano
def feed_get_cover(book_id):
return helper.get_book_cover(book_id)
return get_book_cover(book_id)
@opds.route("/opds/readbooks/")
@requires_basic_auth_if_no_ano

View File

@ -22,7 +22,7 @@ from socket import error as SocketError
import sys
import os
import signal
from cps import config, global_WorkerThread
from . import config, global_WorkerThread
try:
from gevent.pywsgi import WSGIServer

View File

@ -22,11 +22,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from flask import Blueprint, request, flash, redirect, url_for
from cps import ub, searched_ids, app, db
from . import ub, searched_ids, app, db
from flask_babel import gettext as _
from sqlalchemy.sql.expression import func, or_
from flask_login import login_required, current_user
from web import render_title_template
from .web import render_title_template
shelf = Blueprint('shelf', __name__)

View File

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from cps import config, get_locale, Server, app
from . import config, get_locale, Server, app
import threading
import zipfile
import requests

View File

@ -17,14 +17,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# import os
from tempfile import gettempdir
import hashlib
from collections import namedtuple
import os
from flask_babel import gettext as _
from cps import comic
from cps import app
import comic
from . import app
try:
from lxml.etree import LXML_VERSION as lxmlversion
@ -72,14 +71,9 @@ except ImportError:
use_PIL = False
__author__ = 'lemmsh'
BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, series_id, languages')
"""
:rtype: BookMeta
"""
def process(tmp_file_path, original_file_name, original_file_extension):
meta = None

View File

@ -21,8 +21,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from cps import mimetypes, global_WorkerThread, searched_ids, lm, babel, ub, config, get_locale, language_table, app, db
from helper import common_filters, get_search_results, fill_indexpage, speaking_language, check_valid_domain, \
from . import mimetypes, global_WorkerThread, searched_ids, lm, babel, ub, config, get_locale, language_table, app, db
from .helper import common_filters, get_search_results, fill_indexpage, speaking_language, check_valid_domain, \
order_authors, get_typeahead, render_task_status, json_serial, get_unique_other_books, get_cc_columns, \
get_book_cover, get_download_link, send_mail, generate_random_password, send_registration_mail, \
check_send_to_kindle, check_read_formats, lcase
@ -44,7 +44,7 @@ import os.path
import json
import datetime
import isoLanguages
import gdriveutils
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
feature_support = dict()
@ -995,8 +995,8 @@ def serve_book(book_id, book_format):
headers["Content-Type"] = mimetypes.types_map['.' + book_format]
except KeyError:
headers["Content-Type"] = "application/octet-stream"
df = gdriveutils.getFileFromEbooksFolder(book.path, data.name + "." + book_format)
return gdriveutils.do_gdrive_download(df, headers)
df = getFileFromEbooksFolder(book.path, data.name + "." + book_format)
return do_gdrive_download(df, headers)
else:
return send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + book_format)

View File

@ -27,11 +27,11 @@ import socket
import sys
import os
from email.generator import Generator
from cps import config, db, app
from . import config, db, app
from flask_babel import gettext as _
import re
import gdriveutils as gd
from subproc_wrapper import process_open
from .gdriveutils import getFileFromEbooksFolder, updateGdriveCalibreFromLocal
from .subproc_wrapper import process_open
try:
from StringIO import StringIO
@ -70,7 +70,7 @@ def get_attachment(bookpath, filename):
"""Get file as MIMEBase message"""
calibrepath = config.config_calibre_dir
if config.config_use_google_drive:
df = gd.getFileFromEbooksFolder(bookpath, filename)
df = getFileFromEbooksFolder(bookpath, filename)
if df:
datafile = os.path.join(calibrepath, bookpath, filename)
if not os.path.exists(os.path.join(calibrepath, bookpath)):
@ -236,7 +236,7 @@ class WorkerThread(threading.Thread):
filename = self._convert_ebook_format()
if filename:
if config.config_use_google_drive:
gd.updateGdriveCalibreFromLocal()
updateGdriveCalibreFromLocal()
if curr_task == TASK_CONVERT:
self.add_email(self.queue[self.current]['settings']['subject'], self.queue[self.current]['path'],
filename, self.queue[self.current]['settings'], self.queue[self.current]['kindle'],

View File

@ -2,8 +2,8 @@
universal = 1
[metadata]
name = calibre-web
version= 0.6.4 Beta
name = calibro-web
version= 0.6.6 Beta
url = https://github.com/janeczku/calibre-web
project_urls =
Bug Tracker = https://github.com/janeczku/calibre-web/issues
@ -33,15 +33,13 @@ keywords =
calibre-web
library
[entry_points]
[options.entry_points]
console_scripts =
calibre-web=src.cps:main
cps = calibreweb:main
[options]
python_requires = >=2.6
package_dir=
=src
packages = cps
include_package_data = True
zip_safe = False
install_requires =

View File

@ -21,4 +21,5 @@
from setuptools import setup
setup()
setup(
package_dir = {'': 'src'})