mirror of
https://github.com/th3r00t/pyShelf.git
synced 2026-04-28 01:59:35 -04:00
Merge pull request #47 from th3r00t/newui
Pull user system into development
This commit is contained in:
@@ -114,7 +114,6 @@ class Storage:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def make_collections(self):
|
def make_collections(self):
|
||||||
breakpoint()
|
|
||||||
_title_regx = re.compile(r"^[0-9][0-9]*|-|\ \B")
|
_title_regx = re.compile(r"^[0-9][0-9]*|-|\ \B")
|
||||||
_q = "SELECT id,file_name FROM books"
|
_q = "SELECT id,file_name FROM books"
|
||||||
self.cursor.execute(_q)
|
self.cursor.execute(_q)
|
||||||
@@ -123,8 +122,11 @@ class Storage:
|
|||||||
path = self.config.book_path + "/"
|
path = self.config.book_path + "/"
|
||||||
_collections = []
|
_collections = []
|
||||||
_pathing = book[1].split(path)[1].split("/")
|
_pathing = book[1].split(path)[1].split("/")
|
||||||
_pathing.pop(0)
|
try:
|
||||||
_pathing.pop(-1)
|
_pathing.pop(0)
|
||||||
|
_pathing.pop(-1)
|
||||||
|
except IndexError:
|
||||||
|
continue
|
||||||
for _p in _pathing:
|
for _p in _pathing:
|
||||||
_s = _p.replace("'", "")
|
_s = _p.replace("'", "")
|
||||||
_x = re.sub(_title_regx, "", _s)
|
_x = re.sub(_title_regx, "", _s)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ INSTALLED_APPS = [
|
|||||||
"interface.templatetags",
|
"interface.templatetags",
|
||||||
"debug_toolbar",
|
"debug_toolbar",
|
||||||
]
|
]
|
||||||
|
AUTH_USER_MODEL = "interface.CustomUser"
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
@@ -135,6 +135,6 @@ USE_TZ = True
|
|||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||||
|
LOGIN_REDIRECT_URL = 'home'
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = "/static/"
|
||||||
STATIC_ROOT = os.path.join(BASE_DIR, "interface/static/")
|
STATIC_ROOT = os.path.join(BASE_DIR, "interface/static/")
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ Including another URLconf
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path, re_path
|
from django.urls import include, path, re_path
|
||||||
|
from django.contrib.auth import views as auth_views
|
||||||
from interface import views
|
from interface import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("", views.index, name="index"),
|
path("", views.index, name="index"),
|
||||||
path("home", views.home, name="index"),
|
path("home", views.home, name="home"),
|
||||||
path("sort/<_order>", views.index, name="index"),
|
path("sort/<_order>", views.index, name="index"),
|
||||||
path("flip_sort/<_order>", views.flip_sort, name="index"),
|
path("flip_sort/<_order>", views.flip_sort, name="index"),
|
||||||
path("download/<pk>", views.download, name="download"),
|
path("download/<pk>", views.download, name="download"),
|
||||||
@@ -35,7 +36,30 @@ urlpatterns = [
|
|||||||
path("search/", views.index, name="search"),
|
path("search/", views.index, name="search"),
|
||||||
path("search/<query>", views.index, name="search"),
|
path("search/<query>", views.index, name="search"),
|
||||||
path("search/<query>/<_set>", views.index, name="search"),
|
path("search/<query>/<_set>", views.index, name="search"),
|
||||||
path("show_collection/<_collection>/<_colset>", views.show_collection, name="show_collection",),
|
path("show_collection/<_collection>/<_colset>", views.show_collection, name="show_collection"),
|
||||||
|
path("signup", views.signup, name="signup"),
|
||||||
|
path("login", views.userlogin, name="login"),
|
||||||
|
path('logout', views.userlogout, name='logout'),
|
||||||
|
path(
|
||||||
|
'admin/password_reset/',
|
||||||
|
auth_views.PasswordResetView.as_view(),
|
||||||
|
name='admin_password_reset',
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'admin/password_reset/done/',
|
||||||
|
auth_views.PasswordResetDoneView.as_view(),
|
||||||
|
name='password_reset_done',
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'reset/<uidb64>/<token>/',
|
||||||
|
auth_views.PasswordResetConfirmView.as_view(),
|
||||||
|
name='password_reset_confirm',
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'reset/done/',
|
||||||
|
auth_views.PasswordResetCompleteView.as_view(),
|
||||||
|
name='password_reset_complete',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
import debug_toolbar
|
import debug_toolbar
|
||||||
|
|||||||
@@ -1,6 +1,30 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
|
||||||
|
from .models import Books, Collections, Favorites, Navigation, CustomUser
|
||||||
|
from .forms import CustomUserCreationForm, CustomUserChangeForm
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUserAdmin(UserAdmin):
|
||||||
|
model = CustomUser
|
||||||
|
add_form = CustomUserCreationForm
|
||||||
|
form = CustomUserChangeForm
|
||||||
|
list_display = ["email", "username", "facebook", "twitter", "sponsorid", "matrixid"]
|
||||||
|
fieldsets = UserAdmin.fieldsets + (
|
||||||
|
(None, {"fields": ()}),
|
||||||
|
("Personal info", {"fields": ("facebook", "twitter", "matrixid")}),
|
||||||
|
("Permissions", {"fields": ("sponsorid",)}),
|
||||||
|
)
|
||||||
|
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
|
||||||
|
# overrides get_fieldsets to use this attribute when creating a user.
|
||||||
|
add_fieldsets = UserAdmin.add_fieldsets + (
|
||||||
|
(None, {"classes": ("wide",), "fields": ("facebook", "twitter", "sponsorid", "matrixid")},),
|
||||||
|
)
|
||||||
|
|
||||||
from .models import Books
|
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
admin.site.register(Books)
|
admin.site.register(Books)
|
||||||
|
admin.site.register(Collections)
|
||||||
|
admin.site.register(Favorites)
|
||||||
|
admin.site.register(Navigation)
|
||||||
|
admin.site.register(CustomUser, CustomUserAdmin)
|
||||||
|
|||||||
37
src/interface/forms.py
Normal file
37
src/interface/forms.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, AuthenticationForm
|
||||||
|
from .models import CustomUser
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUserCreationForm(UserCreationForm):
|
||||||
|
class Meta:
|
||||||
|
model = CustomUser
|
||||||
|
fields = ("username", "email", "facebook", "twitter", "sponsorid", "matrixid")
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUserChangeForm(UserChangeForm):
|
||||||
|
class Meta:
|
||||||
|
model = CustomUser
|
||||||
|
fields = ("username", "email", "facebook", "twitter", "sponsorid", "matrixid")
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUserLoginForm(AuthenticationForm):
|
||||||
|
class Meta:
|
||||||
|
Model = CustomUser
|
||||||
|
fields = ("username", "password")
|
||||||
|
|
||||||
|
|
||||||
|
class SignUpForm(CustomUserCreationForm):
|
||||||
|
username = forms.CharField(max_length=30, required=False, help_text='Required.')
|
||||||
|
email = forms.EmailField(max_length=254, help_text='Not yet required, as I\'m still deciding how to handle mail')
|
||||||
|
matrixid = forms.CharField(max_length=30, required=False, help_text='Optional.')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = CustomUser
|
||||||
|
fields = ("username", "email", "matrixid")
|
||||||
|
|
||||||
|
|
||||||
|
class UserLoginForm(CustomUserLoginForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = CustomUser
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
from django.contrib.postgres.search import SearchVector
|
from django.contrib.postgres.search import SearchVector
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import AbstractUser
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
@@ -40,12 +42,13 @@ class Books(models.Model):
|
|||||||
def generic_search(self, query):
|
def generic_search(self, query):
|
||||||
try:
|
try:
|
||||||
results = Books.objects.annotate(
|
results = Books.objects.annotate(
|
||||||
search=SearchVector("title", "file_name", "author","tags"),
|
search=SearchVector("title", "file_name", "author", "tags"),
|
||||||
).filter(search=query)
|
).filter(search=query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise
|
raise
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
class Collections(models.Model):
|
class Collections(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "collections"
|
db_table = "collections"
|
||||||
@@ -69,6 +72,7 @@ class Collections(models.Model):
|
|||||||
raise
|
raise
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
class Navigation(models.Model):
|
class Navigation(models.Model):
|
||||||
"""
|
"""
|
||||||
pyShelfs Navigation Database class
|
pyShelfs Navigation Database class
|
||||||
@@ -105,38 +109,6 @@ class Navigation(models.Model):
|
|||||||
raise
|
raise
|
||||||
return results
|
return results
|
||||||
|
|
||||||
class Users(models.Model):
|
|
||||||
"""
|
|
||||||
pyShelfs User Database class
|
|
||||||
:param uname: User Name
|
|
||||||
:param fname: First Name
|
|
||||||
:param lname: Last Name
|
|
||||||
:param email: User Email Address
|
|
||||||
:param password: User Password
|
|
||||||
:param ulvl: User Level
|
|
||||||
"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = "users"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
uname = models.CharField(max_length=255)
|
|
||||||
fname = models.CharField(max_length=255, null=True)
|
|
||||||
lname = models.CharField(max_length=255, null=True)
|
|
||||||
email = models.CharField(max_length=255, null=True, editable=True)
|
|
||||||
password = models.CharField(max_length=255, null=True)
|
|
||||||
ulvl = models.IntegerField(null=True)
|
|
||||||
|
|
||||||
def generic_search(self, query):
|
|
||||||
try:
|
|
||||||
results = Users.objects.annotate(
|
|
||||||
search=SearchVector("uname", "email", "lname"),
|
|
||||||
).filter(search=query)
|
|
||||||
except Exception as e:
|
|
||||||
raise
|
|
||||||
return results
|
|
||||||
|
|
||||||
class Favorites(models.Model):
|
class Favorites(models.Model):
|
||||||
"""
|
"""
|
||||||
@@ -152,7 +124,7 @@ class Favorites(models.Model):
|
|||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
favorite = models.ManyToManyField(Books)
|
favorite = models.ManyToManyField(Books)
|
||||||
uname = models.ManyToManyField(Users)
|
uname = models.ManyToManyField(settings.AUTH_USER_MODEL)
|
||||||
|
|
||||||
def generic_search(self, query):
|
def generic_search(self, query):
|
||||||
try:
|
try:
|
||||||
@@ -162,3 +134,11 @@ class Favorites(models.Model):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise
|
raise
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUser(AbstractUser):
|
||||||
|
facebook = models.CharField(max_length=255, null=True)
|
||||||
|
twitter = models.CharField(max_length=255, null=True)
|
||||||
|
ulvl = models.IntegerField(default=1)
|
||||||
|
sponsorid = models.IntegerField(null=True)
|
||||||
|
matrixid = models.CharField(max_length=255, null=True)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
dfqqyn*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */
|
||||||
|
|
||||||
(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Παρακαλώ διαγράψτε "+t+" χαρακτήρ";return t==1&&(n+="α"),t!=1&&(n+="ες"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Παρακαλώ συμπληρώστε "+t+" ή περισσότερους χαρακτήρες";return n},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(e){var t="Μπορείτε να επιλέξετε μόνο "+e.maximum+" επιλογ";return e.maximum==1&&(t+="ή"),e.maximum!=1&&(t+="ές"),t},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),{define:e.define,require:e.require}})();
|
(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Παρακαλώ διαγράψτε "+t+" χαρακτήρ";return t==1&&(n+="α"),t!=1&&(n+="ες"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Παρακαλώ συμπληρώστε "+t+" ή περισσότερους χαρακτήρες";return n},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(e){var t="Μπορείτε να επιλέξετε μόνο "+e.maximum+" επιλογ";return e.maximum==1&&(t+="ή"),e.maximum!=1&&(t+="ές"),t},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),{define:e.define,require:e.require}})();
|
||||||
|
|||||||
BIN
src/interface/static/img/inspectocat.jpg
vendored
Normal file
BIN
src/interface/static/img/inspectocat.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
22
src/interface/templates/index.html
vendored
22
src/interface/templates/index.html
vendored
@@ -26,12 +26,6 @@
|
|||||||
<input type="hidden" id="_search" name="_search" value="{{ PostedSearch }}" />
|
<input type="hidden" id="_search" name="_search" value="{{ PostedSearch }}" />
|
||||||
<input type="hidden" id="_order" name="_order" value="{{ Order }}" />
|
<input type="hidden" id="_order" name="_order" value="{{ Order }}" />
|
||||||
<div id="pop_over_0">
|
<div id="pop_over_0">
|
||||||
<!-- Login Form -->
|
|
||||||
<div class="hdr_nav" id="hdr_nav_login">
|
|
||||||
<input id="username" class="nav_login input_box noborder" type="text" size="8" value="Username">
|
|
||||||
<input id="password" class="nav_login input_box noborder" type="text" size="8" value="Password">
|
|
||||||
</div>
|
|
||||||
<!-- End Login Form -->
|
|
||||||
</div>
|
</div>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<ul id="shelf_nav">
|
<ul id="shelf_nav">
|
||||||
@@ -43,10 +37,16 @@
|
|||||||
<li class="nav_menu_tab"><i class="fas fa-layer-group"></i> Collections</li>
|
<li class="nav_menu_tab"><i class="fas fa-layer-group"></i> Collections</li>
|
||||||
<li class="nav_menu_tab"><i class="fas fa-star"></i> Favorites</li>
|
<li class="nav_menu_tab"><i class="fas fa-star"></i> Favorites</li>
|
||||||
<li class="nav_menu_tab"><i class="fas fa-bug"></i> Bug report</li>
|
<li class="nav_menu_tab"><i class="fas fa-bug"></i> Bug report</li>
|
||||||
<li class="nav_menu_tab" id="btn_login"> <i class="fa fa-user-circle" aria-hidden="true"></i> Login</li>
|
<li class="nav_menu_tab" id="btn_login"> <i class="fa fa-user-circle" aria-hidden="true"></i>
|
||||||
</div>
|
{% if request.user.is_authenticated %}
|
||||||
</div>
|
<a href='logout' class='nav_link'> {{ request.user }}</a>
|
||||||
<div id="horiz_nav_main">
|
{% else %}
|
||||||
|
<a href="login" class='nav_link'> Login</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="horiz_nav_main">
|
||||||
<div id="horiz_nav_left">
|
<div id="horiz_nav_left">
|
||||||
<i class="fas fa-arrow-circle-left nav_icon prev_page" onclick="window.location.href = '/prev_page/{{ Set }}/{{ Order }}'"></i>
|
<i class="fas fa-arrow-circle-left nav_icon prev_page" onclick="window.location.href = '/prev_page/{{ Set }}/{{ Order }}'"></i>
|
||||||
sort <i class="fas fa-sort nav_icon"></i>
|
sort <i class="fas fa-sort nav_icon"></i>
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
{% elif book.description == None %}
|
{% elif book.description == None %}
|
||||||
<li class="book_description">
|
<li class="book_description">
|
||||||
<div class="inline_sys_message">
|
<div class="inline_sys_message">
|
||||||
We were unable to find a description in this books metadata.
|
We were unable to find a description.
|
||||||
<br />Have some <i class="fas fa-drumstick-bite"></i> instead?
|
<br />Have some <i class="fas fa-drumstick-bite"></i> instead?
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
23
src/interface/templates/login.html
vendored
Normal file
23
src/interface/templates/login.html
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
<div class="fieldWrapper">
|
||||||
|
{{ field.errors }}
|
||||||
|
{{ field.label_tag }} {{ field }}
|
||||||
|
{% if field.help_text %}
|
||||||
|
<p class="help">{{ field.help_text|safe }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
22
src/interface/templates/registration/login.html
vendored
Normal file
22
src/interface/templates/registration/login.html
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form method="post">
|
||||||
|
{% for field in form %}
|
||||||
|
<div class="fieldWrapper">
|
||||||
|
{{ field.errors }}
|
||||||
|
{{ field.label_tag }} {{ field }}
|
||||||
|
{% if field.help_text %}
|
||||||
|
<p class="help">{{ field.help_text|safe }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
26
src/interface/templates/signup.html
vendored
Normal file
26
src/interface/templates/signup.html
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Sign up</h2>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
<p>
|
||||||
|
{{ field.label_tag }}<br>
|
||||||
|
{{ field }}
|
||||||
|
{% if field.help_text %}
|
||||||
|
<small style="color: grey">{{ field.help_text }}</small>
|
||||||
|
{% endif %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<p style="color: red">{{ error }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Sign up</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import json
|
|
||||||
import os
|
import os
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -6,11 +5,13 @@ from pathlib import Path
|
|||||||
from backend.lib.config import Config
|
from backend.lib.config import Config
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from django.shortcuts import HttpResponse, render # render_to_response
|
from django.shortcuts import HttpResponse, render, redirect # render_to_response
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
from django.contrib.auth import login, authenticate, logout
|
||||||
|
from django.contrib.auth.models import User
|
||||||
import json
|
import json
|
||||||
|
from .forms import SignUpForm, UserLoginForm
|
||||||
from .models import Books, Collections, Navigation
|
from .models import Books, Collections, Navigation, Favorites
|
||||||
|
|
||||||
config = Config(Path("../"))
|
config = Config(Path("../"))
|
||||||
|
|
||||||
@@ -28,6 +29,40 @@ def index(request, query=None, _set=1, _limit=None, _order='title'):
|
|||||||
_payload
|
_payload
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def signup(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = SignUpForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
username = form.cleaned_data.get('username')
|
||||||
|
raw_password = form.cleaned_data.get('password1')
|
||||||
|
user = authenticate(username=username, password=raw_password)
|
||||||
|
login(request, user)
|
||||||
|
return redirect('home')
|
||||||
|
else:
|
||||||
|
form = SignUpForm()
|
||||||
|
return render(request, 'signup.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
def userlogin(request):
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
username = request.POST['username']
|
||||||
|
password = request.POST['password']
|
||||||
|
user = authenticate(request, username=username, password=password)
|
||||||
|
if user is not None:
|
||||||
|
login(request, user)
|
||||||
|
return redirect('home')
|
||||||
|
form = UserLoginForm()
|
||||||
|
return render(request, 'login.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
def userlogout(request):
|
||||||
|
logout(request)
|
||||||
|
return redirect('home')
|
||||||
|
|
||||||
|
|
||||||
def home(request, query=None, _set=1, _limit=None, _order='title'):
|
def home(request, query=None, _set=1, _limit=None, _order='title'):
|
||||||
"""
|
"""
|
||||||
Reset Search Queries & Return Home
|
Reset Search Queries & Return Home
|
||||||
@@ -38,6 +73,8 @@ def home(request, query=None, _set=1, _limit=None, _order='title'):
|
|||||||
"index.html",
|
"index.html",
|
||||||
_payload
|
_payload
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def show_collection(request, _collection, _colset):
|
def show_collection(request, _collection, _colset):
|
||||||
try:
|
try:
|
||||||
_set = int(_colset) + 1
|
_set = int(_colset) + 1
|
||||||
@@ -60,6 +97,7 @@ def show_collection(request, _collection, _colset):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def flip_sort(request, bookset=1, query=None, _limit=None, _order='title'):
|
def flip_sort(request, bookset=1, query=None, _limit=None, _order='title'):
|
||||||
"""
|
"""
|
||||||
Goto next page in bookset
|
Goto next page in bookset
|
||||||
@@ -73,6 +111,7 @@ def flip_sort(request, bookset=1, query=None, _limit=None, _order='title'):
|
|||||||
_payload,
|
_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def next_page(request, bookset, query=None, _limit=None, _order='title'):
|
def next_page(request, bookset, query=None, _limit=None, _order='title'):
|
||||||
"""
|
"""
|
||||||
Goto next page in bookset
|
Goto next page in bookset
|
||||||
@@ -88,6 +127,7 @@ def next_page(request, bookset, query=None, _limit=None, _order='title'):
|
|||||||
_payload,
|
_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def prev_page(request, bookset, query=None, _limit=None, _order='title'):
|
def prev_page(request, bookset, query=None, _limit=None, _order='title'):
|
||||||
"""
|
"""
|
||||||
Goto previous page in bookset
|
Goto previous page in bookset
|
||||||
@@ -107,6 +147,7 @@ def prev_page(request, bookset, query=None, _limit=None, _order='title'):
|
|||||||
_payload,
|
_payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def book_set(_order, _limit=None, _set=1, _flip=False):
|
def book_set(_order, _limit=None, _set=1, _flip=False):
|
||||||
"""
|
"""
|
||||||
Get books results by set #
|
Get books results by set #
|
||||||
@@ -121,6 +162,7 @@ def book_set(_order, _limit=None, _set=1, _flip=False):
|
|||||||
books = Books.objects.all().order_by(_order)[_set_min:_set_max]
|
books = Books.objects.all().order_by(_order)[_set_min:_set_max]
|
||||||
return books
|
return books
|
||||||
|
|
||||||
|
|
||||||
def collection(_collection, _set, _limit=None):
|
def collection(_collection, _set, _limit=None):
|
||||||
"""
|
"""
|
||||||
Get books by collection id
|
Get books by collection id
|
||||||
@@ -136,6 +178,7 @@ def collection(_collection, _set, _limit=None):
|
|||||||
_books.append(c.book_id_id)
|
_books.append(c.book_id_id)
|
||||||
return Books.objects.filter(id__in=_books)
|
return Books.objects.filter(id__in=_books)
|
||||||
|
|
||||||
|
|
||||||
def book_set_as_dict(_limit=None, _set=1):
|
def book_set_as_dict(_limit=None, _set=1):
|
||||||
if _limit is None:
|
if _limit is None:
|
||||||
_limit = 20
|
_limit = 20
|
||||||
@@ -155,6 +198,7 @@ def book_set_as_dict(_limit=None, _set=1):
|
|||||||
}
|
}
|
||||||
return json.dumps(_set)
|
return json.dumps(_set)
|
||||||
|
|
||||||
|
|
||||||
def download(request, pk):
|
def download(request, pk):
|
||||||
"""
|
"""
|
||||||
Download book by primary key
|
Download book by primary key
|
||||||
@@ -167,17 +211,14 @@ def download(request, pk):
|
|||||||
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def favorite(request, pk):
|
def favorite(request, pk):
|
||||||
"""
|
"""
|
||||||
Favorite book by primary key
|
Add book to favorites bu primary key
|
||||||
"""
|
"""
|
||||||
_book = Books.objects.all().filter(pk=pk)[0]
|
_book = Books.objects.all().filter(pk=pk)[0]
|
||||||
_fn = hr_name(_book)
|
print(Favorite(book=_book, uname=User))
|
||||||
response = HttpResponse(
|
|
||||||
open(os.path.abspath(_book.file_name), "rb"), content_type="application/zip"
|
|
||||||
)
|
|
||||||
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
|
||||||
return response
|
|
||||||
|
|
||||||
def share(request, pk):
|
def share(request, pk):
|
||||||
"""
|
"""
|
||||||
@@ -191,6 +232,7 @@ def share(request, pk):
|
|||||||
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def info(request, pk):
|
def info(request, pk):
|
||||||
"""
|
"""
|
||||||
Share book by primary key
|
Share book by primary key
|
||||||
@@ -203,12 +245,14 @@ def info(request, pk):
|
|||||||
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
response["Content-Disposition"] = "attachment; filename=%s" % _fn
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def hr_name(book):
|
def hr_name(book):
|
||||||
"""
|
"""
|
||||||
Nicer file names
|
Nicer file names
|
||||||
"""
|
"""
|
||||||
return "{0}{1}".format(slugify(book.title), os.path.splitext(book.file_name)[1])
|
return "{0}{1}".format(slugify(book.title), os.path.splitext(book.file_name)[1])
|
||||||
|
|
||||||
|
|
||||||
def format_list(list_in):
|
def format_list(list_in):
|
||||||
formated_list, formated_list_key, x = [], [], 0
|
formated_list, formated_list_key, x = [], [], 0
|
||||||
for i in list_in:
|
for i in list_in:
|
||||||
@@ -222,6 +266,7 @@ def format_list(list_in):
|
|||||||
else:
|
else:
|
||||||
x = 0
|
x = 0
|
||||||
|
|
||||||
|
|
||||||
def menu(which, _set=1, parent=None):
|
def menu(which, _set=1, parent=None):
|
||||||
if which == "collections":
|
if which == "collections":
|
||||||
collection_list = collections
|
collection_list = collections
|
||||||
@@ -253,6 +298,7 @@ def menu(which, _set=1, parent=None):
|
|||||||
navigation_list = Navigation.objects.all()
|
navigation_list = Navigation.objects.all()
|
||||||
return navigation_list
|
return navigation_list
|
||||||
|
|
||||||
|
|
||||||
def collections_list():
|
def collections_list():
|
||||||
collection_key = []
|
collection_key = []
|
||||||
for i in collections:
|
for i in collections:
|
||||||
@@ -260,6 +306,7 @@ def collections_list():
|
|||||||
collection_key.append(i.collection)
|
collection_key.append(i.collection)
|
||||||
return json.dumps(list(set(collection_key)))
|
return json.dumps(list(set(collection_key)))
|
||||||
|
|
||||||
|
|
||||||
def payload(request, query, _set, _limit, _order, **kwargs):
|
def payload(request, query, _set, _limit, _order, **kwargs):
|
||||||
"""
|
"""
|
||||||
Return formatted data to template
|
Return formatted data to template
|
||||||
@@ -267,7 +314,7 @@ def payload(request, query, _set, _limit, _order, **kwargs):
|
|||||||
still beautiful
|
still beautiful
|
||||||
"""
|
"""
|
||||||
try: request.session['ascending']
|
try: request.session['ascending']
|
||||||
except KeyError: request.session['ascending'] = bool
|
except KeyError: request.session['ascending'] = True
|
||||||
try:
|
try:
|
||||||
if kwargs['flip_sort']:
|
if kwargs['flip_sort']:
|
||||||
request.session['ascending'] = not request.session['ascending']
|
request.session['ascending'] = not request.session['ascending']
|
||||||
@@ -309,7 +356,7 @@ def payload(request, query, _set, _limit, _order, **kwargs):
|
|||||||
_results.count()
|
_results.count()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
query = request.session['cached_query']
|
query = request.session['cached_query'] # Is there a cached query?
|
||||||
if query == None: raise KeyError
|
if query == None: raise KeyError
|
||||||
if request.session['ascending']:
|
if request.session['ascending']:
|
||||||
_results = Books().generic_search(query)
|
_results = Books().generic_search(query)
|
||||||
@@ -324,11 +371,10 @@ def payload(request, query, _set, _limit, _order, **kwargs):
|
|||||||
_r_len, _search = None, None
|
_r_len, _search = None, None
|
||||||
|
|
||||||
_bookstats, _collectionstats, _collectionobject = \
|
_bookstats, _collectionstats, _collectionobject = \
|
||||||
Books.objects.all().count, Collections.objects.all().count, \
|
Books.objects.all().count(), Collections.objects.all().count(), \
|
||||||
collections_list()
|
collections_list()
|
||||||
|
if (_r_len): _btotal = str(_r_len)
|
||||||
if (_r_len): _btotal = _r_len
|
else: _btotal = str(_bookstats)
|
||||||
else: _btotal = _bookstats
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"Books": _r,
|
"Books": _r,
|
||||||
@@ -342,6 +388,6 @@ def payload(request, query, _set, _limit, _order, **kwargs):
|
|||||||
"NowShowing": _now_showing,
|
"NowShowing": _now_showing,
|
||||||
"PostedSearch": query,
|
"PostedSearch": query,
|
||||||
"SearchLen": _r_len,
|
"SearchLen": _r_len,
|
||||||
"Order": _order
|
"Order": _order,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user