From e92870d42beaa1a01ab48a60cb322efa95e399bc Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:12:58 -0700 Subject: Some hacks. But generates some static rss feeds --- lib/util.py | 7 +++---- roka.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- templates/index.html | 2 +- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lib/util.py b/lib/util.py index a2f982d..4a884af 100644 --- a/lib/util.py +++ b/lib/util.py @@ -78,9 +78,7 @@ def escape(s): return s -def generate_rss(request, books): - book = request.args.get('a') # audiobook hash - +def generate_rss(base_url, book, books, static=False): # we only make use of the itunes ns, others provided for posterity namespaces = { 'itunes':'http://www.itunes.com/dtds/podcast-1.0.dtd', @@ -156,8 +154,9 @@ def generate_rss(request, books): pub_format = '%a, %d %b %Y %H:%M:%S %z' pub_date.text = (date(2000, 12, 31) - timedelta(days=idx)).strftime( pub_format) + url_format = '{}{}/{}.mp3' if static else '{}?a={}&f={}' enc_attr = { - 'url': '{}?a={}&f={}'.format(request.base_url, book, f), + 'url': url_format.format(base_url, book, f), 'length': str(books[book]['files'][f]['size_bytes']), 'type': 'audio/mpeg' } diff --git a/roka.py b/roka.py index 4c4da57..5f0da49 100755 --- a/roka.py +++ b/roka.py @@ -2,7 +2,7 @@ import argparse import os -from flask import Flask, request, Response, render_template, send_file +from flask import Flask, request, Response, render_template, send_file, templating from lib.books import Books from lib.util import check_auth, escape, generate_rss, read_cache @@ -11,6 +11,9 @@ app = Flask(__name__) app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) cache_path = os.path.join(abs_path, 'cache') json_path = os.path.join(cache_path, 'audiobooks.json') +static_path = os.path.join(abs_path, 'static') +static_index_path = os.path.join(static_path, 'index.html') +base_url = "blah.com/" @app.route('/') def list_books(): @@ -40,7 +43,7 @@ def list_books(): if not books.get(a): return 'book not found', 404 - rss = generate_rss(request, books) + rss = generate_rss(request.base_url, a, books) return Response(rss, mimetype='text/xml') else: @@ -51,17 +54,59 @@ def list_books(): return render_template('index.html', books=books) +def my_render_template( + app, template_name_or_list, **context +) -> str: + """Renders a template from the template folder with the given + context. + + :param template_name_or_list: the name of the template to be + rendered, or an iterable with template names + the first one existing will be rendered + :param context: the variables that should be available in the + context of the template. + """ + app.update_template_context(context) + return templating._render( + app.jinja_env.get_or_select_template(template_name_or_list), + context, + app, + ) + +def generate(): + books = Books() + books.scan_books() + books.write_cache() + books = read_cache(json_path) + index = my_render_template(app, 'index.html', books=books, static=True) + + indexfile = open(static_index_path, 'w') + indexfile.write(index) + indexfile.close() + + for key in books.keys(): + rss = generate_rss(base_url, key, books, static=True) + rss_path = os.path.join(static_path, key + '.xml') + rssfile = open(rss_path, 'w') + rssfile.write(rss.decode('utf-8')) + rssfile.close() + if __name__ == '__main__': desc = 'roka: listen to audiobooks with podcast apps via RSS' parser = argparse.ArgumentParser(description=desc) parser.add_argument('--scan', dest='scan', action='store_true', help='scan audiobooks directory for new books', required=False) + parser.add_argument('--generate', dest='generate', action='store_true', + help='', + required=False) args = parser.parse_args() if args.scan: books = Books() books.scan_books() books.write_cache() + elif args.generate: + generate() else: app.run(host='127.0.0.1', port='8085', threaded=True) diff --git a/templates/index.html b/templates/index.html index c05ff8e..4e6998d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -35,7 +35,7 @@ {% for b, v in books.items() %} - {{ v['title']|escape }} + {{ v['title']|escape }} {{ v['path']|escape }} {{ v['files']|length }} {{ v['duration_str'] }} -- cgit v1.2.3-54-g00ecf From cc431d59650897dc363b5bc0e34c89dfe004fea0 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:27:17 -0700 Subject: Copy files to expected path --- roka.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/roka.py b/roka.py index 5f0da49..05091ee 100755 --- a/roka.py +++ b/roka.py @@ -2,6 +2,7 @@ import argparse import os +import shutil from flask import Flask, request, Response, render_template, send_file, templating from lib.books import Books from lib.util import check_auth, escape, generate_rss, read_cache @@ -80,17 +81,28 @@ def generate(): books = read_cache(json_path) index = my_render_template(app, 'index.html', books=books, static=True) + os.makedirs(static_path, exist_ok=True) + indexfile = open(static_index_path, 'w') indexfile.write(index) indexfile.close() - for key in books.keys(): - rss = generate_rss(base_url, key, books, static=True) - rss_path = os.path.join(static_path, key + '.xml') + for b_key, book in books.items(): + rss = generate_rss(base_url, b_key, books, static=True) + rss_path = os.path.join(static_path, b_key + '.xml') rssfile = open(rss_path, 'w') rssfile.write(rss.decode('utf-8')) rssfile.close() + book_dir = os.path.join(static_path, b_key) + os.makedirs(book_dir, exist_ok=True) + + for f_key, file in book['files'].items(): + f_path = file['path'] + copy_path = os.path.join(book_dir, f_key + '.mp3') + # print("File: {} {} {}".format(f_key, f_path, copy_path)) + shutil.copyfile(f_path, copy_path) + if __name__ == '__main__': desc = 'roka: listen to audiobooks with podcast apps via RSS' parser = argparse.ArgumentParser(description=desc) -- cgit v1.2.3-54-g00ecf From b8838edda4e9c9a9fd68ab61ecef868218b44f36 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:42:03 -0700 Subject: Takes base URL and static location from args --- roka.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/roka.py b/roka.py index 05091ee..aafc3a3 100755 --- a/roka.py +++ b/roka.py @@ -12,9 +12,6 @@ app = Flask(__name__) app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) cache_path = os.path.join(abs_path, 'cache') json_path = os.path.join(cache_path, 'audiobooks.json') -static_path = os.path.join(abs_path, 'static') -static_index_path = os.path.join(static_path, 'index.html') -base_url = "blah.com/" @app.route('/') def list_books(): @@ -55,6 +52,7 @@ def list_books(): return render_template('index.html', books=books) +# TODO does this really need to be here? def my_render_template( app, template_name_or_list, **context ) -> str: @@ -74,9 +72,12 @@ def my_render_template( app, ) -def generate(): +def generate(static_path, base_url): + static_index_path = os.path.join(static_path, 'index.html') + books = Books() books.scan_books() + # TODO avoid writing and reading cache books.write_cache() books = read_cache(json_path) index = my_render_template(app, 'index.html', books=books, static=True) @@ -100,7 +101,6 @@ def generate(): for f_key, file in book['files'].items(): f_path = file['path'] copy_path = os.path.join(book_dir, f_key + '.mp3') - # print("File: {} {} {}".format(f_key, f_path, copy_path)) shutil.copyfile(f_path, copy_path) if __name__ == '__main__': @@ -109,16 +109,22 @@ if __name__ == '__main__': parser.add_argument('--scan', dest='scan', action='store_true', help='scan audiobooks directory for new books', required=False) - parser.add_argument('--generate', dest='generate', action='store_true', - help='', + parser.add_argument('--generate', dest='static_path', type=str, action='store', + help='Output directory to generate static files', + required=False) + parser.add_argument('--base_url', dest='base_url', type=str, action='store', + help='Base URL to use in static files', required=False) args = parser.parse_args() + if args.static_path and not args.base_url or args.base_url and not args.static_path: + parser.error("--generate and --base_url must both be included") + if args.scan: books = Books() books.scan_books() books.write_cache() - elif args.generate: - generate() + elif args.static_path: + generate(args.static_path, args.base_url) else: app.run(host='127.0.0.1', port='8085', threaded=True) -- cgit v1.2.3-54-g00ecf From f27620092d16676b77e92ae409c15e71d246f025 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:51:04 -0700 Subject: Allow setting scan dir from terminal --- lib/books.py | 6 +++--- roka.py | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/books.py b/lib/books.py index 1c4b4a5..84754f6 100644 --- a/lib/books.py +++ b/lib/books.py @@ -86,7 +86,7 @@ class Books: now = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S") print('%s %s' % (now, msg)) - def scan_books(self): + def scan_books(self, audiobook_path=None): ''' Discover audiobooks under :root_path: and populate books object @@ -94,7 +94,7 @@ class Books: (existing content is not re-hashed) ''' ex = self._get_path_hash_dict() - dirs = self._get_dirs(APP.config['ROOT_PATH']) + dirs = self._get_dirs(audiobook_path or APP.config['ROOT_PATH']) books = dict() for path in dirs: @@ -145,7 +145,7 @@ class Books: # previous conditions met, we've found at least one track is_book = True - self._log(f) + self._log(os.path.join(path, f)) # hash track (used as a key) and update folder hash file_hash = hashlib.md5() diff --git a/roka.py b/roka.py index aafc3a3..809cf3c 100755 --- a/roka.py +++ b/roka.py @@ -72,11 +72,11 @@ def my_render_template( app, ) -def generate(static_path, base_url): +def generate(static_path, base_url, audiobook_dirs): static_index_path = os.path.join(static_path, 'index.html') books = Books() - books.scan_books() + books.scan_books(audiobook_dirs) # TODO avoid writing and reading cache books.write_cache() books = read_cache(json_path) @@ -115,6 +115,9 @@ if __name__ == '__main__': parser.add_argument('--base_url', dest='base_url', type=str, action='store', help='Base URL to use in static files', required=False) + parser.add_argument('--scan_dir', dest='scan_dir', type=str, action='store', + help='Directory to scan for audiobooks', + required=False) args = parser.parse_args() if args.static_path and not args.base_url or args.base_url and not args.static_path: @@ -122,9 +125,9 @@ if __name__ == '__main__': if args.scan: books = Books() - books.scan_books() + books.scan_books(args.scan_dir) books.write_cache() elif args.static_path: - generate(args.static_path, args.base_url) + generate(args.static_path, args.base_url, args.scan_dir) else: app.run(host='127.0.0.1', port='8085', threaded=True) -- cgit v1.2.3-54-g00ecf From 2cfdf43064d526aed1ec76a5c0de639d53fbf72f Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:51:48 -0700 Subject: Fix string --- roka.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roka.py b/roka.py index 809cf3c..4b6a523 100755 --- a/roka.py +++ b/roka.py @@ -121,7 +121,7 @@ if __name__ == '__main__': args = parser.parse_args() if args.static_path and not args.base_url or args.base_url and not args.static_path: - parser.error("--generate and --base_url must both be included") + parser.error('--generate and --base_url must be included together') if args.scan: books = Books() -- cgit v1.2.3-54-g00ecf From 0300ecf7be0063a60a5b603c6c5134e0afa00593 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:53:11 -0700 Subject: Ignore static dir --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f6e84b2..46b2adb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ __pycache__ cache sandbox +static app.cfg uwsgi.ini -- cgit v1.2.3-54-g00ecf From 3d850b4d695acb4de3616eca947cfb0b7390154e Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 6 Jun 2021 15:58:51 -0700 Subject: Allow base_url with no app.cfg --- lib/books.py | 3 ++- roka.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/books.py b/lib/books.py index 84754f6..6f3510b 100644 --- a/lib/books.py +++ b/lib/books.py @@ -15,7 +15,8 @@ JSON_PATH = os.path.join(CACHE_PATH, 'audiobooks.json') # use Flask's config parser, configparser would be hacky APP = Flask(__name__) -APP.config.from_pyfile(os.path.join(ABS_PATH, '../', 'app.cfg')) +if os.path.exists(os.path.join(ABS_PATH, '../', 'app.cfg')): + APP.config.from_pyfile(os.path.join(ABS_PATH, '../', 'app.cfg')) class Books: def __init__(self): diff --git a/roka.py b/roka.py index 4b6a523..8d81641 100755 --- a/roka.py +++ b/roka.py @@ -9,7 +9,8 @@ from lib.util import check_auth, escape, generate_rss, read_cache abs_path = os.path.dirname(os.path.abspath(__file__)) app = Flask(__name__) -app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) +if os.path.exists(os.path.join(abs_path, 'app.cfg')): + app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) cache_path = os.path.join(abs_path, 'cache') json_path = os.path.join(cache_path, 'audiobooks.json') -- cgit v1.2.3-54-g00ecf From a262d5da79d4140fa866f885481ffcad2c33bb93 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Mon, 7 Jun 2021 07:58:48 -0700 Subject: Fix sort --- lib/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.py b/lib/util.py index 4a884af..4693ef1 100644 --- a/lib/util.py +++ b/lib/util.py @@ -119,7 +119,7 @@ def generate_rss(base_url, book, books, static=False): track_list.append(track) else: # we have populated and unique track values, use those - key = lambda x: books[book]['files'][x]['track'] + key = lambda x: int(books[book]['files'][x]['track']) # populate XML attribute values required by Apple podcasts for idx, f in enumerate(sorted(books[book]['files'], key=key)): -- cgit v1.2.3-54-g00ecf From 1356749036af0fc07253aac4f534d84c99e8c741 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Wed, 9 Jun 2021 22:08:05 -0700 Subject: Cleanup config and allow passing as json on terminal --- lib/books.py | 7 +------ roka.py | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/books.py b/lib/books.py index 6f3510b..95df374 100644 --- a/lib/books.py +++ b/lib/books.py @@ -13,11 +13,6 @@ ABS_PATH = os.path.dirname(os.path.abspath(__file__)) CACHE_PATH = os.path.join(ABS_PATH, '../', 'cache') JSON_PATH = os.path.join(CACHE_PATH, 'audiobooks.json') -# use Flask's config parser, configparser would be hacky -APP = Flask(__name__) -if os.path.exists(os.path.join(ABS_PATH, '../', 'app.cfg')): - APP.config.from_pyfile(os.path.join(ABS_PATH, '../', 'app.cfg')) - class Books: def __init__(self): ''' @@ -95,7 +90,7 @@ class Books: (existing content is not re-hashed) ''' ex = self._get_path_hash_dict() - dirs = self._get_dirs(audiobook_path or APP.config['ROOT_PATH']) + dirs = self._get_dirs(audiobook_path) books = dict() for path in dirs: diff --git a/roka.py b/roka.py index 8d81641..cfcd7e5 100755 --- a/roka.py +++ b/roka.py @@ -3,14 +3,13 @@ import argparse import os import shutil +import json from flask import Flask, request, Response, render_template, send_file, templating from lib.books import Books from lib.util import check_auth, escape, generate_rss, read_cache abs_path = os.path.dirname(os.path.abspath(__file__)) app = Flask(__name__) -if os.path.exists(os.path.join(abs_path, 'app.cfg')): - app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) cache_path = os.path.join(abs_path, 'cache') json_path = os.path.join(cache_path, 'audiobooks.json') @@ -78,7 +77,6 @@ def generate(static_path, base_url, audiobook_dirs): books = Books() books.scan_books(audiobook_dirs) - # TODO avoid writing and reading cache books.write_cache() books = read_cache(json_path) index = my_render_template(app, 'index.html', books=books, static=True) @@ -102,7 +100,8 @@ def generate(static_path, base_url, audiobook_dirs): for f_key, file in book['files'].items(): f_path = file['path'] copy_path = os.path.join(book_dir, f_key + '.mp3') - shutil.copyfile(f_path, copy_path) + if not os.path.exists(copy_path): + shutil.copyfile(f_path, copy_path) if __name__ == '__main__': desc = 'roka: listen to audiobooks with podcast apps via RSS' @@ -116,19 +115,30 @@ if __name__ == '__main__': parser.add_argument('--base_url', dest='base_url', type=str, action='store', help='Base URL to use in static files', required=False) - parser.add_argument('--scan_dir', dest='scan_dir', type=str, action='store', - help='Directory to scan for audiobooks', + parser.add_argument('--config', dest='config', type=str, action='store', + help='Json configuration instead of app.cfg', required=False) args = parser.parse_args() if args.static_path and not args.base_url or args.base_url and not args.static_path: parser.error('--generate and --base_url must be included together') + if args.config: + class objectview(object): + def __init__(self, d): + self.__dict__ = d + config = objectview(json.loads(args.config)) + app.config.from_object(config) + elif os.path.exists(os.path.join(abs_path, 'app.cfg')): + app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) + + root_path = os.path.expanduser(app.config['ROOT_PATH']) + if args.scan: books = Books() - books.scan_books(args.scan_dir) + books.scan_books(root_path) books.write_cache() elif args.static_path: - generate(args.static_path, args.base_url, args.scan_dir) + generate(args.static_path, args.base_url, root_path) else: app.run(host='127.0.0.1', port='8085', threaded=True) -- cgit v1.2.3-54-g00ecf From 1ada218538511fa1e1fd982133a928aa589647bb Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Wed, 9 Jun 2021 22:25:08 -0700 Subject: Move to real render_template --- roka.py | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/roka.py b/roka.py index cfcd7e5..4bb86fb 100755 --- a/roka.py +++ b/roka.py @@ -5,6 +5,7 @@ import os import shutil import json from flask import Flask, request, Response, render_template, send_file, templating +from flask.globals import _app_ctx_stack from lib.books import Books from lib.util import check_auth, escape, generate_rss, read_cache @@ -52,26 +53,6 @@ def list_books(): return render_template('index.html', books=books) -# TODO does this really need to be here? -def my_render_template( - app, template_name_or_list, **context -) -> str: - """Renders a template from the template folder with the given - context. - - :param template_name_or_list: the name of the template to be - rendered, or an iterable with template names - the first one existing will be rendered - :param context: the variables that should be available in the - context of the template. - """ - app.update_template_context(context) - return templating._render( - app.jinja_env.get_or_select_template(template_name_or_list), - context, - app, - ) - def generate(static_path, base_url, audiobook_dirs): static_index_path = os.path.join(static_path, 'index.html') @@ -79,7 +60,11 @@ def generate(static_path, base_url, audiobook_dirs): books.scan_books(audiobook_dirs) books.write_cache() books = read_cache(json_path) - index = my_render_template(app, 'index.html', books=books, static=True) + # A bit of a hack, but push to the app context stack so we can render a + # template outside of a Flask request + _app_ctx_stack.push(app.app_context()) + index = render_template('index.html', books=books, static=True) + _app_ctx_stack.pop() os.makedirs(static_path, exist_ok=True) -- cgit v1.2.3-54-g00ecf From 3a2c067bd6790f9c10d7cf3f82cee7aa46777681 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Wed, 9 Jun 2021 22:27:21 -0700 Subject: Always load one or the other config --- roka.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roka.py b/roka.py index 4bb86fb..9ac88d1 100755 --- a/roka.py +++ b/roka.py @@ -114,7 +114,7 @@ if __name__ == '__main__': self.__dict__ = d config = objectview(json.loads(args.config)) app.config.from_object(config) - elif os.path.exists(os.path.join(abs_path, 'app.cfg')): + else: app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) root_path = os.path.expanduser(app.config['ROOT_PATH']) -- cgit v1.2.3-54-g00ecf From 23eb4d3a39c7f02506a9b735257bb5eaa6c3bb0e Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 13 Jun 2021 14:09:55 -0700 Subject: Update README for static generation --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 75572fe..4d76afe 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,23 @@ A screenshot of the web interface is [available here](screenshots/web.png). ./uwsgi.sh ``` +## Static generation + +In addition to running as a server, Roka can also generate a static index and +set of RSS feeds that can be deployed to static hosting. This mode does not +support a username and password. + +1. Run roka.py with `--generate --base_url ` parameters + where `` is a directory to place the generated site and + `` is the base url where the static site will be uploaded to. + + ```bash + ./roka.py --generate ./static --base_url "https://example.com/" + ``` + +2. Upload the static site to any static web hosting. Make sure it is accessible + at the URL previously passed in as `--base_url` + ## Design decisions 1. Directories contained within config:ROOT_PATH are marked as audiobooks if and -- cgit v1.2.3-54-g00ecf From 9ee86c545e14ade1fd14b7068bdda6cf5a7c47a9 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 13 Jun 2021 14:20:15 -0700 Subject: Move base_url to config. Add README info about config override --- README.md | 19 +++++++++++++------ app.cfg.example | 2 ++ roka.py | 8 +------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4d76afe..7a7af22 100644 --- a/README.md +++ b/README.md @@ -33,16 +33,18 @@ In addition to running as a server, Roka can also generate a static index and set of RSS feeds that can be deployed to static hosting. This mode does not support a username and password. -1. Run roka.py with `--generate --base_url ` parameters - where `` is a directory to place the generated site and - `` is the base url where the static site will be uploaded to. +1. Set `BASE_URL` in app.cfg to the base url where the static site will be + uploaded. + +2. Run roka.py with the `--generate ` parameter, where + `` is an output directory to place the generated site. ```bash - ./roka.py --generate ./static --base_url "https://example.com/" + ./roka.py --generate ./static ``` -2. Upload the static site to any static web hosting. Make sure it is accessible - at the URL previously passed in as `--base_url` +3. Upload the static site to any static web hosting. Make sure it is accessible + at the URL set as `BASE_URL` ## Design decisions @@ -68,3 +70,8 @@ support a username and password. 4. No rebuild endpoint exists; cache-affecting routines are run externally by calling roka.py directly + +5. Configuration can either be placed in a file named `app.cfg`, or it can be + overridden on the terminal by passing a JSON string as the `--config` + parameter. I.E. `./roka.py --generate ./static --config '{"ROOT_PATH": + "/path/to/audiobooks", "BASE_URL": "https://example.com/"}'` diff --git a/app.cfg.example b/app.cfg.example index 94d2ef2..1fe4968 100644 --- a/app.cfg.example +++ b/app.cfg.example @@ -1,3 +1,5 @@ ROOT_PATH = '/path/to/audiobooks' +# BASE_URL is only used for static generation +BASE_URL = 'https://example.com/' USERNAME = 'username' PASSWORD = 'password' diff --git a/roka.py b/roka.py index 9ac88d1..b7fc849 100755 --- a/roka.py +++ b/roka.py @@ -97,17 +97,11 @@ if __name__ == '__main__': parser.add_argument('--generate', dest='static_path', type=str, action='store', help='Output directory to generate static files', required=False) - parser.add_argument('--base_url', dest='base_url', type=str, action='store', - help='Base URL to use in static files', - required=False) parser.add_argument('--config', dest='config', type=str, action='store', help='Json configuration instead of app.cfg', required=False) args = parser.parse_args() - if args.static_path and not args.base_url or args.base_url and not args.static_path: - parser.error('--generate and --base_url must be included together') - if args.config: class objectview(object): def __init__(self, d): @@ -124,6 +118,6 @@ if __name__ == '__main__': books.scan_books(root_path) books.write_cache() elif args.static_path: - generate(args.static_path, args.base_url, root_path) + generate(args.static_path, app.config['BASE_URL'], root_path) else: app.run(host='127.0.0.1', port='8085', threaded=True) -- cgit v1.2.3-54-g00ecf From 5e11f94aabd7acb4346739d6235050feced28a11 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Sun, 13 Jun 2021 14:26:01 -0700 Subject: Add detail about copying audiobook files --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a7af22..93455fe 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,8 @@ support a username and password. uploaded. 2. Run roka.py with the `--generate ` parameter, where - `` is an output directory to place the generated site. + `` is an output directory to place the generated site. All + audiobook files will be copied to this location. ```bash ./roka.py --generate ./static -- cgit v1.2.3-54-g00ecf From e7f4b527e2ee2cbae9f7a53f2a8100fa40bc9138 Mon Sep 17 00:00:00 2001 From: Dylan Garrett Date: Tue, 15 Jun 2021 21:46:00 -0700 Subject: Load config outside of main to keep uwsgi working --- roka.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/roka.py b/roka.py index 5729454..252ade9 100755 --- a/roka.py +++ b/roka.py @@ -11,6 +11,10 @@ from lib.util import check_auth, escape, generate_rss, read_cache abs_path = os.path.dirname(os.path.abspath(__file__)) app = Flask(__name__) +config_path = os.path.join(abs_path, 'app.cfg') +config_exists = os.path.exists(config_path) +if config_exists or __name__.startswith('uwsgi'): + app.config.from_pyfile(config_path) cache_path = os.path.join(abs_path, 'cache') json_path = os.path.join(cache_path, 'audiobooks.json') @@ -108,9 +112,10 @@ if __name__ == '__main__': def __init__(self, d): self.__dict__ = d config = objectview(json.loads(args.config)) + # override app.cfg app.config.from_object(config) - else: - app.config.from_pyfile(os.path.join(abs_path, 'app.cfg')) + elif not config_exists: + raise Exception(f"Config file '{config_path}' doesn't exist") root_path = os.path.expanduser(app.config['ROOT_PATH']) -- cgit v1.2.3-54-g00ecf