diff --git a/docs/Automated Collections.html b/docs/Automated Collections.html
new file mode 100644
index 0000000..ff251a6
--- /dev/null
+++ b/docs/Automated Collections.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+Automated Collections
+
+
+
+
+
+
+
+The collection management system needs rewritten from the ground up.
+The model should look something like this.
+
+
+
+it is likely the book object will need rewritten as well.
+
+
+ Book {
+ id: int
+ title: String
+ # other book metadata
+ collection: list(Collection.id)
+ }
+
+
+
+
diff --git a/docs/Book Scraping System.html b/docs/Book Scraping System.html
index 8c71dd3..151555c 100644
--- a/docs/Book Scraping System.html
+++ b/docs/Book Scraping System.html
@@ -29,25 +29,25 @@ sub-folders in your collection.
-
-epub #75f00edf
+epub #2899a8e9
-
-mobi #2fe4b161
+mobi #ec035720
-
-pdf #ffa7e7f0
+pdf #05875e64
-
-cbz #64b5da95
+cbz #4a513e39
-
-Manual Collections #2e7e6fcf
+Manual Collections #b07156f4
-
-
-Automated Collections #81db675a
+
-
+Automated Collections #f258c1f8
diff --git a/docs/Client.html b/docs/Client.html
new file mode 100644
index 0000000..6fb6d23
--- /dev/null
+++ b/docs/Client.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Client
+
+
+
+
+
+
+Home TOC github
+
+
+
+frontend ui
+
+
+
+
+dependency
+
+
+
+-
+npm #c5f8d347
+
+
-
+sass #8f43ab4c
+
+
-
+pip #14ee256e
+
+
+
+
+
+-
+NextAuthjs
+
+
-
+Authentication Providers
+
+
+-
+Discord
+ Required: Client ID, Client Secret
+
+
-
+Github
+ Required: Client ID, Client Secret, only one callback per app.
+
+
+
+
+
+
+
+
+ux
+
+
+
+-
+Favorites #0fc67f94
+
+
-
+Permissions / Roles #9c4f279e
+
+
-
+User Profile #289e0fe0
+
+
-
+User Settings #51955b33
+
+
+
+
+data
+
+
+
+-
+Book Management System #92e523d2
+
+
+-
+add #bda9a0f3
+
+
-
+remove #4b34e931
+
+
-
+update #eb959340
+
+
-
+access level #b00795a4
+
+
-
+ownership #8c80edc5
+
+
-
+attach #8acb21a9
+
+
-
+detach #2e263616
+
+
+
+
+
+
diff --git a/docs/index.html b/docs/index.html
index fea8886..72e7cc3 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -108,7 +108,7 @@ Filesystem-io
REST API #c7bc51c5
-Frontend #a76c1038
+Client #c68b0664
diff --git a/src/backend/lib/models.py b/src/backend/lib/models.py
index ba456d8..9258b52 100644
--- a/src/backend/lib/models.py
+++ b/src/backend/lib/models.py
@@ -6,22 +6,20 @@ import datetime
timestamp = Annotated[
datetime.datetime,
- mapped_column(nullable=False, server_default=func.CURRENT_TIMESTAMP())
+ mapped_column(nullable=False, server_default=func.CURRENT_TIMESTAMP()),
]
class Base(DeclarativeBase):
"""Base class for all models."""
- pass
-
class Book(Base):
"""Book model."""
- __tablename__ = "books"
+ __tablename__ = "Book"
- book_id: Mapped[int] = mapped_column(primary_key=True, nullable=False)
+ id: Mapped[int] = mapped_column(primary_key=True, nullable=False)
title: Mapped[str]
author: Mapped[Optional[str]]
categories: Mapped[Optional[str]]
@@ -37,12 +35,11 @@ class Book(Base):
publisher: Mapped[Optional[str]]
-
class Collection(Base):
"""Collection model."""
- __tablename__ = "collections"
+ __tablename__ = "Collection"
+ id: Mapped[int] = mapped_column(primary_key=True)
collection: Mapped[str]
- book_id: Mapped[int] = mapped_column(ForeignKey(Book.book_id))
- collection_id: Mapped[int] = mapped_column(primary_key=True)
+ book_id: Mapped[int] = mapped_column(ForeignKey(Book.id))
diff --git a/src/backend/lib/storage.py b/src/backend/lib/storage.py
index 969140c..3699a7b 100644
--- a/src/backend/lib/storage.py
+++ b/src/backend/lib/storage.py
@@ -1,6 +1,5 @@
"""Pyshelf's Main Storage Class."""
import re
-import os
from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
@@ -36,8 +35,7 @@ class Storage:
self.password = self.config.password
self.db_host = self.config.db_host
self.db_port = self.config.db_port
- self.engine = create_engine(self.get_connection_string(),
- pool_pre_ping=True)
+ self.engine = create_engine(self.get_connection_string(), pool_pre_ping=True)
def get_connection_string(self):
"""Get connection string.
@@ -49,7 +47,7 @@ class Storage:
str : sqlalchemy Connection String
"""
if self.config.db_engine == "sqlite":
- return f"sqlite:////{self.config.root}/pyshelf.db"
+ return f"sqlite:////{self.config.root}/pyshelf.sqlite3"
elif self.config.db_engine == "psql":
return f"postgresql://{self.user}:{self.password}\
@{self.db_host}:{self.db_port}/{self.sql}"
@@ -86,6 +84,8 @@ class Storage:
cover_image = None
if not book[1]:
pass
+ # breakpoint()
+ self.parse_collections_from_path(book)
_book = Book(
title=book[0],
author=book[1],
@@ -117,6 +117,36 @@ class Storage:
session.close()
return _result
+ def parse_collections_from_path(self, book: dict()) -> list():
+ """Parse book path's to determine common folder structure.
+
+ Stores collections based on shared paths.
+
+ Parameters
+ ----------
+ book : dict()
+ Book object to parse.
+
+ Returns
+ -------
+ collections : list()
+ List of collections.
+ """
+ collections = []
+ title_regx = re.compile(r"^[0-9][0-9]*|-|\ \B")
+ _pathing = book[3].split(self.config.book_path + "/")[1].split("/")
+ try:
+ _pathing.pop(0)
+ _pathing.pop(-1)
+ except IndexError:
+ pass
+ for _p in _pathing:
+ _s = _p.replace("'", "")
+ _x = re.sub(title_regx, "", _s)
+ _s = _x.strip()
+ collections.append(_s)
+ return collections
+
def make_collections(self):
"""Parse book path's to determine common folder structure.
@@ -126,7 +156,7 @@ class Storage:
self.config.logger.info("Making collections.")
_title_regx = re.compile(r"^[0-9][0-9]*|-|\ \B")
session = Session(self.engine)
- _set = session.execute(select(Book.book_id, Book.file_name)).all()
+ _set = session.execute(select(Book.id, Book.file_name)).all()
if _set.__len__() > 0:
for book in _set:
path = self.config.book_path + "/"
@@ -143,25 +173,22 @@ class Storage:
_s = _x.strip()
_sess = Session(self.engine)
_q = _sess.execute(
- select(Collection.collection_id).where(
+ select(Collection.id).where(
Collection.collection == _s,
- Collection.book_id == book.book_id,
+ Collection.book_id == book.id,
)
)
_sess.close()
if _q.fetchone() is None:
- _collection = Collection(
- collection=_s, book_id=book.book_id)
+ _collection = Collection(collection=_s, book_id=book.id)
with Session(self.engine) as _sess:
try:
_sess.add(_collection)
_sess.commit()
_sess.close()
- self.config.logger.info(
- f"Collection {_s} added.")
+ self.config.logger.info(f"Collection {_s} added.")
except Exception as e:
- self.config.logger.error(
- f"Collection {_s} failed: {e}")
+ self.config.logger.error(f"Collection {_s} failed: {e}")
_collections.append(_p)
self.config.logger.info("Finished making collections.")
@@ -180,21 +207,23 @@ class Storage:
session = Session(self.engine)
if collection:
_result = session.execute(
- select(Book).join(Collection)
- .where(Collection.collection_id == collection)
- .offset(skip).limit(limit)).all()
+ select(Book)
+ .join(Collection)
+ .where(Collection.id == collection)
+ .offset(skip)
+ .limit(limit)
+ ).all()
else:
- _result = session.execute(
- select(Book).offset(skip).limit(limit)).all()
+ _result = session.execute(select(Book).offset(skip).limit(limit)).all()
session.close()
return _result
- def get_book(self, book_id):
+ def get_book(self, id):
"""Get book from database.
Parameters
----------
- book_id : int
+ id : int
Book ID to filter by.
Returns
@@ -202,7 +231,7 @@ class Storage:
_result : ScalarResult Object
"""
session = Session(self.engine)
- _result = session.execute(select(Book).where(Book.book_id == book_id)).first()
+ _result = session.execute(select(Book).where(Book.id == id)).first()
session.close()
return _result
@@ -214,9 +243,6 @@ class Storage:
_result : ScalarResult Object
"""
session = Session(self.engine)
- _result = session.execute(
- select(Collection)
- .join(Book)
- ).all()
+ _result = session.execute(select(Collection).join(Book)).all()
session.close()
return _result
diff --git a/wiki/Automated Collections.wiki b/wiki/Automated Collections.wiki
new file mode 100644
index 0000000..4b7b72c
--- /dev/null
+++ b/wiki/Automated Collections.wiki
@@ -0,0 +1,21 @@
+= Automated Collection Management System =
+The collection management system needs rewritten from the ground up.
+The model should look something like this.
+* [ ] TODO :: Refactor collections algorithm. #8f46262c
+{{{python
+ Collection {
+ id: int
+ name: String
+ books: list(Book)
+ }
+}}}
+
+it is likely the book object will need rewritten as well.
+{{{python
+ Book {
+ id: int
+ title: String
+ # other book metadata
+ collection: list(Collection.id)
+ }
+}}}
diff --git a/wiki/Book Scraping System.wiki b/wiki/Book Scraping System.wiki
index 83234cd..fcdd627 100644
--- a/wiki/Book Scraping System.wiki
+++ b/wiki/Book Scraping System.wiki
@@ -10,14 +10,14 @@ pyShelf features a recursive scraping algorithm that itterates over all
sub-folders in your collection.
== Scrapers ==
- * [X] epub #75f00edf
- * [X] mobi #2fe4b161
- * [X] pdf #ffa7e7f0
- * [ ] cbz #64b5da95
+ * [X] epub #2899a8e9
+ * [X] mobi #ec035720
+ * [X] pdf #05875e64
+ * [ ] cbz #4a513e39
== Collections ==
- * [ ] Manual Collections #2e7e6fcf
- * [X] Automated Collections #81db675a
+ * [ ] Manual Collections #b07156f4
+ * [ ] [[Automated Collections]] #f258c1f8
== State ==
diff --git a/wiki/Client.wiki b/wiki/Client.wiki
new file mode 100644
index 0000000..50586ef
--- /dev/null
+++ b/wiki/Client.wiki
@@ -0,0 +1,41 @@
+[[index|Home]] [[TOC]] [[https://github.com/th3r00t/pyShelf.git|github]]
+= Client =
+:frontend:ui:
+
+== Dependency Management ==
+:dependency:
+
+* [X] npm #c5f8d347
+* [X] sass #8f43ab4c
+* [ ] pip #14ee256e
+
+== [[https://create.t3.gg|T3.gg]] ==
+=== User System ===
+- NextAuthjs
+- Authentication Providers
+ - Discord
+ Required: Client ID, Client Secret
+ - Github
+ Required: Client ID, Client Secret, only one callback per app.
+ {{https://next-auth.js.org/providers/github|NextAuthjs Github}}
+=== User Experience ===
+
+
+:ux:
+
+* [ ] Favorites #0fc67f94
+* [ ] Permissions / Roles #9c4f279e
+* [ ] User Profile #289e0fe0
+* [ ] User Settings #51955b33
+
+=== Data Management ===
+:data:
+
+* [ ] Book Management System #92e523d2
+ * [ ] add #bda9a0f3
+ * [ ] remove #4b34e931
+ * [ ] update #eb959340
+ * [ ] access level #b00795a4
+ * [ ] ownership #8c80edc5
+ * [ ] attach #8acb21a9
+ * [ ] detach #2e263616
diff --git a/wiki/index.wiki b/wiki/index.wiki
index 96ac3ce..b7ad694 100644
--- a/wiki/index.wiki
+++ b/wiki/index.wiki
@@ -38,7 +38,7 @@ pyShelf supports the following formats:
== TODO ==
* [ ] [[Book Scraping System]] #f7edafb1
* [ ] [[REST API]] #c7bc51c5
- * [ ] [[Frontend]] #a76c1038
+ * [ ] [[Client]] #c68b0664
== Development ==