From 53e9a1d222067733a5ea908055506866485fb5d8 Mon Sep 17 00:00:00 2001 From: Raelon Masters Date: Sun, 22 Mar 2020 01:05:42 -0400 Subject: [PATCH] Massive UI changes, and updates to the collection system --- .gitignore | 3 ++ config.json | 2 +- src/backend/lib/storage.py | 6 +++ src/frontend/settings.py | 3 +- src/interface/models.py | 9 ++++ src/interface/static/css/main.css | 64 ++++++++++++++++++++----- src/interface/static/js/pyshelf_ux.js | 65 ++++++++++++++++++++------ src/interface/templates/index.html | 3 +- src/interface/templates/search.html | 12 +++++ src/interface/views.py | 67 ++++++++++++++++++--------- 10 files changed, 183 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index b53eaff..7d5c28b 100755 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,6 @@ create_db.sql uwsgi.ini installer.log pyshelf_nginx.conf +tags +TAGS +config.json diff --git a/config.json b/config.json index eabce68..28132cf 100755 --- a/config.json +++ b/config.json @@ -1 +1 @@ -{"TITLE": "pyShelf E-Book Server", "VERSION": "0.4.1", "BOOKPATH": "/home/raelon/Books", "DB_HOST": "localhost", "DB_PORT": "5432", "DATABASE": "pyshelf", "USER": "pyshelf", "PASSWORD": "pyshelf", "BOOKSHELF": "data/shelf.json", "ALLOWED_HOSTS": "*", "hostname": "localhost", "webport": "8000", "wsgiport": "8001"} +{"TITLE": "pyShelf E-Book Server", "VERSION": "0.5.0", "BOOKPATH": "/home/raelon/Books", "DB_HOST": "localhost", "DB_PORT": "5432", "DATABASE": "pyshelf", "USER": "pyshelf", "PASSWORD": "pyshelf", "BOOKSHELF": "data/shelf.json", "ALLOWED_HOSTS": "*", "hostname": "localhost", "webport": "8000", "wsgiport": "8001"} diff --git a/src/backend/lib/storage.py b/src/backend/lib/storage.py index bdfda31..972937d 100755 --- a/src/backend/lib/storage.py +++ b/src/backend/lib/storage.py @@ -1,4 +1,6 @@ #!/usr/bin/python +import re + import psycopg2 @@ -96,6 +98,7 @@ class Storage: return True def make_collections(self): + _title_regx = re.compile(r"^[0-9][0-9]*|-|\ \B") _q = "SELECT id,file_name FROM books" self.cursor.execute(_q) _set = self.cursor.fetchall() @@ -107,6 +110,9 @@ class Storage: _pathing.pop(-1) for _p in _pathing: _s = _p.replace("'", "") + _x = re.sub(_title_regx, "", _s) + _s = _x.strip() + breakpoint() _q_x = """ SELECT id FROM collections where collection='%s' AND book_id_id=%s """ % ( diff --git a/src/frontend/settings.py b/src/frontend/settings.py index ba63f05..6fe29bb 100755 --- a/src/frontend/settings.py +++ b/src/frontend/settings.py @@ -34,7 +34,8 @@ SECRET_KEY = "@(9b9jslgg41u1u=mr)-2*-n2x0vef0zsy39*z@sz18&tvow18" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = TEMPLATE_DEBUG = True - +if DEBUG is True: + from pudb.remote import set_trace ALLOWED_HOSTS = CONFIG.allowed_hosts diff --git a/src/interface/models.py b/src/interface/models.py index 39b9b27..2f07909 100755 --- a/src/interface/models.py +++ b/src/interface/models.py @@ -30,6 +30,15 @@ class Books(models.Model): progress = models.IntegerField(null=True) file_name = models.CharField(max_length=255, null=False) + def generic_search(self, query): + try: + results = Books.objects.annotate( + search=SearchVector("title", "file_name", "author"), + ).filter(search=query) + except Exception as e: + raise + return results + class Collections(models.Model): class Meta: diff --git a/src/interface/static/css/main.css b/src/interface/static/css/main.css index bca8818..060213a 100755 --- a/src/interface/static/css/main.css +++ b/src/interface/static/css/main.css @@ -12,7 +12,7 @@ body { "app_body" "app_footer"; grid-template-rows: auto auto auto; - max-height: 100%; + /*max-height: 100%;*/ } .clear { @@ -84,23 +84,61 @@ body { grid-area: app_body; grid-template-rows: auto; grid-template-areas: "nav_l shelf"; - grid-template-columns: 13vw auto; - justify-items: center; + grid-template-columns: 15vw 85vw; background-color: dimgray; } .nav_l { display: grid; grid-area: nav_l; + font-family: 'Gruppo', cursive; + font-size: 20px; + max-height: 500px; + overflow-y: scroll; + padding: 0px 10px; } -.nav_l_hdr {} +.popover{ + display: none; + z-index: 100; + background-color: #000; + /*min-width: 200px;*/ + min-height: 30px; + position: fixed; + text-align: center; + font-weight: bold; + align-items: center; + justify-content:center; + justify-items: center; + padding: 0px 10px; +} +.nav_l_hdr { + text-align: center; + padding: 5px; + background-color: #292f35; + border-bottom: 2px solid #000; +} -.nav_l_0 {background-color: #2b2b2b; font-size: 15px; padding: 5px;} +.nav_l_0 { + background-color: #2b2b2b; + padding: 5px; + text-align: center; + border-bottom: 1px solid #000; +} -.nav_l_1 {font-size: 15px; padding: 5px;} +.nav_l_1 { + padding: 5px; + text-align: center; + border-bottom: 1px solid #000; +} .nav_link {} -#vert-nav {list-style: None; padding: 0px;} +#vert-nav { + list-style: None; + padding: 0px; + margin: 10px 0px; + border-left: 5px solid #292f35; + border-right: 5px solid #292f35; +} .vert-nav-item {} @@ -208,6 +246,8 @@ body { margin: 0px 0px; padding: 10px 0px 10px; list-style-type: none; + overflow-y: scroll; + overflow-x: hidden; } .shelf_contents {} @@ -234,7 +274,7 @@ p { #book_shelf { display: grid; - grid-template-columns: 25% 25% 25% 25%; + grid-template-columns: 21% 21% 21% 21%; list-style-type: none; font-family: 'Audiowide', cursive; font-size: 25px; @@ -247,14 +287,14 @@ p { display: grid; background-color: burlywood; margin: 0 10px 10px 10px; - max-width: 23vw; - max-height: 75vh; + max-width: 20vw; + max-height: 70vh; text-align: center; } .book_thumb { - width: 23vw; - height: 50vh; + width: 20vw; + height: 70vh; } a.book_link { diff --git a/src/interface/static/js/pyshelf_ux.js b/src/interface/static/js/pyshelf_ux.js index 69ea6d2..64374cf 100755 --- a/src/interface/static/js/pyshelf_ux.js +++ b/src/interface/static/js/pyshelf_ux.js @@ -1,15 +1,54 @@ $(document).ready(function(){ - $(".search_submit").click(function(){ - var query = $('.nav_search').val(); - console.log(query); - window.location.href = '/search/'+query; - }); - $('.nav_search').on('keypress', function (e) { - if(e.which === 13){ - $(this).attr("disabled", "disabled"); - var query = $('.nav_search').val(); - window.location.href = '/search/'+query; - $(this).removeAttr("disabled"); - } - }); + function customlog(outstream) { + /* Gather my variables and output them */ + for (var i = 0; i < outstream.length; i++){ + console.log(">> "+outstream[i]); + }; + }; + /* Initialize ui variables */ + var outstream = []; // put customlog messages here + var win_height = window.innerHeight; // Get the displays height + var win_width = window.innwerWidth; // Get the displays width + var scr_height = window.outerHeight; + var scr_width = window.outerWidth; + var hdr_height = $('.app_hdr').height(); // Get our header height + var ftr_height = $('.app_footer').height(); // Get our footer height + var nav_width = $('.nav_l').width(); // Get the width of our nav items + var cmp_height = window.screen.availHeight; + var max_height = win_height - (hdr_height + ftr_height) - (scr_height - win_height); // Set our available height + customlog([cmp_height]); + $(".search_submit").click(function(){ + var query = $('.nav_search').val(); + console.log(query); + window.location.href = '/search/'+query; + }); + $('.nav_search').on('keypress', function (e) { + if(e.which === 13){ + $(this).attr("disabled", "disabled"); + var query = $('.nav_search').val(); + window.location.href = '/search/'+query; + $(this).removeAttr("disabled"); + } + }); + $('#app').css("height", max_height); + $('.nav_l').css("max-height", max_height); + $('div.shelf').css("max-height", max_height); + $('.nav_link').on('mouseover', function (e){ + var popover_str = $(this).attr('alt'); + x = $(this).offset().left + y = $(this).offset().top + $('.popover').html(popover_str); + $('.popover').css('left', x+nav_width); + $('.popover').css('top', y); + $('.popover').css('display','flex'); + }); + $('.nav_link').on('mouseout', function (e){ + var popover_str = $(this).attr('alt'); + x = $(this).offset().left + y = $(this).offset().top + $('.popover').html(popover_str); + $('.popover').css('left', x); + $('.popover').css('top', y); + $('.popover').css('display','none'); + }); }) diff --git a/src/interface/templates/index.html b/src/interface/templates/index.html index 863d04a..d8ea54b 100755 --- a/src/interface/templates/index.html +++ b/src/interface/templates/index.html @@ -51,10 +51,11 @@
+
Your search for {{ Query }} returned {{ len_results }} results diff --git a/src/interface/views.py b/src/interface/views.py index ce8b7a5..d244e7d 100755 --- a/src/interface/views.py +++ b/src/interface/views.py @@ -38,7 +38,7 @@ def show_collection(request, _collection, _colset): _set = 1 return render( request, - "search.html", + "index.html", { "Books": collection(_collection, _set), "Set": str(_set), @@ -48,26 +48,6 @@ def show_collection(request, _collection, _colset): ) -def menu(which): - if which == "collections": - collection_list = Collections.objects.all() - collections = [] - collection_key = [] - x = 0 - for i in collection_list: - if x % 2 == 0: - c = 0 - else: - c = 1 - if i.collection not in collection_key: - collections.append( - {"string": i.collection, "link": i.collection, "class": c} - ) - collection_key.append(i.collection) - x = x + 1 - return collections - - def next_page(request, bookset): """ Goto next page in bookset @@ -79,7 +59,12 @@ def next_page(request, bookset): return render( request, "index.html", - {"Books": book_set(None, _set), "Set": str(_set), "Version": config.VERSION}, + { + "Books": book_set(None, _set), + "Set": str(_set), + "Version": config.VERSION, + "LeftNav": menu("collections"), + }, ) @@ -98,7 +83,12 @@ def prev_page(request, bookset): return render( request, "index.html", - {"Books": book_set(None, _set), "Set": str(_set), "Version": config.VERSION}, + { + "Books": book_set(None, _set), + "Set": str(_set), + "Version": config.VERSION, + "LeftNav": menu("collections"), + }, ) @@ -127,6 +117,7 @@ def search(request, query=None, _set=1, _limit=None): "Set": _set, "len_results": search_len, "Version": config.VERSION, + "LeftNav": menu("collections"), }, ) @@ -197,3 +188,33 @@ def hr_name(book): Nicer file names """ return "{0}{1}".format(slugify(book.title), os.path.splitext(book.file_name)[1]) + + +def menu(which, _set=1): + if which == "collections": + collection_list = Collections.objects.all() + collections, collection_key, x = [], [], 0 + for i in collection_list: + if i.collection not in collection_key: + # Using c as the alternating row identifier + # set c here + if x % 2 == 0: + c = 0 + else: + c = 1 + if x <= 10: + x = x + 1 + else: + x = 0 + breakpoint() + # TODO trim #'s and symbols from front of collection name + if len(i.collection) > 16: + collection_string = i.collection[0:16] + " ..." + else: + collection_string = i.collection + + collections.append( + {"string": collection_string, "link": i.collection, "class": c} + ) + collection_key.append(i.collection) + return collections