|
|
|
@ -1,7 +1,9 @@
|
|
|
|
|
import os
|
|
|
|
|
import math
|
|
|
|
|
import time
|
|
|
|
|
import signal
|
|
|
|
|
import logging
|
|
|
|
|
import argparse
|
|
|
|
|
import cherrypy
|
|
|
|
|
from collections import defaultdict
|
|
|
|
|
from urllib.parse import urlparse
|
|
|
|
@ -617,57 +619,22 @@ class SearchView(object):
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
import argparse
|
|
|
|
|
import signal
|
|
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description="Photod photo server")
|
|
|
|
|
|
|
|
|
|
parser.add_argument('-p', '--port', help="tcp port to listen on",
|
|
|
|
|
default=int(os.environ.get("PHOTOLIB_PORT", 8080)), type=int)
|
|
|
|
|
parser.add_argument('-l', '--library', default=os.environ.get("STORAGE_URL"), help="library path")
|
|
|
|
|
parser.add_argument('-c', '--cache', default=os.environ.get("CACHE_URL"), help="cache url")
|
|
|
|
|
parser.add_argument('-t', '--thumb-service', default=os.environ.get("THUMB_SERVICE_URL"), help="thumbnail service url")
|
|
|
|
|
# https://docs.sqlalchemy.org/en/13/core/engines.html
|
|
|
|
|
parser.add_argument('-s', '--database', help="sqlalchemy database connection uri",
|
|
|
|
|
default=os.environ.get("DATABASE_URL")),
|
|
|
|
|
parser.add_argument('--debug', action="store_true", help="enable development options")
|
|
|
|
|
|
|
|
|
|
tunables = parser.add_argument_group(title="tunables")
|
|
|
|
|
tunables.add_argument('--max-upload', help="maximum file upload size accepted in bytes",
|
|
|
|
|
default=1024**3, type=int)
|
|
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO if args.debug else logging.WARNING,
|
|
|
|
|
format="%(asctime)-15s %(levelname)-8s %(filename)s:%(lineno)d %(message)s")
|
|
|
|
|
|
|
|
|
|
if not args.database:
|
|
|
|
|
parser.error("--database or DATABASE_URL is required")
|
|
|
|
|
|
|
|
|
|
if not args.library:
|
|
|
|
|
parser.error("--library or STORAGE_URL is required")
|
|
|
|
|
|
|
|
|
|
if not args.cache:
|
|
|
|
|
parser.error("--cache or CACHE_URL is required")
|
|
|
|
|
|
|
|
|
|
if not args.thumb_service:
|
|
|
|
|
logging.warning("THUMB_SERVICE_URL not set. Video thumbnails will be unavailable")
|
|
|
|
|
def setup_webapp(database_url, library_url, cache_url, thumb_service_url, debug=False, max_upload=1024**3):
|
|
|
|
|
|
|
|
|
|
# Get database connection
|
|
|
|
|
engine = get_db_engine(args.database)
|
|
|
|
|
engine = get_db_engine(database_url)
|
|
|
|
|
|
|
|
|
|
# Setup database in web framework
|
|
|
|
|
cherrypy.tools.db = SATool()
|
|
|
|
|
SAEnginePlugin(cherrypy.engine, engine).subscribe()
|
|
|
|
|
|
|
|
|
|
# Create various internal tools
|
|
|
|
|
library_storage = uri_to_storage(args.library)
|
|
|
|
|
library_storage = uri_to_storage(library_url)
|
|
|
|
|
library_manager = LibraryManager(library_storage)
|
|
|
|
|
thumbnail_tool = ThumbGenerator(library_manager, uri_to_storage(args.cache), args.thumb_service)
|
|
|
|
|
thumbnail_tool = ThumbGenerator(library_manager, uri_to_storage(cache_url), thumb_service_url)
|
|
|
|
|
|
|
|
|
|
# Setup and mount web ui
|
|
|
|
|
tpl_dir = os.path.join(APPROOT, "templates") if not args.debug else "templates"
|
|
|
|
|
tpl_dir = os.path.join(APPROOT, "templates") if not debug else "templates"
|
|
|
|
|
web = PhotosWeb(library_manager, thumbnail_tool, tpl_dir)
|
|
|
|
|
cherrypy.tree.mount(web, '/', {'/': {'tools.trailing_slash.on': False,
|
|
|
|
|
'tools.db.on': True,
|
|
|
|
@ -675,7 +642,7 @@ def main():
|
|
|
|
|
'error_page.404': web.error},
|
|
|
|
|
'/static': {"tools.staticdir.on": True,
|
|
|
|
|
"tools.staticdir.dir": os.path.join(APPROOT, "styles/dist")
|
|
|
|
|
if not args.debug else os.path.abspath("styles/dist")},
|
|
|
|
|
if not debug else os.path.abspath("styles/dist")},
|
|
|
|
|
'/thumb': {'tools.expires.on': True,
|
|
|
|
|
'tools.expires.secs': 7 * 86400},
|
|
|
|
|
'/login': {'tools.auth_basic.on': True,
|
|
|
|
@ -699,13 +666,61 @@ def main():
|
|
|
|
|
'tools.sessions.locking': 'explicit',
|
|
|
|
|
'tools.sessions.timeout': 525600,
|
|
|
|
|
'request.show_tracebacks': True,
|
|
|
|
|
'server.show_tracebacks': True,
|
|
|
|
|
'log.screen': False,
|
|
|
|
|
'server.max_request_body_size': max_upload
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
parser = argparse.ArgumentParser(description="Photod photo server")
|
|
|
|
|
|
|
|
|
|
parser.add_argument('-p', '--port', help="tcp port to listen on",
|
|
|
|
|
default=int(os.environ.get("PHOTOLIB_PORT", 8080)), type=int)
|
|
|
|
|
parser.add_argument('-l', '--library', default=os.environ.get("STORAGE_URL"), help="library path")
|
|
|
|
|
parser.add_argument('-c', '--cache', default=os.environ.get("CACHE_URL"), help="cache url")
|
|
|
|
|
parser.add_argument('-t', '--thumb-service', default=os.environ.get("THUMB_SERVICE_URL"), help="thumbnail service url")
|
|
|
|
|
# https://docs.sqlalchemy.org/en/13/core/engines.html
|
|
|
|
|
parser.add_argument('-s', '--database', help="sqlalchemy database connection uri",
|
|
|
|
|
default=os.environ.get("DATABASE_URL")),
|
|
|
|
|
parser.add_argument('--debug', action="store_true", help="enable development options")
|
|
|
|
|
|
|
|
|
|
tunables = parser.add_argument_group(title="tunables")
|
|
|
|
|
tunables.add_argument('--max-upload', help="maximum file upload size accepted in bytes",
|
|
|
|
|
default=1024**3, type=int)
|
|
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO if args.debug else logging.WARNING,
|
|
|
|
|
format="%(asctime)-15s %(levelname)-8s %(filename)s:%(lineno)d %(message)s")
|
|
|
|
|
|
|
|
|
|
if not args.database:
|
|
|
|
|
parser.error("--database or DATABASE_URL is required")
|
|
|
|
|
|
|
|
|
|
if not args.library:
|
|
|
|
|
parser.error("--library or STORAGE_URL is required")
|
|
|
|
|
|
|
|
|
|
if not args.cache:
|
|
|
|
|
parser.error("--cache or CACHE_URL is required")
|
|
|
|
|
|
|
|
|
|
if not args.thumb_service:
|
|
|
|
|
logging.warning("THUMB_SERVICE_URL not set. Video thumbnails will be unavailable")
|
|
|
|
|
|
|
|
|
|
setup_webapp(
|
|
|
|
|
args.database,
|
|
|
|
|
args.library,
|
|
|
|
|
args.cache,
|
|
|
|
|
args.thumb_service,
|
|
|
|
|
debug=args.debug,
|
|
|
|
|
max_upload=args.max_upload
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Server config options
|
|
|
|
|
cherrypy.config.update({
|
|
|
|
|
'server.socket_port': args.port,
|
|
|
|
|
'server.thread_pool': 25,
|
|
|
|
|
'server.socket_host': '0.0.0.0',
|
|
|
|
|
'server.show_tracebacks': True,
|
|
|
|
|
'log.screen': False,
|
|
|
|
|
'engine.autoreload.on': args.debug,
|
|
|
|
|
'server.max_request_body_size': args.max_upload
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
# Setup signal handling and run it.
|
|
|
|
|