beautified it
This commit is contained in:
parent
73f6937c78
commit
0ab703f8b9
@ -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"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -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'
|
|
19
CalibreWebCompanion/library/context_processors.py
Normal file
19
CalibreWebCompanion/library/context_processors.py
Normal 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
|
||||||
|
}
|
7
CalibreWebCompanion/library/forms.py
Normal file
7
CalibreWebCompanion/library/forms.py
Normal 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)
|
||||||
|
|
@ -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
|
||||||
|
}
|
@ -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>
|
@ -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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 %}
|
@ -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 %}
|
@ -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%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
10
README.md
10
README.md
@ -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.
|
Loading…
Reference in New Issue
Block a user