From 58d4f27c615b0226a05bdf4470bb4d7907753e6e Mon Sep 17 00:00:00 2001 From: MassiveAtoms Date: Sat, 11 Jul 2020 14:56:22 -0300 Subject: [PATCH] did some optimisation --- .../CalibreWebCompanion/settings.py | 4 +- .../CalibreWebCompanion/urls.py | 10 +- CalibreWebCompanion/library/calibredb.py | 107 +++++++++ .../library/context_processors.py | 21 +- .../migrations/0002_auto_20200711_1322.py | 221 ++++++++++++++++++ CalibreWebCompanion/library/models.py | 45 ++-- .../library/templates/base.html | 8 +- .../library/templates/library/results.html | 40 ++++ README.md | 14 +- 9 files changed, 439 insertions(+), 31 deletions(-) create mode 100644 CalibreWebCompanion/library/calibredb.py create mode 100644 CalibreWebCompanion/library/migrations/0002_auto_20200711_1322.py create mode 100644 CalibreWebCompanion/library/templates/library/results.html diff --git a/CalibreWebCompanion/CalibreWebCompanion/settings.py b/CalibreWebCompanion/CalibreWebCompanion/settings.py index 623a415..e25b9fa 100644 --- a/CalibreWebCompanion/CalibreWebCompanion/settings.py +++ b/CalibreWebCompanion/CalibreWebCompanion/settings.py @@ -78,11 +78,11 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', "library", - # 'debug_toolbar', # DEBUG purposes + 'debug_toolbar', # DEBUG purposes ] MIDDLEWARE = [ - # 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes + 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/CalibreWebCompanion/CalibreWebCompanion/urls.py b/CalibreWebCompanion/CalibreWebCompanion/urls.py index 8efcffc..f736019 100644 --- a/CalibreWebCompanion/CalibreWebCompanion/urls.py +++ b/CalibreWebCompanion/CalibreWebCompanion/urls.py @@ -30,8 +30,8 @@ urlpatterns = [ ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) -# if settings.DEBUG: # DEBUG purposes -# import debug_toolbar -# urlpatterns = [ -# path('__debug__/', include(debug_toolbar.urls)), -# ] + urlpatterns +if settings.DEBUG: # DEBUG purposes + import debug_toolbar + urlpatterns = [ + path('__debug__/', include(debug_toolbar.urls)), + ] + urlpatterns diff --git a/CalibreWebCompanion/library/calibredb.py b/CalibreWebCompanion/library/calibredb.py new file mode 100644 index 0000000..a0cdb7c --- /dev/null +++ b/CalibreWebCompanion/library/calibredb.py @@ -0,0 +1,107 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +engine = create_engine('sqlite:///C://Users//MassiveAtoms//Documents//Calibre Library//metadata.db.', echo=True) +Base = declarative_base(engine) +######################################################################## + +class Author(Base): # needed + """""" + __tablename__ = 'authors' + __table_args__ = {'autoload':True} + # has int id, text name, sort + +class Comment(Base): # needed + """""" + __tablename__ = 'comments' + __table_args__ = {'autoload':True} + # has int id, int book, text text + +# class Data(Base): # maybe +# """""" +# __tablename__ = 'data' +# __table_args__ = {'autoload':True} +# # has int id, int book, text format, text name + +class Identifier(Base): # needed + """""" + __tablename__ = 'identifiers' + __table_args__ = {'autoload':True} + # has int id, int book, text value + +class Publisher(Base): # needed + """""" + __tablename__ = 'publishers' + __table_args__ = {'autoload':True} + # has int id, text name + +class Rating(Base): # needed + """""" + __tablename__ = 'ratings' + __table_args__ = {'autoload':True} + # has int id, int rating + +class Series(Base): # needed + """""" + __tablename__ = 'series' + __table_args__ = {'autoload':True} + # has int id, text name + +class Tag(Base): # needed + """""" + __tablename__ = 'tags' + __table_args__ = {'autoload':True} + # has int id, text name + +class Book(Base): # needed + """""" + __tablename__ = 'books' + __table_args__ = {'autoload':True} + # has int id, text title, text sort, time timestamp, time pubdate, + # float series_index, text path + +class Book_author_link(Base): # needed + """""" + __tablename__ = 'books_authors_link' + __table_args__ = {'autoload':True} + # has int id, id book, id author + +class Book_publisher_link(Base): # needed + """""" + __tablename__ = 'books_publishers_link' + __table_args__ = {'autoload':True} + # has int id, id book, id publisher + +class Book_rating_link(Base): # needed + """""" + __tablename__ = 'books_ratings_link' + __table_args__ = {'autoload':True} + # has int id, id book, id rating + +class Book_series_link(Base): # needed + """""" + __tablename__ = 'books_series_link' + __table_args__ = {'autoload':True} + # has int id, id book, id series + +class Book_tags_link(Base): # needed + """""" + __tablename__ = 'books_tags_link' + __table_args__ = {'autoload':True} + # has int id, id book, id tag + + +#---------------------------------------------------------------------- +def loadSession(): + """""" + metadata = Base.metadata + Session = sessionmaker(bind=engine) + session = Session() + return session + +if __name__ == "__main__": + session = loadSession() + res = session.query(Book).all() + for i in res: + print(i.id, i.title, i.sort, i.timestamp, i.pubdate, i.series_index, i.path) + diff --git a/CalibreWebCompanion/library/context_processors.py b/CalibreWebCompanion/library/context_processors.py index bee6b0f..584a6ed 100644 --- a/CalibreWebCompanion/library/context_processors.py +++ b/CalibreWebCompanion/library/context_processors.py @@ -1,13 +1,22 @@ from .models import Author, Tag, Publisher, Language, Rating, Series +from django.db.models import Count def filters(request): - unique_authors = Author.objects.all().order_by('sort') - unique_tags = Tag.objects.all().order_by('name') - unique_publishers = Publisher.objects.all().order_by('name') - unique_languages = Language.objects.all() - unique_ratings = Rating.objects.all().order_by('rating') - unique_series = Series.objects.all().order_by('sort') + # unique_authors = Author.objects.all().order_by('sort') + # unique_tags = Tag.objects.all().order_by('name') + # unique_publishers = Publisher.objects.all().order_by('name') + # unique_ratings = Rating.objects.all().order_by('rating') + # unique_languages = Language.objects.all() + # unique_series = Series.objects.all().order_by('sort') + # unique_authors = Author.objects.annotate(num_books=Count('book')).order_by('sort') + unique_authors = Author.objects.only('name', "id").annotate(num_books=Count('book')).order_by('name') + unique_tags = Tag.objects.annotate(num_books=Count('book')).order_by('name') + unique_publishers = Publisher.objects.annotate(num_books=Count('book')).order_by('name') + unique_languages = Language.objects.annotate(num_books=Count('book')).order_by('rating') + unique_ratings = Rating.objects.annotate(num_books=Count('book')) + unique_series = Series.objects.annotate(num_books=Count('book')).order_by('sort') + return { "unique_authors": unique_authors, diff --git a/CalibreWebCompanion/library/migrations/0002_auto_20200711_1322.py b/CalibreWebCompanion/library/migrations/0002_auto_20200711_1322.py new file mode 100644 index 0000000..11beef0 --- /dev/null +++ b/CalibreWebCompanion/library/migrations/0002_auto_20200711_1322.py @@ -0,0 +1,221 @@ +# Generated by Django 3.0.7 on 2020-07-11 16:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Author', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField()), + ('sort', models.TextField(blank=True, null=True)), + ('link', models.TextField()), + ], + options={ + 'db_table': 'authors', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Book', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('sort', models.TextField(blank=True, null=True)), + ('timestamp', models.TextField(blank=True, null=True)), + ('pubdate', models.TextField(blank=True, null=True)), + ('series_index', models.FloatField()), + ('author_sort', models.TextField(blank=True, null=True)), + ('isbn', models.TextField(blank=True, null=True)), + ('lccn', models.TextField(blank=True, null=True)), + ('path', models.TextField()), + ('flags', models.IntegerField()), + ('uuid', models.TextField(blank=True, null=True)), + ('has_cover', models.BooleanField(blank=True, null=True)), + ('last_modified', models.TextField()), + ], + options={ + 'db_table': 'books', + 'managed': False, + }, + ), + migrations.CreateModel( + name='BookAuthorLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'db_table': 'books_authors_link', + 'managed': False, + }, + ), + migrations.CreateModel( + name='BookLanguageLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item_order', models.IntegerField()), + ], + options={ + 'db_table': 'books_languages_link', + 'managed': False, + }, + ), + migrations.CreateModel( + name='BookPublisherLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'db_table': 'books_publishers_link', + 'managed': False, + }, + ), + migrations.CreateModel( + name='BookRatingLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'db_table': 'books_ratings_link', + 'managed': False, + }, + ), + migrations.CreateModel( + name='BookSeriesLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'db_table': 'books_series_link', + 'managed': False, + }, + ), + migrations.CreateModel( + name='BookTagLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'db_table': 'books_tags_link', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField()), + ], + options={ + 'db_table': 'comments', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Identifier', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('book', models.IntegerField()), + ('type', models.TextField()), + ('val', models.TextField()), + ], + options={ + 'db_table': 'identifiers', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Language', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('lang_code', models.TextField()), + ], + options={ + 'db_table': 'languages', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Publisher', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField()), + ('sort', models.TextField(blank=True, null=True)), + ], + options={ + 'db_table': 'publishers', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Rating', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rating', models.IntegerField(blank=True, null=True)), + ], + options={ + 'db_table': 'ratings', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField()), + ], + options={ + 'db_table': 'tags', + 'managed': False, + }, + ), + migrations.DeleteModel( + name='Authors', + ), + migrations.DeleteModel( + name='Books', + ), + migrations.DeleteModel( + name='BooksAuthorsLink', + ), + migrations.DeleteModel( + name='BooksLanguagesLink', + ), + migrations.DeleteModel( + name='BooksPublishersLink', + ), + migrations.DeleteModel( + name='BooksRatingsLink', + ), + migrations.DeleteModel( + name='BooksSeriesLink', + ), + migrations.DeleteModel( + name='BooksTagsLink', + ), + migrations.DeleteModel( + name='Comments', + ), + migrations.DeleteModel( + name='Identifiers', + ), + migrations.DeleteModel( + name='Languages', + ), + migrations.DeleteModel( + name='Publishers', + ), + migrations.DeleteModel( + name='Ratings', + ), + migrations.DeleteModel( + name='Tags', + ), + ] diff --git a/CalibreWebCompanion/library/models.py b/CalibreWebCompanion/library/models.py index 757f43b..81e0aa8 100644 --- a/CalibreWebCompanion/library/models.py +++ b/CalibreWebCompanion/library/models.py @@ -17,7 +17,7 @@ class Author(models.Model): def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('author-detail-view', args=[str(self.id)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.name @@ -27,12 +27,11 @@ class Author(models.Model): db_table = 'authors' - class Comment(models.Model): - book = models.ForeignKey("Book", db_column="book", on_delete=models.CASCADE) + book = models.ForeignKey("Book", db_column="book", + on_delete=models.CASCADE) text = models.TextField() - class Meta: managed = False db_table = 'comments' @@ -41,7 +40,6 @@ class Comment(models.Model): ] - class Data(models.Model): book = models.IntegerField() format = models.TextField() @@ -61,7 +59,7 @@ class Identifier(models.Model): book = models.IntegerField() type = models.TextField() val = models.TextField() - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.val @@ -77,7 +75,7 @@ class Language(models.Model): def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('language-detail-view', args=[str(self.lang_code)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.lang_code @@ -98,12 +96,12 @@ class Publisher(models.Model): through='BookPublisherLink', through_fields=('publisher', 'book'), related_name="released" - ) + ) def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('publisher-detail-view', args=[str(self.id)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.name @@ -118,10 +116,11 @@ class Publisher(models.Model): class Rating(models.Model): rating = models.IntegerField(blank=True, null=True) + def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('rating-detail-view', args=[str(self.id)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return str(self.rating) @@ -138,7 +137,7 @@ class Series(models.Model): def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('series-detail-view', args=[str(self.id)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.name @@ -153,10 +152,11 @@ class Series(models.Model): class Tag(models.Model): name = models.TextField() + def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('tag-detail-view', args=[str(self.id)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.name @@ -193,14 +193,28 @@ class Book(models.Model): Language, through='BookLanguageLink', through_fields=('book', 'lang_code')) + + @property + def language(self): + return self.languages.first() + publishers = models.ManyToManyField( Publisher, through='BookPublisherLink', through_fields=('book', 'publisher')) + + @property + def publisher(self): + return self.publishers.first() + series = models.ManyToManyField( Series, through='BookSeriesLink', through_fields=('book', 'series')) + + @property + def serie(self): + return self.series.first() tags = models.ManyToManyField( Tag, through='BookTagLink', @@ -209,10 +223,15 @@ class Book(models.Model): Rating, through='BookRatingLink', through_fields=('book', 'rating')) + + @property + def rating(self): + return self.rating.first() + def get_absolute_url(self): """Returns the url to access a particular instance of MyModelName.""" return reverse('book-detail-view', args=[str(self.id)]) - + def __str__(self): """String for representing the MyModelName object (in Admin site etc.).""" return self.title diff --git a/CalibreWebCompanion/library/templates/base.html b/CalibreWebCompanion/library/templates/base.html index 9199e18..a167ba6 100644 --- a/CalibreWebCompanion/library/templates/base.html +++ b/CalibreWebCompanion/library/templates/base.html @@ -39,7 +39,7 @@ @@ -49,7 +49,7 @@ @@ -59,7 +59,7 @@ @@ -68,7 +68,7 @@ diff --git a/CalibreWebCompanion/library/templates/library/results.html b/CalibreWebCompanion/library/templates/library/results.html new file mode 100644 index 0000000..849b4c6 --- /dev/null +++ b/CalibreWebCompanion/library/templates/library/results.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} + +{% block content %} +{% load static %} +

Results

+ + + + + + + + + + + {% for book in book_list %} + + + + + + + + {% endfor %} +
TitleAuthorRatingTagsAdded
{{ book.title }}{{book.author_sort}} {% for rating in book.ratings.all %} + {{rating}} + {% endfor %} + + {% for tag in book.tags.all %} + {{tag}}, + {% endfor %} + {{book.timestamp}}
+ + + + + + + +{% endblock %} \ No newline at end of file diff --git a/README.md b/README.md index b0ec19b..3174527 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,16 @@ Set CALIBREPATH to the path of your library `./CalibreWebCompanion` run `./manage.py runserver` -this is in development mode. don't actually use it or release it like this. The debug info it shows is spicy. \ No newline at end of file +this is in development mode. don't actually use it or release it like this. The debug info it shows is spicy. +# Features + +- [x] Books +- [x] navbar with tags, series, authors, etc +- [x] Search +- [x] authentication + + +# TODO + +- [ ] fix author_detail_view with annotate instead of current implementation + \ No newline at end of file