Merge branch '0.8.0--dev' into collections_refactor

This commit is contained in:
th3r00t
2025-08-05 00:19:01 -04:00
committed by GitHub
15 changed files with 83 additions and 1749 deletions

6
.tern-config vendored
View File

@@ -1,6 +0,0 @@
{
“plugins”:
{
“node”: {}
}
}

33
_Pipfile vendored
View File

@@ -1,33 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
websockets = "*"
loguru = "*"
pypdf2 = "*"
bs4 = "*"
requests = "*"
psycopg2-binary = "*"
mobi-python = "*"
psycopg = "*"
lxml = "*"
"sqlalchemy.orm" = "*"
sqlalchemy = "==2.0.0b3"
fastapi = {extras = ["all"], version = "*"}
jinja2 = "*"
libsass = "*"
nodejs-bin = "*"
npm = "*"
brotlipy = "*"
[dev-packages]
debugpy = "*"
pudb = "*"
ptipython = "*"
chardet = "*"
pre-commit = "*"
[requires]
python_version = "3.11.2"

1579
_Pipfile.lock generated vendored

File diff suppressed because it is too large Load Diff

32
docker/Dockerfile vendored
View File

@@ -1,6 +1,6 @@
# This file is used to build the Dockerhub image. To host pyShelf yourself for
# production, please use the official pyShelf image on
# This file is used to build the Dockerhub image. To host pyShelf yourself for
# production, please use the official pyShelf image on
# https://hub.docker.com/r/pyshelf/pyshelf
# Use the following commands to build and push the docker image to Dockerhub:
@@ -9,20 +9,30 @@
# docker login
# docker push pyshelf/pyshelf
FROM ubuntu
FROM ubuntu:latest
EXPOSE 8000
EXPOSE 8080
EXPOSE 1337
RUN apt-get update -y
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential python3 python3-dev python3-pip python3-venv
RUN apt-get upgrade -y
RUN apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev \
libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget \
libbz2-dev curl -y
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
RUN export NVM_DIR="$HOME/.nvm" ; \
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" ; nvm install 14 npm
WORKDIR /tmp
RUN wget https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tgz
RUN tar -xf Python-3.12.0.tgz
WORKDIR /tmp/Python-3.12.0/
RUN ./configure --enable-optimizations
RUN make -j 4
RUN make install
COPY . /pyshelf
COPY ./docker/config.json /pyshelf/config.json
COPY ./docker/requirements.txt /pyshelf/requirements.txt
WORKDIR /pyshelf/
RUN python3 -m pip install -r requirements.txt
ENTRYPOINT python3 configure \
&& cd src/ \
&& daphne -b 0.0.0.0 -p 8000 frontend.asgi:application
RUN python3 -m pip install --no-cache-dir -r requirements.txt
ENTRYPOINT hatch run ./pyShelf.py

2
docker/README.md vendored
View File

@@ -2,5 +2,3 @@ Use `docker build -t pyshelf/pyshelf -f ./docker/Dockerfile .` in the project ro
Make sure the following files are in sync:
* config.json
* docker/pyshelf_nginx.conf
* uwsgi.ini

20
docker/config.json vendored
View File

@@ -1 +1,19 @@
{"TITLE": "pyShelf E-Book Server", "VERSION": "0.7.0", "BOOKPATH": "/books", "DB_HOST": "localhost", "DB_PORT": "5432", "DATABASE": "pyshelf", "USER": "pyshelf", "PASSWORD": "pyshelf", "BOOKSHELF": "data/shelf.json", "ALLOWED_HOSTS": ["localhost", "127.0.0.1", "[::1]", "0.0.0.0"], "SECRET": "", "BUILD_MODE": "production"}
{
"TITLE": "pyShelf E-Book Server",
"VERSION": "0.8.0",
"BOOKPATH": "/books",
"DB_HOST": "127.0.0.1",
"DB_PORT": "5433",
"DB_ENGINE": "sqlite",
"DATABASE": "pyshelf",
"USER": "pyshelf",
"PASSWORD": "pyshelf",
"BOOKSHELF": "data/shelf.json",
"ALLOWED_HOSTS": [
"localhost",
"127.0.0.1",
"[::1]",
"0.0.0.0"
],
"BUILD_MODE": "production"
}

View File

@@ -1,34 +1,36 @@
version: "3.7"
# This file is used to test the Dockerhub image. To host pyShelf yourself for
# production, please use the official pyShelf image on
# This file is used to test the Dockerhub image. To host pyShelf yourself for
# production, please use the official pyShelf image on
# https://hub.docker.com/r/pyshelf/pyshelf
# For development, use the following command in the root folder:
#
#
# docker-compose -f ./docker/development.docker-compose.yml up --build
services:
db:
image: "postgres"
environment:
- "POSTGRES_PASSWORD=pyshelf"
- "POSTGRES_USER=pyshelf"
- "POSTGRES_DB=pyshelf"
volumes:
- "db_data:/var/lib/postgresql/data/"
# db:
# image: "postgres"
# environment:
# - "POSTGRES_PASSWORD=pyshelf"
# - "POSTGRES_USER=pyshelf"
# - "POSTGRES_DB=pyshelf"
# volumes:
# - "db_data:/var/lib/postgresql/data/"
# ports:
# - "5433:5432"
pyshelf:
build:
context: ..
dockerfile: ./docker/Dockerfile
ports:
ports:
- "8080:8000"
- "1337:1337"
volumes:
- "${LOCAL_BOOK_DIR}:/books"
depends_on:
- db
# depends_on:
# - db
volumes:
db_data:
# volumes:
# db_data:

View File

@@ -1,15 +1,17 @@
version: "3.7"
services:
db:
image: "postgres"
restart: always
environment:
- "POSTGRES_PASSWORD=pyshelf"
- "POSTGRES_USER=pyshelf"
- "POSTGRES_DB=pyshelf"
volumes:
- "db_data:/var/lib/postgresql/data/"
# db:
# image: "postgres"
# restart: always
# environment:
# - "POSTGRES_PASSWORD=pyshelf"
# - "POSTGRES_USER=pyshelf"
# - "POSTGRES_DB=pyshelf"
# volumes:
# - "db_data:/var/lib/postgresql/data/"
# ports:
# - "5433:5432"
pyshelf:
image: "pyshelf/pyshelf"
restart: always
@@ -18,7 +20,7 @@ services:
- "1337:1337"
volumes:
- "${LOCAL_BOOK_DIR}:/books"
depends_on:
- db
volumes:
db_data:
# depends_on:
# - db
#volumes:
# db_data:

View File

@@ -1,30 +0,0 @@
upstream django {
server unix:///tmp/pyshelf_wsgi.sock;
}
server {
listen 8000;
server_name localhost;
access_log /var/log/nginx/pyshelf.access.log;
error_log /var/log/nginx/pyshelf.error.log;
charset utf-8;
client_max_body_size 75M;
location /media {
root /pyshelf/src/interface;
}
location /static {
root /pyshelf/src/interface;
}
location /books {
internal;
alias /pyshelf;
}
location / {
uwsgi_pass django;
include uwsgi_params;
}
}

1
docker/requirements.txt vendored Normal file
View File

@@ -0,0 +1 @@
hatch

3
pyShelf.py vendored Executable file → Normal file
View File

@@ -6,7 +6,6 @@ from pathlib import Path
from threading import Thread
from src.backend.lib.config import Config
from src.backend.lib.storage import Storage
from src.backend.pyShelf_MakeCollections import MakeCollections
from src.backend.pyShelf_ScanLibrary import execute_scan
from src.frontend.lib.FastAPIServer import FastAPIServer
# import websockets
@@ -23,7 +22,7 @@ def run_import():
config.logger.info("Begining book import.")
execute_scan(PRG_PATH, config=config)
config.logger.info("Finished book import.")
MakeCollections(PRG_PATH, config=config)
# MakeCollections(PRG_PATH, config=config)
return "Import Complete"

6
pyproject.toml vendored
View File

@@ -90,8 +90,4 @@ include_trailing_comma = true
line_length = 88
multi_line_output = 3
use_parentheses = true
known_third_party = [
"backend", "bs4", "django", "interface", "mobi", "prompt_toolkit",
"psycopg2", "pyfiglet", "requests"
]
known_third_party = ["backend", "bs4", "django", "interface", "mobi", "prompt_toolkit", "psycopg2-binary", "pyfiglet", "requests"]

View File

@@ -1,5 +1,6 @@
from typing import Optional
from typing_extensions import Annotated
from sqlalchemy import func, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
import datetime
@@ -49,38 +50,4 @@ class Collection(Base):
book_id: Mapped[int] = mapped_column(ForeignKey("Book.id"))
# Each collection entry points to one book
book = relationship("Book", back_populates="collections")
# class Book(Base):
# """Book model."""
#
# __tablename__ = "Book"
#
# id: Mapped[int] = mapped_column(primary_key=True, nullable=False)
# title: Mapped[str]
# author: Mapped[Optional[str]]
# categories: Mapped[Optional[str]]
# cover: Mapped[Optional[bytes]]
# pages: Mapped[Optional[int]]
# progress: Mapped[Optional[float]]
# file_name: Mapped[str]
# description: Mapped[Optional[str]]
# date: Mapped[timestamp]
# rights: Mapped[Optional[str]]
# tags: Mapped[Optional[str]]
# identifier: Mapped[Optional[str]]
# publisher: Mapped[Optional[str]]
# collection = relationship("Collection", back_populates="book")
#
#
# class Collection(Base):
# """Collection model."""
#
# __tablename__ = "Collection"
#
# id: Mapped[int] = mapped_column(primary_key=True)
# collection: Mapped[str]
# book_id: Mapped[int] = mapped_column(ForeignKey(Book.id))
# book = relationship("Book", back_populates="collections")
book = relationship("Book", back_populates="collections")

View File

@@ -86,7 +86,8 @@ class Storage:
cover_image = None
if not book[1]:
pass
collections = self.parse_collections_from_path(book)
# collections = self.parse_collections_from_path(book)
# breakpoint()
_book = Book(
title=book[0],
author=book[1],
@@ -173,6 +174,7 @@ class Storage:
_q = _sess.execute(
select(Collection.id).where(
Collection.collection == _s,
# BUG: book.id is not the correct identifier.
Collection.book_id == book.id,
)
)

View File

@@ -1,6 +1,4 @@
"""pyShelf's Frontend Objects."""
from sys import exit
from shutil import which
from subprocess import run
from pathlib import Path
from ...backend.lib.config import Config
@@ -16,16 +14,5 @@ class JSInterface():
def install(self):
"""Install the JavaScript dependencies."""
if which("npm"):
self.config.logger.info("Installing JavaScript dependencies...")
run(["npm", "install"], cwd=self.package_json.parent)
else:
self.config.logger.error("npm is not installed.")
exit(1)
if which("npx"):
self.config.logger.info("Compiling TypeScript...")
run(["npx", "tsc", "static/script/pyshelf.ts"], cwd=self.package_json.parent)
else:
self.config.logger.error("npx is not installed.")
exit(1)
run(["npm", "install"], cwd=self.package_json.parent)
run(["npx", "tsc", "static/script/pyshelf.ts"], cwd=self.package_json.parent)