From 802a07e52f10f45c2774cd2a8b9f34e85ec1eef3 Mon Sep 17 00:00:00 2001 From: Raelon Masters Date: Sun, 19 Jul 2020 16:52:01 -0400 Subject: [PATCH 1/5] Began working on favorites model --- src/frontend/urls.py | 4 +++- src/interface/models.py | 24 +++++++++++++----------- src/interface/static/js/pyshelf_ux.js | 8 ++++++++ src/interface/templates/index.html | 2 +- src/interface/views.py | 17 +++++++++++------ 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/frontend/urls.py b/src/frontend/urls.py index 6369c3b..63acad0 100755 --- a/src/frontend/urls.py +++ b/src/frontend/urls.py @@ -17,6 +17,8 @@ from django.conf import settings from django.contrib import admin from django.urls import include, path, re_path from django.contrib.auth import views as auth_views +from django.contrib.auth.models import User +from django.shortcuts import HttpResponse from interface import views urlpatterns = [ @@ -26,7 +28,6 @@ urlpatterns = [ path("sort/<_order>", views.index, name="index"), path("flip_sort/<_order>", views.flip_sort, name="index"), path("download/", views.download, name="download"), - path("favorite/", views.favorite, name="favorite"), path("share/", views.share, name="share"), path("share/", views.info, name="info"), path("prev_page/", views.prev_page, name="prev_page"), @@ -40,6 +41,7 @@ urlpatterns = [ path("signup", views.signup, name="signup"), path("login", views.userlogin, name="login"), path('logout', views.userlogout, name='logout'), + path('favorite/', views.favorite, name='favorite'), path( 'admin/password_reset/', auth_views.PasswordResetView.as_view(), diff --git a/src/interface/models.py b/src/interface/models.py index 04cc090..d625037 100755 --- a/src/interface/models.py +++ b/src/interface/models.py @@ -1,7 +1,8 @@ from django.contrib.postgres.search import SearchVector from django.db import models from django.conf import settings -from django.contrib.auth.models import AbstractUser +from django.contrib.auth.models import AbstractUser, User +from django.contrib.auth import get_user_model # Create your models here. @@ -110,6 +111,14 @@ class Navigation(models.Model): 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) + + class Favorites(models.Model): """ pyShelfs User Database class @@ -122,10 +131,9 @@ class Favorites(models.Model): def __str__(self): return self.title - - favorite = models.ManyToManyField(Books) - uname = models.ManyToManyField(settings.AUTH_USER_MODEL) - + + book = models.ForeignKey(Books.id, on_delete=models.PROTECT) + user = models.ForeignKey(get_user_model(), on_delete=models.PROTECT) def generic_search(self, query): try: results = Favorites.objects.annotate(search=SearchVector("uname"),).filter( @@ -136,9 +144,3 @@ class Favorites(models.Model): 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) diff --git a/src/interface/static/js/pyshelf_ux.js b/src/interface/static/js/pyshelf_ux.js index 8493489..5095e05 100755 --- a/src/interface/static/js/pyshelf_ux.js +++ b/src/interface/static/js/pyshelf_ux.js @@ -73,6 +73,9 @@ $(document).ready(function(){ }); $('#btn_login').on('click', function(){ $('#hdr_nav_login').toggle(); + }); + $('.favorite_action').on('click', toggle_favorite(){ + }); $('#sortlist').change(function () { var optionSelected = $(this).find("option:selected"); @@ -101,3 +104,8 @@ function resize_search(win_width){ $('.search_string').val("Search"); } } + +function toggle_favorite($(this)){ + custom_log('Favorite book by _pk'+$(this)); +} + diff --git a/src/interface/templates/index.html b/src/interface/templates/index.html index d6a983c..78457a9 100755 --- a/src/interface/templates/index.html +++ b/src/interface/templates/index.html @@ -97,7 +97,7 @@ {% endif %}
  • Tags: {{ book.tags }}
  • - + diff --git a/src/interface/views.py b/src/interface/views.py index 19405e0..87695dc 100755 --- a/src/interface/views.py +++ b/src/interface/views.py @@ -8,10 +8,13 @@ from django.http import JsonResponse from django.shortcuts import HttpResponse, render, redirect # render_to_response from django.utils.text import slugify from django.contrib.auth import login, authenticate, logout +from django.contrib import auth from django.contrib.auth.models import User +from django.conf import settings +from django.contrib.auth import get_user_model import json from .forms import SignUpForm, UserLoginForm -from .models import Books, Collections, Navigation, Favorites +from .models import Books, Collections, Navigation, Favorites, CustomUser config = Config(Path("../")) @@ -63,8 +66,8 @@ def userlogout(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 """ _payload = payload(request, query, _set, _limit, _order, reset='1') @@ -203,7 +206,7 @@ def download(request, pk): """ Download book by primary key """ - _book = Books.objects.all().filter(pk=pk)[0] + _book = Books.objects.get(pk=pk) _fn = hr_name(_book) response = HttpResponse( open(os.path.abspath(_book.file_name), "rb"), content_type="application/zip" @@ -216,8 +219,10 @@ def favorite(request, pk): """ Add book to favorites bu primary key """ - _book = Books.objects.all().filter(pk=pk)[0] - print(Favorite(book=_book, uname=User)) + breakpoint() + f = Favorites(book=Books.objects.get(pk=pk)) + f.save + return redirect('home') def share(request, pk): From 337600a74ef2dbe348750da83cc88b19f919ce3f Mon Sep 17 00:00:00 2001 From: Raelon Masters Date: Tue, 21 Jul 2020 20:45:15 -0400 Subject: [PATCH 2/5] Add to favorites functionality backend complete. --- src/frontend/settings.py | 2 +- src/interface/admin.py | 6 +++--- src/interface/forms.py | 12 ++++++------ src/interface/models.py | 25 ++++++++++++++++--------- src/interface/views.py | 8 +++++--- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/frontend/settings.py b/src/frontend/settings.py index ce8927f..ef4e3e5 100755 --- a/src/frontend/settings.py +++ b/src/frontend/settings.py @@ -52,7 +52,7 @@ INSTALLED_APPS = [ "interface.templatetags", "debug_toolbar", ] -AUTH_USER_MODEL = "interface.CustomUser" +AUTH_USER_MODEL = "interface.User" MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", diff --git a/src/interface/admin.py b/src/interface/admin.py index 9a9db2e..96c61be 100755 --- a/src/interface/admin.py +++ b/src/interface/admin.py @@ -1,12 +1,12 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin -from .models import Books, Collections, Favorites, Navigation, CustomUser +from .models import Books, Collections, Favorites, Navigation, User from .forms import CustomUserCreationForm, CustomUserChangeForm class CustomUserAdmin(UserAdmin): - model = CustomUser + model = User add_form = CustomUserCreationForm form = CustomUserChangeForm list_display = ["email", "username", "facebook", "twitter", "sponsorid", "matrixid"] @@ -27,4 +27,4 @@ admin.site.register(Books) admin.site.register(Collections) admin.site.register(Favorites) admin.site.register(Navigation) -admin.site.register(CustomUser, CustomUserAdmin) +admin.site.register(User, CustomUserAdmin) diff --git a/src/interface/forms.py b/src/interface/forms.py index 1807b14..b345393 100644 --- a/src/interface/forms.py +++ b/src/interface/forms.py @@ -1,23 +1,23 @@ from django import forms from django.contrib.auth.forms import UserCreationForm, UserChangeForm, AuthenticationForm -from .models import CustomUser +from .models import User class CustomUserCreationForm(UserCreationForm): class Meta: - model = CustomUser + model = User fields = ("username", "email", "facebook", "twitter", "sponsorid", "matrixid") class CustomUserChangeForm(UserChangeForm): class Meta: - model = CustomUser + model = User fields = ("username", "email", "facebook", "twitter", "sponsorid", "matrixid") class CustomUserLoginForm(AuthenticationForm): class Meta: - Model = CustomUser + Model = User fields = ("username", "password") @@ -27,11 +27,11 @@ class SignUpForm(CustomUserCreationForm): matrixid = forms.CharField(max_length=30, required=False, help_text='Optional.') class Meta: - model = CustomUser + model = User fields = ("username", "email", "matrixid") class UserLoginForm(CustomUserLoginForm): class Meta: - model = CustomUser + model = User diff --git a/src/interface/models.py b/src/interface/models.py index d625037..3d1e013 100755 --- a/src/interface/models.py +++ b/src/interface/models.py @@ -111,32 +111,39 @@ class Navigation(models.Model): return results -class CustomUser(AbstractUser): +class User(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) + def __str__(self): + return self.username + class Favorites(models.Model): """ - pyShelfs User Database class - :param uname: User Name - :param fname: First Name + Favorites Database class + :param book: book foreign key + :param user: user foreign key """ class Meta: db_table = "favorites" def __str__(self): - return self.title - - book = models.ForeignKey(Books.id, on_delete=models.PROTECT) - user = models.ForeignKey(get_user_model(), on_delete=models.PROTECT) + pass + # return self.book + + book = models.ForeignKey(Books, on_delete=models.CASCADE) + user = models.ForeignKey( + User, + on_delete=models.CASCADE + ) def generic_search(self, query): try: - results = Favorites.objects.annotate(search=SearchVector("uname"),).filter( + results = Favorites.objects.annotate(search=SearchVector("user"),).filter( search=query ) except Exception as e: diff --git a/src/interface/views.py b/src/interface/views.py index 87695dc..3eaf61b 100755 --- a/src/interface/views.py +++ b/src/interface/views.py @@ -14,7 +14,7 @@ from django.conf import settings from django.contrib.auth import get_user_model import json from .forms import SignUpForm, UserLoginForm -from .models import Books, Collections, Navigation, Favorites, CustomUser +from .models import Books, Collections, Navigation, Favorites, User config = Config(Path("../")) @@ -51,11 +51,13 @@ def signup(request): def userlogin(request): if request.method == 'POST': + breakpoint() username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) + user.save() return redirect('home') form = UserLoginForm() return render(request, 'login.html', {'form': form}) @@ -219,9 +221,9 @@ def favorite(request, pk): """ Add book to favorites bu primary key """ - breakpoint() f = Favorites(book=Books.objects.get(pk=pk)) - f.save + f.user = request.user + f.save() return redirect('home') From 5ebaa22ee4a4dfd8c3bdc9e252baca03212772fd Mon Sep 17 00:00:00 2001 From: Raelon Masters Date: Tue, 21 Jul 2020 23:25:26 -0400 Subject: [PATCH 3/5] Toggling of Favorites, and frontend state display complete --- src/interface/models.py | 3 +-- src/interface/static/css/main.css | 4 ++++ src/interface/static/css/main.scss | 3 +++ src/interface/templates/index.html | 6 +++++- src/interface/views.py | 29 +++++++++++++++++++++-------- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/interface/models.py b/src/interface/models.py index 3d1e013..a6e6c67 100755 --- a/src/interface/models.py +++ b/src/interface/models.py @@ -133,8 +133,7 @@ class Favorites(models.Model): db_table = "favorites" def __str__(self): - pass - # return self.book + return self.book book = models.ForeignKey(Books, on_delete=models.CASCADE) user = models.ForeignKey( diff --git a/src/interface/static/css/main.css b/src/interface/static/css/main.css index 1c954a2..a60fd50 100644 --- a/src/interface/static/css/main.css +++ b/src/interface/static/css/main.css @@ -541,6 +541,10 @@ a.book_link { padding: 5px 10px 5px 10px; } +.favorite { + color: #a7ff00 !important; +} + .controls { cursor: pointer; } diff --git a/src/interface/static/css/main.scss b/src/interface/static/css/main.scss index 053fa94..0aa1b1d 100755 --- a/src/interface/static/css/main.scss +++ b/src/interface/static/css/main.scss @@ -552,6 +552,9 @@ a.book_link { font-size: x-large; padding: 5px 10px 5px 10px; } +.favorite{ + color: #a7ff00 !important; +} .controls{ cursor: pointer; } diff --git a/src/interface/templates/index.html b/src/interface/templates/index.html index 78457a9..af992a1 100755 --- a/src/interface/templates/index.html +++ b/src/interface/templates/index.html @@ -98,7 +98,11 @@
  • Tags: {{ book.tags }}
  • - + {% if book.is_favorite %} + + {% else %} + + {% endif %} diff --git a/src/interface/views.py b/src/interface/views.py index 3eaf61b..4a79b0d 100755 --- a/src/interface/views.py +++ b/src/interface/views.py @@ -153,7 +153,7 @@ def prev_page(request, bookset, query=None, _limit=None, _order='title'): ) -def book_set(_order, _limit=None, _set=1, _flip=False): +def book_set(request, _order, _limit=None, _set=1, _flip=False): """ Get books results by set # """ @@ -165,6 +165,15 @@ def book_set(_order, _limit=None, _set=1, _flip=False): books = Books.objects.all().order_by(_order).reverse()[_set_min:_set_max] else: books = Books.objects.all().order_by(_order)[_set_min:_set_max] + try: + favorites = Favorites.objects.filter(user=request.user) + except Exception as e: breakpoint() + for book in books: + for favorite in favorites: + if book == favorite.book: + book.is_favorite = True + break + else: book.is_favorite = False return books @@ -221,9 +230,13 @@ def favorite(request, pk): """ Add book to favorites bu primary key """ - f = Favorites(book=Books.objects.get(pk=pk)) - f.user = request.user - f.save() + _d = Favorites.objects.filter(user=request.user, book=Books.objects.get(pk=pk)) + if len(_d) == 1: + _d.delete() + return redirect('home') + _f = Favorites(book=Books.objects.get(pk=pk)) + _f.user = request.user + _f.save() return redirect('home') @@ -335,8 +348,8 @@ def payload(request, query, _set, _limit, _order, **kwargs): _set_min = _set_max - _limit _now_showing = "%s-%s"%(_set_min, _set_max) if request.session['ascending']: - _r = book_set(_order, _limit, _set) - else: _r = book_set(_order, _limit, _set, True) + _r = book_set(request, _order, _limit, _set) + else: _r = book_set(request, _order, _limit, _set, True) _r_len, _search = None, None except KeyError: _set = int(_set) @@ -373,8 +386,8 @@ def payload(request, query, _set, _limit, _order, **kwargs): _results.count() except KeyError: if request.session['ascending']: - _r = book_set(_order, _limit, _set) - else: _r = book_set(_order, _limit, _set, True) + _r = book_set(request, _order, _limit, _set) + else: _r = book_set(request, _order, _limit, _set, True) _r_len, _search = None, None _bookstats, _collectionstats, _collectionobject = \ From 632976328e113abd248084268e101198586e6c56 Mon Sep 17 00:00:00 2001 From: Raelon Masters Date: Tue, 21 Jul 2020 23:46:32 -0400 Subject: [PATCH 4/5] Toggle favorite without losing postion in catalog --- src/interface/static/js/pyshelf_ux.js | 8 ++------ src/interface/views.py | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/interface/static/js/pyshelf_ux.js b/src/interface/static/js/pyshelf_ux.js index 5095e05..604057f 100755 --- a/src/interface/static/js/pyshelf_ux.js +++ b/src/interface/static/js/pyshelf_ux.js @@ -74,8 +74,8 @@ $(document).ready(function(){ $('#btn_login').on('click', function(){ $('#hdr_nav_login').toggle(); }); - $('.favorite_action').on('click', toggle_favorite(){ - + $('.favorite_action').on('click', function(){ + $(this).toggleClass('favorite'); }); $('#sortlist').change(function () { var optionSelected = $(this).find("option:selected"); @@ -105,7 +105,3 @@ function resize_search(win_width){ } } -function toggle_favorite($(this)){ - custom_log('Favorite book by _pk'+$(this)); -} - diff --git a/src/interface/views.py b/src/interface/views.py index 4a79b0d..60e14e2 100755 --- a/src/interface/views.py +++ b/src/interface/views.py @@ -233,11 +233,11 @@ def favorite(request, pk): _d = Favorites.objects.filter(user=request.user, book=Books.objects.get(pk=pk)) if len(_d) == 1: _d.delete() - return redirect('home') + return HttpResponse(status=204) _f = Favorites(book=Books.objects.get(pk=pk)) _f.user = request.user _f.save() - return redirect('home') + return HttpResponse(status=204) def share(request, pk): From 5aeb7ff13cb99bdf979574b656e842253dfc75d4 Mon Sep 17 00:00:00 2001 From: Raelon Masters Date: Tue, 21 Jul 2020 23:55:44 -0400 Subject: [PATCH 5/5] Fixed an issue where not being logged in would fail favorites check --- src/interface/templates/index.html | 4 ++-- src/interface/views.py | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/interface/templates/index.html b/src/interface/templates/index.html index af992a1..108ea25 100755 --- a/src/interface/templates/index.html +++ b/src/interface/templates/index.html @@ -39,9 +39,9 @@
  • diff --git a/src/interface/views.py b/src/interface/views.py index 60e14e2..a920cc4 100755 --- a/src/interface/views.py +++ b/src/interface/views.py @@ -51,7 +51,6 @@ def signup(request): def userlogin(request): if request.method == 'POST': - breakpoint() username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) @@ -167,14 +166,14 @@ def book_set(request, _order, _limit=None, _set=1, _flip=False): books = Books.objects.all().order_by(_order)[_set_min:_set_max] try: favorites = Favorites.objects.filter(user=request.user) - except Exception as e: breakpoint() - for book in books: - for favorite in favorites: - if book == favorite.book: - book.is_favorite = True - break - else: book.is_favorite = False - return books + for book in books: + for favorite in favorites: + if book == favorite.book: + book.is_favorite = True + break + return books + except Exception as e: + return books def collection(_collection, _set, _limit=None):