aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2023-09-17 12:23:47 +0200
committerJoris2023-09-17 12:23:47 +0200
commit1ebc55c72a1a17293bbf4ad86e0177a10a794750 (patch)
tree5fce0ea3a011ccbae85b0d3927f8ac33099585fb
parentc236facb4d4c277773c83f1a4ee85b48833d7e67 (diff)
downloadbooks-1ebc55c72a1a17293bbf4ad86e0177a10a794750.tar.gz
books-1ebc55c72a1a17293bbf4ad86e0177a10a794750.tar.bz2
books-1ebc55c72a1a17293bbf4ad86e0177a10a794750.zip
Make app packageable
-rw-r--r--.gitignore2
-rw-r--r--Makefile10
-rw-r--r--README.md5
-rwxr-xr-xbin/dev-server8
-rwxr-xr-xbooks6
-rw-r--r--cli/__init__.py (renamed from src/library/__init__.py)0
-rw-r--r--cli/library/__init__.py (renamed from src/new/__init__.py)0
-rw-r--r--cli/library/command.py (renamed from src/library/command.py)8
-rw-r--r--cli/main.py80
-rw-r--r--cli/new/__init__.py (renamed from src/view/__init__.py)0
-rw-r--r--cli/new/command.py (renamed from src/new/command.py)14
-rw-r--r--cli/new/format.py (renamed from src/new/format.py)8
-rw-r--r--cli/new/reader.py (renamed from src/new/reader.py)0
-rw-r--r--cli/view/__init__.py0
-rw-r--r--cli/view/command.py16
-rw-r--r--flake.nix2
-rw-r--r--library/client/book.ts (renamed from src/view/client/book.ts)0
-rw-r--r--library/client/lib/functions.ts (renamed from src/view/client/lib/functions.ts)0
-rw-r--r--library/client/lib/i18n.ts (renamed from src/view/client/lib/i18n.ts)0
-rw-r--r--library/client/lib/rx.ts (renamed from src/view/client/lib/rx.ts)0
-rw-r--r--library/client/lib/search.ts (renamed from src/view/client/lib/search.ts)0
-rw-r--r--library/client/main.ts (renamed from src/view/client/main.ts)0
-rw-r--r--library/client/view/books.ts (renamed from src/view/client/view/books.ts)0
-rw-r--r--library/client/view/components/modal.ts (renamed from src/view/client/view/components/modal.ts)0
-rw-r--r--library/client/view/filters.ts (renamed from src/view/client/view/filters.ts)0
-rw-r--r--library/public/index.html (renamed from src/view/public/index.html)0
-rw-r--r--library/public/main.css (renamed from src/view/public/main.css)0
-rw-r--r--library/tsconfig.json (renamed from src/view/tsconfig.json)0
-rw-r--r--setup.py12
-rw-r--r--src/main.py71
-rw-r--r--src/view/command.py17
31 files changed, 137 insertions, 122 deletions
diff --git a/.gitignore b/.gitignore
index f7a3017..674e9cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
__pycache__
-src/view/public/*.js
+library/public/*.js
diff --git a/Makefile b/Makefile
index 593752d..fc2acc6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,11 @@
-build:
+build: library/public/main.js
+
+library/public/main.js:
@esbuild \
- --bundle src/main.ts \
+ --bundle library/client/main.ts \
--minify \
--target=es2017 \
- --outdir=public
+ --outdir=library/public
clean:
- @rm -f public/main.js
+ @rm -f library/public/*.js
diff --git a/README.md b/README.md
index b45f1bc..d676bf2 100644
--- a/README.md
+++ b/README.md
@@ -33,8 +33,9 @@ In nix shell (`nix develop`), run:
## Show library
- BOOK_LIBRARY=path-to-books python src/main.py library
+ make
+ BOOKS_LIBRARY=path-to-books BOOKS_BROWSER=firefox python src/main.py library
## Add book
- BOOK_LIBRARY=path-to-books python src/main.py new optional-path-to-ebook
+ BOOKS_LIBRARY=path-to-books python src/main.py new optional-path-to-ebook
diff --git a/bin/dev-server b/bin/dev-server
index c98fdc5..7351209 100755
--- a/bin/dev-server
+++ b/bin/dev-server
@@ -3,7 +3,7 @@ set -euo pipefail
cd $(dirname "$0")/..
if [ "$#" == 1 ]; then
- BOOK_LIBRARY="$1"
+ BOOKS_LIBRARY="$1"
else
echo "usage: $0 path-to-book-directory"
exit 1
@@ -11,14 +11,14 @@ fi
# Watch books
-BUILD_BOOKS_CMD="echo \"const bookLibrary=\" > src/view/public/books.js && python src/main.py library >> src/view/public/books.js && echo src/view/public/books.js updated."
+BUILD_BOOKS_CMD="echo \"const bookLibrary=\" > library/public/books.js && ./books library >> library/public/books.js && echo library/public/books.js updated."
watchexec \
- --watch "$BOOK_LIBRARY" \
+ --watch "$BOOKS_LIBRARY" \
-- "$BUILD_BOOKS_CMD" &
# Watch TypeScript
-cd src/view
+cd library
CHECK="echo -e 'Checking TypeScript…\n' && tsc --checkJs"
BUILD="esbuild --bundle main.ts --target=es2017 --outdir=public"
SHOW="echo -e '\nOpen $PWD/public/index.html'"
diff --git a/books b/books
new file mode 100755
index 0000000..dbdc846
--- /dev/null
+++ b/books
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+import cli.main
+import os
+
+bin_dir = os.path.dirname(os.path.realpath(__file__))
+cli.main.main(bin_dir)
diff --git a/src/library/__init__.py b/cli/__init__.py
index e69de29..e69de29 100644
--- a/src/library/__init__.py
+++ b/cli/__init__.py
diff --git a/src/new/__init__.py b/cli/library/__init__.py
index e69de29..e69de29 100644
--- a/src/new/__init__.py
+++ b/cli/library/__init__.py
diff --git a/src/library/command.py b/cli/library/command.py
index 6b8577e..1c4d20c 100644
--- a/src/library/command.py
+++ b/cli/library/command.py
@@ -3,13 +3,13 @@ import json
import os
import tomllib
-def run(book_library):
- print(get(book_library))
+def run(books_library):
+ print(get(books_library))
-def get(book_library):
+def get(books_library):
metadatas = []
- for path in glob.glob(f'{book_library}/**/metadata.toml', recursive=True):
+ for path in glob.glob(f'{books_library}/**/metadata.toml', recursive=True):
with open(path, 'rb') as f:
directory = os.path.dirname(os.path.realpath(path))
metadata = tomllib.load(f)
diff --git a/cli/main.py b/cli/main.py
new file mode 100644
index 0000000..01434fa
--- /dev/null
+++ b/cli/main.py
@@ -0,0 +1,80 @@
+# Manage book library.
+#
+# Required dependencies:
+#
+# - python >= 3.11
+# - requests
+# - pillow
+# - ebook-convert CLI (from calibre)
+
+import cli.library.command
+import cli.new.command
+import cli.view.command
+import os
+import sys
+
+def main(bin_dir):
+ match sys.argv:
+ case [ _, 'new' ]:
+ books_library = get_books_library()
+ cli.new.command.run(books_library)
+ case [ _, 'new', book_source ]:
+ if os.path.isfile(book_source):
+ books_library = get_books_library()
+ cli.new.command.run(books_library, book_source)
+ else:
+ print_help(title=f'File not found: {book_source}.')
+ exit(1)
+ case [ _, 'library' ]:
+ books_library = get_books_library()
+ cli.library.command.run(books_library)
+ case [ _, 'view' ]:
+ books_library = get_books_library()
+ books_browser = get_env_var('BOOKS_BROWSER')
+ cli.view.command.run(books_library, books_browser, bin_dir)
+ case [ _, '--help' ]:
+ print_help()
+ case [ _, '-h' ]:
+ print_help()
+ case _:
+ print_help('Command not found.')
+ exit(1)
+
+def get_books_library():
+ books_library = get_env_var('BOOKS_LIBRARY')
+ if os.path.isdir(books_library):
+ return books_library
+ else:
+ print_help(title=f'BOOKS_LIBRARY {books_library} not found.')
+ exit(1)
+
+def get_env_var(key):
+ value = os.getenv(key)
+ if value:
+ return value
+ else:
+ print_help(title=f'{key} environment variable is required.')
+ exit(1)
+
+def print_help(title='Manage book library'):
+ print(f"""{title}
+
+- Insert book entry with optional ebook file:
+
+ $ python {sys.argv[0]} new [path-to-book]
+
+- Print library metadata as json:
+
+ $ python {sys.argv[0]} library
+
+- View books in web page:
+
+ $ python {sys.argv[0]} view
+
+Environment variables:
+
+ BOOKS_LIBRARY: path to book library,
+ BOOKS_BROWSER: browser command executed to view the library.""")
+
+if __name__ == "__main__":
+ main()
diff --git a/src/view/__init__.py b/cli/new/__init__.py
index e69de29..e69de29 100644
--- a/src/view/__init__.py
+++ b/cli/new/__init__.py
diff --git a/src/new/command.py b/cli/new/command.py
index fe706c2..9f5e5dc 100644
--- a/src/new/command.py
+++ b/cli/new/command.py
@@ -1,19 +1,14 @@
import PIL.Image
+import cli.new.format as format
+import cli.new.reader as reader
import io
import os
import pathlib
-import re
import requests
import shutil
import subprocess
-import sys
-import unicodedata
-import urllib.request
-import new.reader as reader
-import new.format as format
-
-def run(book_library, book_source=None):
+def run(books_library, book_source=None):
# Get data
@@ -33,8 +28,7 @@ def run(book_library, book_source=None):
author_path = format.path_part(author_sort)
title_path = format.path_part(title)
- library_path = '/home/joris/documents/books'
- output_dir = f'{library_path}/{author_path}/{title_path}'
+ output_dir = f'{books_library}/{author_path}/{title_path}'
metadata_path = f'{output_dir}/metadata.toml'
cover_path = f'{output_dir}/cover.webp'
diff --git a/src/new/format.py b/cli/new/format.py
index a712544..c004f82 100644
--- a/src/new/format.py
+++ b/cli/new/format.py
@@ -1,14 +1,6 @@
-import PIL.Image
-import io
-import os
import pathlib
import re
-import requests
-import shutil
-import subprocess
-import sys
import unicodedata
-import urllib.request
def format_list(xs):
return '[ ' + ', '.join([f'"{x}"' for x in xs]) + ' ]'
diff --git a/src/new/reader.py b/cli/new/reader.py
index eacd70b..eacd70b 100644
--- a/src/new/reader.py
+++ b/cli/new/reader.py
diff --git a/cli/view/__init__.py b/cli/view/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cli/view/__init__.py
diff --git a/cli/view/command.py b/cli/view/command.py
new file mode 100644
index 0000000..72e44dd
--- /dev/null
+++ b/cli/view/command.py
@@ -0,0 +1,16 @@
+import cli.library.command
+import shutil
+import subprocess
+import subprocess
+import tempfile
+import time
+
+def run(books_library, books_browser, bin_dir):
+ tmp_dir = tempfile.mkdtemp()
+ shutil.copytree(f'{bin_dir}/library/public', tmp_dir, dirs_exist_ok=True)
+ subprocess.run(['chmod', 'u+w', tmp_dir])
+ with open(f'{tmp_dir}/books.js', 'w') as f:
+ json = cli.library.command.get(books_library)
+ f.write(f'const bookLibrary = {json}')
+ browser_cmd = f'{books_browser} {tmp_dir}/index.html'
+ subprocess.run(browser_cmd.split(' '))
diff --git a/flake.nix b/flake.nix
index 10c1430..97d9261 100644
--- a/flake.nix
+++ b/flake.nix
@@ -23,8 +23,8 @@
# CLI
python311
- python311Packages.requests
python311Packages.pillow
+ python311Packages.requests
ebook-convert
];
};
diff --git a/src/view/client/book.ts b/library/client/book.ts
index 680cc11..680cc11 100644
--- a/src/view/client/book.ts
+++ b/library/client/book.ts
diff --git a/src/view/client/lib/functions.ts b/library/client/lib/functions.ts
index 21fdad9..21fdad9 100644
--- a/src/view/client/lib/functions.ts
+++ b/library/client/lib/functions.ts
diff --git a/src/view/client/lib/i18n.ts b/library/client/lib/i18n.ts
index 3716367..3716367 100644
--- a/src/view/client/lib/i18n.ts
+++ b/library/client/lib/i18n.ts
diff --git a/src/view/client/lib/rx.ts b/library/client/lib/rx.ts
index bf01b6d..bf01b6d 100644
--- a/src/view/client/lib/rx.ts
+++ b/library/client/lib/rx.ts
diff --git a/src/view/client/lib/search.ts b/library/client/lib/search.ts
index 026cb94..026cb94 100644
--- a/src/view/client/lib/search.ts
+++ b/library/client/lib/search.ts
diff --git a/src/view/client/main.ts b/library/client/main.ts
index 5885871..5885871 100644
--- a/src/view/client/main.ts
+++ b/library/client/main.ts
diff --git a/src/view/client/view/books.ts b/library/client/view/books.ts
index aba55c1..aba55c1 100644
--- a/src/view/client/view/books.ts
+++ b/library/client/view/books.ts
diff --git a/src/view/client/view/components/modal.ts b/library/client/view/components/modal.ts
index 5e845e1..5e845e1 100644
--- a/src/view/client/view/components/modal.ts
+++ b/library/client/view/components/modal.ts
diff --git a/src/view/client/view/filters.ts b/library/client/view/filters.ts
index efe4115..efe4115 100644
--- a/src/view/client/view/filters.ts
+++ b/library/client/view/filters.ts
diff --git a/src/view/public/index.html b/library/public/index.html
index ce4d568..ce4d568 100644
--- a/src/view/public/index.html
+++ b/library/public/index.html
diff --git a/src/view/public/main.css b/library/public/main.css
index f361cbe..f361cbe 100644
--- a/src/view/public/main.css
+++ b/library/public/main.css
diff --git a/src/view/tsconfig.json b/library/tsconfig.json
index 1e07c37..1e07c37 100644
--- a/src/view/tsconfig.json
+++ b/library/tsconfig.json
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..c2bae59
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,12 @@
+import setuptools
+
+setuptools.setup(
+ name="books",
+ version="1.0.0",
+ author="Joris Guyonvarch",
+ description="Visualize a book library",
+ long_description_content_type="text/markdown",
+ url="https://git.guyonvarch.me/books",
+ packages=setuptools.find_packages(),
+ scripts=['./books']
+)
diff --git a/src/main.py b/src/main.py
deleted file mode 100644
index 1f07785..0000000
--- a/src/main.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Manage book library.
-#
-# Required dependencies:
-#
-# - python >= 3.11
-# - requests
-# - pillow
-# - ebook-convert CLI (from calibre)
-
-import sys
-import os
-
-import library.command
-import view.command
-import new.command
-
-def print_help(title='Manage book library'):
- print(f"""{title}
-
-- Insert book entry with optional ebook file:
-
- $ python {sys.argv[0]} new [path-to-book]
-
-- Print library metadata as json:
-
- $ python {sys.argv[0]} library
-
-- View books in web page:
-
- $ python {sys.argv[0]} view browser-cmd
-
-Environment variables:
-
- BOOK_LIBRARY: path to book library.""")
-
-def get_book_library():
- path = os.getenv('BOOK_LIBRARY')
- if path is None or not os.path.isdir(path):
- print_help(title='BOOK_LIBRARY environment variable is required.')
- exit(1)
- else:
- return path
-
-def main():
- match sys.argv:
- case [ _, 'new' ]:
- book_library = get_book_library()
- new.command.run(book_library)
- case [ _, 'new', book_source ]:
- if os.path.isfile(book_source):
- book_library = get_book_library()
- new.command.run(book_library, book_source)
- else:
- print_help(title=f'File not found: {book_source}.')
- exit(1)
- case [ _, 'library' ]:
- book_library = get_book_library()
- library.command.run(book_library)
- case [ _, 'view', browser_cmd ]:
- book_library = get_book_library()
- view.command.run(book_library, browser_cmd)
- case [ _, '--help' ]:
- print_help()
- case [ _, '-h' ]:
- print_help()
- case _:
- print_help('Command not found.')
- exit(1)
-
-if __name__ == "__main__":
- main()
diff --git a/src/view/command.py b/src/view/command.py
deleted file mode 100644
index e50027f..0000000
--- a/src/view/command.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import os
-import shutil
-import subprocess
-import tempfile
-import time
-
-import library.command
-
-def run(book_library, browser_cmd):
- tmp_dir = tempfile.mkdtemp()
- directory = os.path.dirname(os.path.realpath(__file__))
- shutil.copytree(f'{directory}/public', tmp_dir, dirs_exist_ok=True)
- with open(f'{tmp_dir}/books.js', 'w') as f:
- json = library.command.get(book_library)
- f.write(f'const bookLibrary = {json}')
- browser_cmd = f'{browser_cmd} {tmp_dir}/index.html'
- subprocess.run(browser_cmd.split(' '))