did some optimisation

This commit is contained in:
MassiveAtoms 2020-07-11 14:56:22 -03:00
parent c00b2b0e52
commit 58d4f27c61
9 changed files with 439 additions and 31 deletions

View File

@ -78,11 +78,11 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
"library", "library",
# 'debug_toolbar', # DEBUG purposes 'debug_toolbar', # DEBUG purposes
] ]
MIDDLEWARE = [ MIDDLEWARE = [
# 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',

View File

@ -30,8 +30,8 @@ urlpatterns = [
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
# if settings.DEBUG: # DEBUG purposes if settings.DEBUG: # DEBUG purposes
# import debug_toolbar import debug_toolbar
# urlpatterns = [ urlpatterns = [
# path('__debug__/', include(debug_toolbar.urls)), path('__debug__/', include(debug_toolbar.urls)),
# ] + urlpatterns ] + urlpatterns

View File

@ -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)

View File

@ -1,13 +1,22 @@
from .models import Author, Tag, Publisher, Language, Rating, Series from .models import Author, Tag, Publisher, Language, Rating, Series
from django.db.models import Count
def filters(request): def filters(request):
unique_authors = Author.objects.all().order_by('sort') # unique_authors = Author.objects.all().order_by('sort')
unique_tags = Tag.objects.all().order_by('name') # unique_tags = Tag.objects.all().order_by('name')
unique_publishers = Publisher.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_ratings = Rating.objects.all().order_by('rating') # unique_languages = Language.objects.all()
unique_series = Series.objects.all().order_by('sort') # 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 { return {
"unique_authors": unique_authors, "unique_authors": unique_authors,

View File

@ -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',
),
]

View File

@ -17,7 +17,7 @@ class Author(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('author-detail-view', args=[str(self.id)]) return reverse('author-detail-view', args=[str(self.id)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.name return self.name
@ -27,12 +27,11 @@ class Author(models.Model):
db_table = 'authors' db_table = 'authors'
class Comment(models.Model): 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() text = models.TextField()
class Meta: class Meta:
managed = False managed = False
db_table = 'comments' db_table = 'comments'
@ -41,7 +40,6 @@ class Comment(models.Model):
] ]
class Data(models.Model): class Data(models.Model):
book = models.IntegerField() book = models.IntegerField()
format = models.TextField() format = models.TextField()
@ -61,7 +59,7 @@ class Identifier(models.Model):
book = models.IntegerField() book = models.IntegerField()
type = models.TextField() type = models.TextField()
val = models.TextField() val = models.TextField()
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.val return self.val
@ -77,7 +75,7 @@ class Language(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('language-detail-view', args=[str(self.lang_code)]) return reverse('language-detail-view', args=[str(self.lang_code)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.lang_code return self.lang_code
@ -98,12 +96,12 @@ class Publisher(models.Model):
through='BookPublisherLink', through='BookPublisherLink',
through_fields=('publisher', 'book'), through_fields=('publisher', 'book'),
related_name="released" related_name="released"
) )
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('publisher-detail-view', args=[str(self.id)]) return reverse('publisher-detail-view', args=[str(self.id)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.name return self.name
@ -118,10 +116,11 @@ class Publisher(models.Model):
class Rating(models.Model): class Rating(models.Model):
rating = models.IntegerField(blank=True, null=True) rating = models.IntegerField(blank=True, null=True)
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('rating-detail-view', args=[str(self.id)]) return reverse('rating-detail-view', args=[str(self.id)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return str(self.rating) return str(self.rating)
@ -138,7 +137,7 @@ class Series(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('series-detail-view', args=[str(self.id)]) return reverse('series-detail-view', args=[str(self.id)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.name return self.name
@ -153,10 +152,11 @@ class Series(models.Model):
class Tag(models.Model): class Tag(models.Model):
name = models.TextField() name = models.TextField()
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('tag-detail-view', args=[str(self.id)]) return reverse('tag-detail-view', args=[str(self.id)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.name return self.name
@ -193,14 +193,28 @@ class Book(models.Model):
Language, Language,
through='BookLanguageLink', through='BookLanguageLink',
through_fields=('book', 'lang_code')) through_fields=('book', 'lang_code'))
@property
def language(self):
return self.languages.first()
publishers = models.ManyToManyField( publishers = models.ManyToManyField(
Publisher, Publisher,
through='BookPublisherLink', through='BookPublisherLink',
through_fields=('book', 'publisher')) through_fields=('book', 'publisher'))
@property
def publisher(self):
return self.publishers.first()
series = models.ManyToManyField( series = models.ManyToManyField(
Series, Series,
through='BookSeriesLink', through='BookSeriesLink',
through_fields=('book', 'series')) through_fields=('book', 'series'))
@property
def serie(self):
return self.series.first()
tags = models.ManyToManyField( tags = models.ManyToManyField(
Tag, Tag,
through='BookTagLink', through='BookTagLink',
@ -209,10 +223,15 @@ class Book(models.Model):
Rating, Rating,
through='BookRatingLink', through='BookRatingLink',
through_fields=('book', 'rating')) through_fields=('book', 'rating'))
@property
def rating(self):
return self.rating.first()
def get_absolute_url(self): def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName.""" """Returns the url to access a particular instance of MyModelName."""
return reverse('book-detail-view', args=[str(self.id)]) return reverse('book-detail-view', args=[str(self.id)])
def __str__(self): def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.).""" """String for representing the MyModelName object (in Admin site etc.)."""
return self.title return self.title

View File

@ -39,7 +39,7 @@
</button> </button>
<div class="dropdown-container"> <div class="dropdown-container">
{% for author in unique_authors %} {% for author in unique_authors %}
<a href="{{author.get_absolute_url}}">{{author}}</a> <a href="{{author.get_absolute_url}}">{{author.name}}({{author.num_books}})</a>
{% endfor %} {% endfor %}
</div> </div>
@ -49,7 +49,7 @@
</button> </button>
<div class="dropdown-container"> <div class="dropdown-container">
{% for publisher in unique_publishers %} {% for publisher in unique_publishers %}
<a href="{{publisher.get_absolute_url}}">{{publisher}}</a> <a href="{{publisher.get_absolute_url}}">{{publisher}} ({{publisher.num_books}})</a>
{% endfor %} {% endfor %}
</div> </div>
@ -59,7 +59,7 @@
</button> </button>
<div class="dropdown-container"> <div class="dropdown-container">
{% for rating in unique_ratings %} {% for rating in unique_ratings %}
<a href="{{rating.get_absolute_url}}">{{rating}}</a> <a href="{{rating.get_absolute_url}}">{{rating}} ({{rating.num_books}})</a>
{% endfor %} {% endfor %}
</div> </div>
@ -68,7 +68,7 @@
</button> </button>
<div class="dropdown-container"> <div class="dropdown-container">
{% for tag in unique_tags %} {% for tag in unique_tags %}
<a href="{{tag.get_absolute_url}}">{{tag}}</a> <a href="{{tag.get_absolute_url}}">{{tag}} ({{tag.num_books}})</a>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -0,0 +1,40 @@
{% extends "base.html" %}
{% block content %}
{% load static %}
<h1>Results</h1>
<table id="books">
<tr>
<!--When a header is clicked, run the sortTable function, with a parameter, 0 for sorting by names, 1 for sorting by country:-->
<th onclick="sortTable(0)">Title</th>
<th onclick="sortTable(1)">Author</th>
<th onclick="sortTable(2)">Rating</th>
<th onclick="sortTable(3)">Tags</th>
<th onclick="sortTable(4)">Added</th>
</tr>
{% for book in book_list %}
<tr>
<td><a href="{{ book.get_absolute_url }}">{{ book.title }}</a></td>
<td>{{book.author_sort}}</td>
<td> {% for rating in book.ratings.all %}
{{rating}}
{% endfor %}
</td>
<td>
{% for tag in book.tags.all %}
{{tag}},
{% endfor %}
</td>
<td>{{book.timestamp}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@ -7,4 +7,16 @@ Set CALIBREPATH to the path of your library
`./CalibreWebCompanion` `./CalibreWebCompanion`
run `./manage.py runserver` 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. 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