Commit b74a075a authored by OzzieIsaacs's avatar OzzieIsaacs

Added posibility to change settings db via command line for multiple instances (#247)

parent 152f7857
import argparse
import os
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')
args = parser.parse_args()
generalPath = os.path.normpath(os.getenv("CALIBRE_DBPATH",
os.path.dirname(os.path.realpath(__file__)) + os.sep + ".." + os.sep))
if args.p:
settingspath = args.p
else:
settingspath = os.path.join(generalPath, "app.db")
if args.g:
gdpath = args.g
else:
gdpath = os.path.join(generalPath, "gdrive.db")
......@@ -7,6 +7,7 @@ except ImportError:
import os
from ub import config
import cli
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
......@@ -15,9 +16,7 @@ from sqlalchemy.orm import *
import web
dbpath = os.path.join(os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + os.sep + ".." + os.sep), "gdrive.db")
engine = create_engine('sqlite:///{0}'.format(dbpath), echo=False)
engine = create_engine('sqlite:///{0}'.format(cli.gdpath), echo=False)
Base = declarative_base()
# Open session for database connection
......@@ -64,7 +63,7 @@ def migrate():
session.execute('ALTER TABLE gdrive_ids2 RENAME to gdrive_ids')
break
if not os.path.exists(dbpath):
if not os.path.exists(cli.gdpath):
try:
Base.metadata.create_all(engine)
except Exception:
......
......@@ -88,6 +88,10 @@
<option value="40" {% if content.config_log_level == 40 %}selected{% endif %}>ERROR</option>
</select>
</div>
<div class="form-group">
<label for="config_logfile">{{_('Location and name of logfile (calibre-web.log for no entry)')}}</label>
<input type="text" class="form-control" name="config_logfile" id="config_logfile" value="{% if content.config_logfile != None %}{{ content.config_logfile }}{% endif %}" autocomplete="off">
</div>
<div class="col-sm-6">
<div class="form-group">
<input type="checkbox" id="config_uploading" name="config_uploading" {% if content.config_uploading %}checked{% endif %}>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -14,9 +14,9 @@ from flask_babel import gettext as _
import json
import datetime
from binascii import hexlify
import cli
dbpath = os.path.join(os.path.normpath(os.getenv("CALIBRE_DBPATH", os.path.dirname(os.path.realpath(__file__)) + os.sep + ".." + os.sep)), "app.db")
engine = create_engine('sqlite:///{0}'.format(dbpath), echo=False)
engine = create_engine('sqlite:///{0}'.format(cli.settingspath), echo=False)
Base = declarative_base()
ROLE_USER = 0
......@@ -294,6 +294,7 @@ class Settings(Base):
config_goodreads_api_key = Column(String)
config_goodreads_api_secret = Column(String)
config_mature_content_tags = Column(String) # type: str
config_logfile = Column(String)
def __repr__(self):
pass
......@@ -322,6 +323,7 @@ class Config:
self.config_main_dir = os.path.join(os.path.normpath(os.path.dirname(
os.path.realpath(__file__)) + os.sep + ".." + os.sep))
self.db_configured = None
self.config_logfile = None
self.loadSettings()
def loadSettings(self):
......@@ -356,11 +358,22 @@ class Config:
self.config_goodreads_api_key = data.config_goodreads_api_key
self.config_goodreads_api_secret = data.config_goodreads_api_secret
self.config_mature_content_tags = data.config_mature_content_tags
if data.config_logfile:
self.config_logfile = data.config_logfile
@property
def get_main_dir(self):
return self.config_main_dir
def get_config_logfile(self):
if not self.config_logfile:
return os.path.join(self.get_main_dir, "calibre-web.log")
else:
if os.path.dirname(self.config_logfile):
return self.config_logfile
else:
return os.path.join(self.get_main_dir, self.config_logfile)
def role_admin(self):
if self.config_default_role is not None:
return True if self.config_default_role & ROLE_ADMIN == ROLE_ADMIN else False
......@@ -584,6 +597,13 @@ def migrate_Database():
conn = engine.connect()
conn.execute("ALTER TABLE Settings ADD column `config_default_show` SmallInteger DEFAULT 2047")
session.commit()
try:
session.query(exists().where(Settings.config_logfile)).scalar()
session.commit()
except exc.OperationalError: # Database is not compatible, some rows are missing
conn = engine.connect()
conn.execute("ALTER TABLE Settings ADD column `config_logfile` String DEFAULT ''")
session.commit()
def clean_database():
......@@ -662,7 +682,7 @@ Session.configure(bind=engine)
session = Session()
# generate database and admin and guest user, if no database is existing
if not os.path.exists(dbpath):
if not os.path.exists(cli.settingspath):
try:
Base.metadata.create_all(engine)
create_default_config()
......
......@@ -222,7 +222,7 @@ gevent_server = None
formatter = logging.Formatter(
"[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s")
file_handler = RotatingFileHandler(os.path.join(config.get_main_dir, "calibre-web.log"), maxBytes=50000, backupCount=2)
file_handler = RotatingFileHandler(config.get_config_logfile(), maxBytes=50000, backupCount=2)
file_handler.setFormatter(formatter)
app.logger.addHandler(file_handler)
app.logger.setLevel(config.config_log_level)
......@@ -2573,7 +2573,20 @@ def configuration_helper(origin):
content.config_default_show = content.config_default_show + ub.SIDEBAR_RECENT
if "show_sorted" in to_save:
content.config_default_show = content.config_default_show + ub.SIDEBAR_SORTED
if content.config_logfile != to_save["config_logfile"]:
# check valid path, only path or file
if os.path.dirname(to_save["config_logfile"]):
if os.path.exists(os.path.dirname(to_save["config_log_level"])):
content.config_logfile = to_save["config_logfile"]
else:
ub.session.commit()
flash(_(u'Logfile location is not valid, please enter correct path'), category="error")
return render_title_template("config_edit.html", content=config, origin=origin,
gdrive=gdrive_support,
goodreads=goodreads_support, title=_(u"Basic Configuration"))
else:
content.config_logfile = to_save["config_logfile"]
reboot_required = True
try:
if content.config_use_google_drive and is_gdrive_ready() and not os.path.exists(config.config_calibre_dir + "/metadata.db"):
gdriveutils.downloadFile(Gdrive.Instance().drive, None, "metadata.db", config.config_calibre_dir + "/metadata.db")
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ Calibre Web is a web app providing a clean interface for browsing, reading and d
The configuration can be changed as admin in the admin panel under "Configuration"
Server Port:
Changes the port calibre-web is listening, changes take effect after pressing submit button
Changes the port Calibre-Web is listening, changes take effect after pressing submit button
Enable public registration:
Tick to enable public user registration.
......@@ -70,7 +70,7 @@ Optionally, to enable on-the-fly conversion from EPUB to MOBI when using the sen
## Using Google Drive integration
Additional optional dependencys are necessary to get this work. Please install all optional requirements by executing `pip install --target vendor -r optional-requirements.txt`
Calibre Calibre library (metadata.db) can be located on a Google Drive. Additional optional dependencys are necessary to get this work. Please install all optional requirements by executing `pip install --target vendor -r optional-requirements.txt`
To use google drive integration, you have to use the google developer console to create a new app. https://console.developers.google.com
......@@ -84,7 +84,7 @@ Once a project has been created, we need to create a client ID and a client secr
6. Give the Credentials a name and enter your callback, which will be CALIBRE_WEB_URL/gdrive/callback
7. Finally click save
The Drive API should now be setup and ready to use, so we need to integrate it into Calibre Web. This is done as below: -
The Drive API should now be setup and ready to use, so we need to integrate it into Calibre-Web. This is done as below: -
1. Open config page
2. Enter the location that will be used to store the metadata.db file, and to temporary store uploaded books and other temporary files for upload
......@@ -92,7 +92,7 @@ The Drive API should now be setup and ready to use, so we need to integrate it i
3. Enter Client Secret and Client Key as provided via previous steps
4. Enter the folder that is the root of your calibre library
5. Enter base URL for calibre (used for google callbacks)
6 Now select Authenticate Google Drive
6. Now select Authenticate Google Drive
7. This should redirect you to google to allow it top use your Drive, and then redirect you back to the config page
8. Google Drive should now be connected and be used to get images and download Epubs. The metadata.db is stored in the calibre library location
......@@ -108,7 +108,7 @@ Calibre Web can be run as Docker container. Pre-built Docker images based on Alp
## Reverse Proxy
Reverse proxy configuration examples for apache and nginx to use calibre-web:
Reverse proxy configuration examples for apache and nginx to use Calibre-Web:
nginx configuration for a local server listening on port 8080, mapping calibre web to /calibre:
......@@ -152,12 +152,12 @@ Listen 443
</VirtualHost>
```
## Start calibre-web as service under Linux
## Start Calibre-Web as service under Linux
Create a file "cps.service" as root in the folder /etc/systemd/system with the following content:
```[Unit]
Description=Calibre-web
Description=Calibre-Web
[Service]
Type=simple
......@@ -173,3 +173,12 @@ Replace the user and ExecStart with your user and foldernames.
`sudo systemctl enable cps.service`
enables the service.
## Command line options
Starting the script with `-h` lists all supported command line options
Currently supported are 2 options, which are both useful for running multiple instances of Calibre-Web
`"-p path"` allows to specify the location of the settings database
`"-p path"` allows to specify the location of the google-drive database
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