beautified it

This commit is contained in:
MassiveAtoms 2020-07-08 13:22:37 -03:00
parent 73f6937c78
commit 0ab703f8b9
13 changed files with 342 additions and 349 deletions

View File

@ -65,6 +65,7 @@ TEMPLATES = [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
"library.context_processors.filters"
], ],
}, },
}, },

View File

@ -1,265 +0,0 @@
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models
class Authors(models.Model):
name = models.TextField()
sort = models.TextField(blank=True, null=True)
link = models.TextField()
class Meta:
managed = False
db_table = 'authors'
class Comments(models.Model):
book = models.ForeignField("Book")
text = models.TextField()
class Meta:
managed = False
db_table = 'comments'
class Data(models.Model):
book = models.IntegerField()
format = models.TextField()
uncompressed_size = models.IntegerField()
name = models.TextField()
class Meta:
managed = False
db_table = 'data'
class Identifiers(models.Model):
book = models.IntegerField()
type = models.TextField()
val = models.TextField()
class Meta:
managed = False
db_table = 'identifiers'
class Languages(models.Model):
lang_code = models.TextField()
class Meta:
managed = False
db_table = 'languages'
class Publishers(models.Model):
name = models.TextField()
sort = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'publishers'
class Ratings(models.Model):
rating = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'ratings'
class Series(models.Model):
name = models.TextField()
sort = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'series'
class Tags(models.Model):
name = models.TextField()
class Meta:
managed = False
db_table = 'tags'
class Books(models.Model):
title = models.TextField()
sort = models.TextField(blank=True, null=True)
# This field type is a guess.
timestamp = models.TextField(blank=True, null=True)
# This field type is a guess.
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() # This field type is a guess.
authors = models.ManyToManyField(
Authors,
through='BooksAuthorsLink',
through_fields=('book', 'author'))
languages = models.ManyToManyField(
Languages,
through='BooksLanguagesLink',
through_fields=('book', 'lang_code'))
publishers = models.ManyToManyField(
Publishers,
through='BooksPublishersLink',
through_fields=('book', 'publisher'))
series = models.ManyToManyField(
Series,
through='BooksSeriesLink',
through_fields=('book', 'series'))
tags = models.ManyToManyField(
Tags,
through='BooksTagsLink',
through_fields=('book', 'tag'))
class Meta:
managed = False
db_table = 'books'
class BooksAuthorsLink(models.Model):
book = models.ForeignKey(db_column="book")
author = models.ForeignKey(db_column="author")
class Meta:
managed = False
db_table = 'books_authors_link'
class BooksLanguagesLink(models.Model):
book = models.ForeignKey(db_colum="book")
lang_code = models.ForeignKey(db_column="lang_code")
item_order = models.IntegerField()
class Meta:
managed = False
db_table = 'books_languages_link'
class BooksPublishersLink(models.Model):
book = models.ForeignKey(db_column="book")
publisher = models.ForeignKey(db_column="publisher")
class Meta:
managed = False
db_table = 'books_publishers_link'
# class BooksRatingsLink(models.Model): # TODO add this somehow
# book = models.ForeignKey(db_column="book")
# rating = models.IntegerField()
# class Meta:
# managed = False
# db_table = 'books_ratings_link'
class BooksSeriesLink(models.Model):
book = models.ForeignKey(db_column="book")
series = models.ForeignKey(db_column="series")
class Meta:
managed = False
db_table = 'books_series_link'
class BooksTagsLink(models.Model):
book = models.ForeignKey(db_column="book")
tag = models.ForeignKey(db_column="tag")
class Meta:
managed = False
db_table = 'books_tags_link'
# class BooksPluginData(models.Model):
# book = models.IntegerField()
# name = models.TextField()
# val = models.TextField()
# class Meta:
# managed = False
# db_table = 'books_plugin_data'
# class ConversionOptions(models.Model):
# format = models.TextField()
# book = models.IntegerField(blank=True, null=True)
# data = models.BinaryField()
#
# class Meta:
# managed = False
# db_table = 'conversion_options'
#
# class LibraryId(models.Model):
# uuid = models.TextField()
#
# class Meta:
# managed = False
# db_table = 'library_id'
#
# class CustomColumns(models.Model):
# label = models.TextField()
# name = models.TextField()
# datatype = models.TextField()
# mark_for_delete = models.BooleanField()
# editable = models.BooleanField()
# display = models.TextField()
# is_multiple = models.BooleanField()
# normalized = models.BooleanField()
#
# class Meta:
# managed = False
# db_table = 'custom_columns'
#
# class Preferences(models.Model):
# key = models.TextField()
# val = models.TextField()
#
# class Meta:
# managed = False
# db_table = 'preferences'
#
# class Feeds(models.Model):
# title = models.TextField()
# script = models.TextField()
#
# class Meta:
# managed = False
# db_table = 'feeds'
#
#
# class LastReadPositions(models.Model):
# book = models.IntegerField()
# format = models.TextField()
# user = models.TextField()
# device = models.TextField()
# cfi = models.TextField()
# epoch = models.FloatField()
# pos_frac = models.FloatField()
#
# class Meta:
# managed = False
# db_table = 'last_read_positions'
# class MetadataDirtied(models.Model):
# book = models.IntegerField()
# class Meta:
# managed = False
# db_table = 'metadata_dirtied'

View File

@ -0,0 +1,19 @@
from .models import Authors, Tags, Publishers, Languages, Ratings, Series
def filters(request):
unique_authors = Authors.objects.all().order_by('sort')
unique_tags = Tags.objects.all().order_by('name')
unique_publishers = Publishers.objects.all().order_by('name')
unique_languages = Languages.objects.all()
unique_ratings = Ratings.objects.all().order_by('rating')
unique_series = Series.objects.all().order_by('sort')
return {
"unique_authors": unique_authors,
"unique_tags": unique_tags,
"unique_publishers": unique_publishers,
"unique_languages": unique_languages,
"unique_ratings": unique_ratings,
"unique_series": unique_series
}

View File

@ -0,0 +1,7 @@
from django import forms
class SearchForm(forms.Form):
title = forms.CharField(label="Title", max_length=200)
author = forms.CharField(label='Author', max_length=100)
# identifier = forms.CharField(label='Identifier(ISBN, Google-id, amazon id)', max_length=20)

View File

@ -55,4 +55,24 @@
.fa-caret-down { .fa-caret-down {
float: right; float: right;
padding-right: 8px; padding-right: 8px;
} }
table {
border-spacing: 0;
width: 100%;
border: 1px solid #ddd;
}
th {
cursor: pointer;
}
th, td {
text-align: left;
padding: 16px;
}
tr:nth-child(even) {
background-color: #f2f2f2
}

View File

@ -1,55 +1,142 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
{% block title %}<title>Local Library</title>{% endblock %} {% block title %}<title>Local Library</title>{% endblock %}
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<!-- Add additional CSS in static file --> <!-- Add additional CSS in static file -->
{% load static %} {% load static %}
<link rel="stylesheet" href="{% static 'css/styles.css' %}"> <link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head> </head>
<body> <body>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-sm-2"> <div class="col-sm-2">
{% block sidebar %} {% block sidebar %}
<div class="sidenav"> <div class="sidenav">
<a href="{% url 'books' %}">Books</a> <a href="{% url 'books' %}">Books</a>
<a href="{% url 'authors' %}">Authors</a> <button class="dropdown-btn">Authors
<a href="{% url 'publishers' %}">Publishers</a> <i class="fa fa-caret-down"></i>
<a href="{% url 'ratings' %}">Ratings</a> </button>
<button class="dropdown-btn">Tags <div class="dropdown-container">
<i class="fa fa-caret-down"></i> {% for author in unique_authors %}
</button> <a href="{{author.get_absolute_url}}">{{author}}</a>
<div class="dropdown-container">
{% for tag in tag_list %} {% endfor %}
<a href="{{tag.get_absolute_url}}">{{tag}}</a> </div>
{% endfor %} <button class="dropdown-btn">Publishers
<a href="#">doesnt work </a> <i class="fa fa-caret-down"></i>
</div> </button>
</div> <div class="dropdown-container">
{% endblock %} {% for publisher in unique_publishers %}
<a href="{{publisher.get_absolute_url}}">{{publisher}}</a>
{% endfor %}
</div>
<button class="dropdown-btn">Ratings
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-container">
{% for rating in unique_ratings %}
<a href="{{rating.get_absolute_url}}">{{rating}}</a>
{% endfor %}
</div>
<button class="dropdown-btn">Tags
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-container">
{% for tag in unique_tags %}
<a href="{{tag.get_absolute_url}}">{{tag}}</a>
{% endfor %}
</div>
</div>
{% endblock %}
</div> </div>
<div class="col-sm-10 ">{% block content %}{% endblock %}</div> <div class="col-sm-10 ">{% block content %}{% endblock %}</div>
</div> </div>
</div> </div>
<script> <script>
var dropdown = document.getElementsByClassName("dropdown-btn"); var dropdown = document.getElementsByClassName("dropdown-btn");
var i; var i;
for (i = 0; i < dropdown.length; i++) { for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() { dropdown[i].addEventListener("click", function () {
this.classList.toggle("active"); this.classList.toggle("active");
var dropdownContent = this.nextElementSibling; var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") { if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none"; dropdownContent.style.display = "none";
} else { } else {
dropdownContent.style.display = "block"; dropdownContent.style.display = "block";
}
});
}
</script>
<script>
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("books");
switching = true;
// Set the sorting direction to ascending:
dir = "asc";
/* Make a loop that will continue until
no switching has been done: */
while (switching) {
// Start by saying: no switching is done:
switching = false;
rows = table.rows;
/* Loop through all table rows (except the
first, which contains table headers): */
for (i = 1; i < (rows.length - 1); i++) {
// Start by saying there should be no switching:
shouldSwitch = false;
/* Get the two elements you want to compare,
one from current row and one from the next: */
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/* Check if the two rows should switch place,
based on the direction, asc or desc: */
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
/* If a switch has been marked, make the switch
and mark that a switch has been done: */
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
// Each time a switch is done, increase this count by 1:
switchcount++;
} else {
/* If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again. */
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
} }
});
}
</script> </script>
</body> </body>
</html> </html>

View File

@ -3,15 +3,33 @@
{% block content %} {% block content %}
{% load static %} {% load static %}
<h1>{{authors}}</h1> <h1>{{authors}}</h1>
{% if books %}
<ul>
{% for book in books %}
<li><a href="{{book.get_absolute_url}}">{{book.title}}</a></li> <table id="books">
{%endfor%} <tr>
</ul> <!--When a header is clicked, run the sortTable function, with a parameter, 0 for sorting by names, 1 for sorting by country:-->
{% else %} <th onclick="sortTable(0)">Title</th>
{%endif%} <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 books %}
<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>

View File

@ -2,16 +2,39 @@
{% block content %} {% block content %}
{% load static %} {% load static %}
<h1>Book List</h1> <h1>Book List</h1>
{% if books_list %}
<ul> <table id="books">
{% for book in books_list %} <tr>
<li> <!--When a header is clicked, run the sortTable function, with a parameter, 0 for sorting by names, 1 for sorting by country:-->
<a href="{{ book.get_absolute_url }}">{{ book.title }}</a> ({{book.author_sort}}) <th onclick="sortTable(0)">Title</th>
</li> <th onclick="sortTable(1)">Author</th>
{% endfor %} <th onclick="sortTable(2)">Rating</th>
</ul> <th onclick="sortTable(3)">Tags</th>
{% else %} <th onclick="sortTable(4)">Added</th>
<p>There are no books in the library.</p> </tr>
{% endif %} {% for book in books_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 %} {% endblock %}

View File

@ -2,17 +2,37 @@
{% block content %} {% block content %}
{% load static %} {% load static %}
<h1>{{authors}} </h1> <h1>{{publishers}} </h1>
{% if publishers.released %} {% if publishers.released %}
<ul> <table id="books">
{% for book in publishers.released.all %} <tr>
<!--When a header is clicked, run the sortTable function, with a parameter, 0 for sorting by names, 1 for sorting by country:-->
<li><a href="{{book.get_absolute_url}}">{{book.title}}</a></li> <th onclick="sortTable(0)">Title</th>
{%endfor%} <th onclick="sortTable(1)">Author</th>
</ul> <th onclick="sortTable(2)">Rating</th>
{% else %} <th onclick="sortTable(3)">Tags</th>
{%endif%} <th onclick="sortTable(4)">Added</th>
</tr>
{% for book in publishers.released.all %}
<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>
{% else %}
{%endif%}
{% endblock %} {% endblock %}

View File

@ -4,15 +4,35 @@
{% load static %} {% load static %}
<h1>{{ratings}}</h1> <h1>{{ratings}}</h1>
{% if books %} {% if books %}
<ul> <table id="books">
{% for book in books %} <tr>
<!--When a header is clicked, run the sortTable function, with a parameter, 0 for sorting by names, 1 for sorting by country:-->
<li><a href="{{book.get_absolute_url}}">{{book.title}}</a></li> <th onclick="sortTable(0)">Title</th>
{%endfor%} <th onclick="sortTable(1)">Author</th>
</ul> <th onclick="sortTable(2)">Rating</th>
{% else %} <th onclick="sortTable(3)">Tags</th>
{%endif%} <th onclick="sortTable(4)">Added</th>
</tr>
{% for book in books %}
<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>
{% else %}
{%endif%}

View File

@ -4,15 +4,35 @@
{% load static %} {% load static %}
<h1>{{tags}}</h1> <h1>{{tags}}</h1>
{% if books %} {% if books %}
<ul> <table id="books">
{% for book in books %} <tr>
<!--When a header is clicked, run the sortTable function, with a parameter, 0 for sorting by names, 1 for sorting by country:-->
<li><a href="{{book.get_absolute_url}}">{{book.title}}</a></li> <th onclick="sortTable(0)">Title</th>
{%endfor%} <th onclick="sortTable(1)">Author</th>
</ul> <th onclick="sortTable(2)">Rating</th>
{% else %} <th onclick="sortTable(3)">Tags</th>
{%endif%} <th onclick="sortTable(4)">Added</th>
</tr>
{% for book in books %}
<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>
{% else %}
{%endif%}

View File

@ -1,8 +1,31 @@
from django.shortcuts import render from django.shortcuts import render
from django.views import generic from django.views import generic
from .models import Authors, Books, Comments, Ratings, BooksAuthorsLink, Publishers, Tags, BooksTagsLink, BooksRatingsLink, Data from .models import Authors, Books, Comments, Ratings, BooksAuthorsLink, Publishers, Tags, BooksTagsLink, BooksRatingsLink, Data
from django.http import HttpResponseRedirect
# from .forms import SearchForms
# def get_results(request): # TODO this might not be what i want
# # if this is a POST request we need to process the form data
# if request.method == 'POST':
# # create a form instance and populate it with data from the request:
# form = SearchForm(request.POST)
# # check whether it's valid:
# if form.is_valid():
# books = Books.objects.all()
# if form.title:
# books.filter(sort_icontains=form.title)
# if form.author:
# books.filter(author_sort_icontains=form.author)
# return HttpResponseRedirect('/results/')
# # if a GET (or any other method) we'll create a blank form
# else:
# form = NameForm()
# return render(request, 'name.html', {'form': form})
class AuthorListView(generic.ListView): class AuthorListView(generic.ListView):
model = Authors model = Authors

View File

@ -2,9 +2,9 @@
Django 3.0 Django 3.0
# how to use: # how to use:
Edit `./CalibreWebCompanion/CalibreWebCompanion/settings`. Edit `./CalibreWebCompanion/CalibreWebCompanion/settings`.
Set CALIBREPATH to the path of your library 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.