From bc1083c25787632d2eb2ee7cc413cc4b814e9cb5 Mon Sep 17 00:00:00 2001 From: Jordy van Zeeland Date: Tue, 21 Nov 2023 08:24:48 +0100 Subject: [PATCH] Useraccounts + testing ML --- ras/api/modules/challenges.py | 153 ++++++++---------- ras/api/modules/crud.py | 119 +++++--------- ras/api/modules/functions.py | 21 ++- ras/api/modules/pandas.py | 12 +- ras/api/modules/predictions.py | 52 ++++++ ras/api/static/books2.csv | 65 -------- ras/api/static/books_data.csv | 5 - ras/api/urls.py | 2 + ras/api/views.py | 23 +-- ras/frontend/src/components/Data.js | 68 +++----- ras/frontend/static/.DS_Store | Bin 6148 -> 6148 bytes .../static/js/src_components_Data_js.js | 2 +- 12 files changed, 211 insertions(+), 311 deletions(-) create mode 100644 ras/api/modules/predictions.py delete mode 100644 ras/api/static/books2.csv delete mode 100644 ras/api/static/books_data.csv diff --git a/ras/api/modules/challenges.py b/ras/api/modules/challenges.py index 1a1fd4e..2e6b415 100644 --- a/ras/api/modules/challenges.py +++ b/ras/api/modules/challenges.py @@ -7,116 +7,95 @@ from sqlalchemy.sql import text from django.http import JsonResponse import pandas as pd from rest_framework.response import Response - -def filterData(df, datayear = None): - df['readed'] = pd.to_datetime(df['readed'], format='%Y-%m-%d') - df['readed'] = df['readed'].dt.strftime('%m-%Y') - - # Filter data on year - if datayear and datayear is not None: - df = df.where(df['readed'].str.contains(datayear)) - - return df - -def getBooksData(): - engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) - df = pd.read_sql('SELECT * FROM api_books ORDER BY readed', engine, parse_dates={'readed': {'format': '%m-%Y'}}) - - return df - -def getBookChallenge(year = None): - engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) - if(year): - df = pd.read_sql('SELECT * FROM book_challenge where year = ' + year, engine) - else: - df = pd.read_sql('SELECT * FROM book_challenge', engine) - - return df +from .functions import isAuthorized, getBooksData, getBookChallenge, filterData @api_view(['GET']) def getAllChallenges(request): - data = [] - df = getBookChallenge() + if(request.headers.get('Authorization')): + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - for index, row in df.iterrows(): + if(isLoggedIn): + data = [] + df = getBookChallenge(request.headers.get('userid')) - books = filterData(getBooksData(), str(row['year'])) - books = books.dropna() + for index, row in df.iterrows(): + books = filterData(getBooksData(request.headers.get('userid')), str(row['year'])) + books = books.dropna() + totalBooksRead = books['name'].count() - totalBooksRead = books['name'].count() + data.append({ + "id": row['id'], + "year": row['year'], + "nrofbooks": row['nrofbooks'], + "booksread": totalBooksRead + }) - data.append({ - "id": row['id'], - "year": row['year'], - "nrofbooks": row['nrofbooks'], - "booksread": totalBooksRead - }) - - return Response(data) + return Response(data) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) + else: + return JsonResponse({'error': 'Unauthorized'}, safe=False) @api_view(['GET']) def getChallengeOfYear(request): - if request.META.get('HTTP_YEAR'): - data = [] - df = getBookChallenge(request.META.get('HTTP_YEAR')) + if(request.headers.get('Authorization')): + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - for index, row in df.iterrows(): - data.append({ - "year": row['year'], - "nrofbooks": row['nrofbooks'] - }) + if(isLoggedIn): + if request.META.get('HTTP_YEAR'): + data = [] + df = getBookChallenge(request.headers.get('userid'), request.META.get('HTTP_YEAR')) - return Response(data) + for index, row in df.iterrows(): + data.append({ + "year": row['year'], + "nrofbooks": row['nrofbooks'] + }) + + return Response(data) + else: + return JsonResponse({'error': 'No year header included'}, safe=False) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) else: - return Response("No year header included") + return JsonResponse({'error': 'Unauthorized'}, safe=False) @api_view(['POST']) def addChallenge(request): if(request.headers.get('Authorization')): - token = request.headers.get('Authorization').split(' ')[1] + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - try: - User = get_user_model() - payload = jwt.decode(token, 'secret', algorithms=['HS256']) - user = User.objects.get(id=payload['id']) + if(isLoggedIn): + year = request.POST.get('year') + challenge = request.POST.get('challenge') - if(user): - year = request.POST.get('year') - challenge = request.POST.get('challenge') - - if(year and challenge): - engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) - conn = engine.connect() - conn.execute(text("INSERT INTO book_challenge (year, nrofbooks) VALUES ('" + str(year) + "', '" + str(challenge) + "')")) - return JsonResponse("OK", safe=False) - else: - return JsonResponse({'error': 'No year and challenge detected'}, safe=False) + if(year and challenge): + engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) + conn = engine.connect() + conn.execute(text("INSERT INTO book_challenge (year, nrofbooks) VALUES ('" + str(year) + "', '" + str(challenge) + "')")) + return JsonResponse("OK", safe=False) else: - return JsonResponse({'error': 'No user detected'}, safe=False) - except (jwt.DecodeError, User.DoesNotExist): - return JsonResponse({'error': 'Token invalid'}, safe=False) + return JsonResponse({'error': 'No year and challenge detected'}, safe=False) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) + else: + return JsonResponse({'error': 'Unauthorized'}, safe=False) @api_view(['DELETE']) def deleteChallenge(request, id = None): - if(request.headers.get('Authorization')): - token = request.headers.get('Authorization').split(' ')[1] + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - try: - User = get_user_model() - payload = jwt.decode(token, 'secret', algorithms=['HS256']) - user = User.objects.get(id=payload['id']) - - if(user): - - if(id): - engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) - conn = engine.connect() - conn.execute(text("DELETE FROM book_challenge WHERE id = " + str(id))) - return JsonResponse("OK", safe=False) - else: - return JsonResponse({'error': 'No challengeid detected'}, safe=False) + if(isLoggedIn): + if(id): + engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) + conn = engine.connect() + conn.execute(text("DELETE FROM book_challenge WHERE id = " + str(id))) + return JsonResponse("OK", safe=False) else: - return JsonResponse({'error': 'No user detected'}, safe=False) - except (jwt.DecodeError, User.DoesNotExist): - return JsonResponse({'error': 'Token invalid'}, safe=False) \ No newline at end of file + return JsonResponse({'error': 'No challengeid detected'}, safe=False) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) + else: + return JsonResponse({'error': 'Unauthorized'}, safe=False) + \ No newline at end of file diff --git a/ras/api/modules/crud.py b/ras/api/modules/crud.py index af1a4c5..da34223 100644 --- a/ras/api/modules/crud.py +++ b/ras/api/modules/crud.py @@ -7,6 +7,7 @@ from sqlalchemy.sql import text from django.http import JsonResponse import pandas as pd from rest_framework.response import Response +from .functions import isAuthorized, getBooksData, filterData engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) conn = engine.connect() @@ -18,37 +19,29 @@ conn = engine.connect() @api_view(['GET']) def getAllBooks(request): if(request.headers.get('Authorization')): - token = request.headers.get('Authorization').split(' ')[1] + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - try: - User = get_user_model() - payload = jwt.decode(token, 'secret', algorithms=['HS256']) - user = User.objects.get(id=payload['id']) + if(isLoggedIn): + books = getBooksData(request.headers.get('userid')) + data = [] - if(user): - books = pd.read_sql('SELECT * FROM api_books ORDER BY readed', engine, parse_dates={'readed': {'format': '%m-%Y'}}) - data = [] + for index, row in books.iterrows(): + data.append({ + "id": row['id'], + "name": row['name'], + "author": row['author'], + "genre": row['genre'], + "author": row['author'], + "country": row['country'], + "country_code": row['country_code'], + "pages": row['pages'], + "readed": row['readed'], + "rating": row['rating'], + }) - for index, row in books.iterrows(): - data.append({ - "id": row['id'], - "name": row['name'], - "author": row['author'], - "genre": row['genre'], - "author": row['author'], - "country": row['country'], - "country_code": row['country_code'], - "pages": row['pages'], - "readed": row['readed'], - "rating": row['rating'], - }) - - return Response(data) - else: - return JsonResponse({'error': 'No user detected'}, safe=False) - - except (jwt.DecodeError, User.DoesNotExist): - return JsonResponse({'error': 'Token invalid'}, safe=False) + return Response(data) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) else: return JsonResponse({'error': 'Unauthorized'}, safe=False) @@ -59,23 +52,13 @@ def getAllBooks(request): @api_view(['POST']) def addBook(request): if(request.headers.get('Authorization')): - token = request.headers.get('Authorization').split(' ')[1] - book = request.POST.get('book') - book = json.loads(book) + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - try: - User = get_user_model() - payload = jwt.decode(token, 'secret', algorithms=['HS256']) - user = User.objects.get(id=payload['id']) - - if(user): - conn.execute(text("INSERT INTO api_books (name, author, genre, country, country_code, pages, readed, rating) VALUES ('" + str(book['name']) + "', '" + str(book['author']) + "', '" + str(book['genre']) + "', '" + str(book['country']) + "', '" + str(book['country_code']) + "', " + str(book['pages']) + ", '" + str(book['readed']) + "', " + str(book['rating']) + ")")) - return JsonResponse("OK", safe=False) - else: - return JsonResponse({'error': 'No user detected'}, safe=False) - - except (jwt.DecodeError, User.DoesNotExist): - return JsonResponse({'error': 'Token invalid'}, safe=False) + if(isLoggedIn): + conn.execute(text("INSERT INTO api_books (name, author, genre, country, country_code, pages, readed, rating) VALUES ('" + str(book['name']) + "', '" + str(book['author']) + "', '" + str(book['genre']) + "', '" + str(book['country']) + "', '" + str(book['country_code']) + "', " + str(book['pages']) + ", '" + str(book['readed']) + "', " + str(book['rating']) + ")")) + return JsonResponse("OK", safe=False) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) else: return JsonResponse({'error': 'Unauthorized'}, safe=False) @@ -86,24 +69,17 @@ def addBook(request): @api_view(['PUT']) def updateBook(request): if(request.headers.get('Authorization')): - token = request.headers.get('Authorization').split(' ')[1] - book = request.POST.get('book') - book = json.loads(book) - bookid = request.headers.get('bookid') + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - try: - User = get_user_model() - payload = jwt.decode(token, 'secret', algorithms=['HS256']) - user = User.objects.get(id=payload['id']) + if(isLoggedIn): + book = request.POST.get('book') + book = json.loads(book) + bookid = request.headers.get('bookid') - if(user): - conn.execute(text("UPDATE api_books set name='" + str(book['name']) + "', author='" + str(book['author']) + "', genre='" + str(book['genre']) + "', country='" + str(book['country']) + "', country_code='" + str(book['country_code']) + "', pages='" + str(book['pages']) + "', readed='" + str(book['readed']) + "', rating='" + str(book['rating']) + "' WHERE id=" + str(bookid))) - return JsonResponse("OK", safe=False) - else: - return JsonResponse({'error': 'No user detected'}, safe=False) - - except (jwt.DecodeError, User.DoesNotExist): - return JsonResponse({'error': 'Token invalid'}, safe=False) + conn.execute(text("UPDATE api_books set name='" + str(book['name']) + "', author='" + str(book['author']) + "', genre='" + str(book['genre']) + "', country='" + str(book['country']) + "', country_code='" + str(book['country_code']) + "', pages='" + str(book['pages']) + "', readed='" + str(book['readed']) + "', rating='" + str(book['rating']) + "' WHERE id=" + str(bookid))) + return JsonResponse("OK", safe=False) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) else: return JsonResponse({'error': 'Unauthorized'}, safe=False) @@ -115,21 +91,14 @@ def updateBook(request): @api_view(['DELETE']) def deleteBook(request): if(request.headers.get('Authorization')): - token = request.headers.get('Authorization').split(' ')[1] - bookid = request.headers.get('bookid') + isLoggedIn = isAuthorized(request.headers.get('Authorization')); - try: - User = get_user_model() - payload = jwt.decode(token, 'secret', algorithms=['HS256']) - user = User.objects.get(id=payload['id']) - - if(user): - conn.execute(text("DELETE FROM api_books WHERE id = " + str(bookid))) - return JsonResponse("OK", safe=False) - else: - return JsonResponse({'error': 'No user detected'}, safe=False) - - except (jwt.DecodeError, User.DoesNotExist): - return JsonResponse({'error': 'Token invalid'}, safe=False) + if(isLoggedIn): + bookid = request.headers.get('bookid') + + conn.execute(text("DELETE FROM api_books WHERE id = " + str(bookid))) + return JsonResponse("OK", safe=False) + else: + return JsonResponse({'error': 'No user detected'}, safe=False) else: return JsonResponse({'error': 'Unauthorized'}, safe=False) \ No newline at end of file diff --git a/ras/api/modules/functions.py b/ras/api/modules/functions.py index 02924d7..7faaece 100644 --- a/ras/api/modules/functions.py +++ b/ras/api/modules/functions.py @@ -20,9 +20,26 @@ def isAuthorized(authtoken): else: return JsonResponse({'error': 'Unauthorized'}, safe=False) -def getBooksData(): +def getBooksData(userid, year = None): engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) - df = pd.read_sql('SELECT * FROM api_books ORDER BY readed', engine, parse_dates={'readed': {'format': '%m-%Y'}}) + + if year: + sql = 'SELECT * FROM api_books WHERE userid = ' + userid + ' AND year = ' + str(year) + ' ORDER BY readed' + else: + sql = 'SELECT * FROM api_books WHERE userid = ' + userid + ' ORDER BY readed' + + df = pd.read_sql(sql, engine, parse_dates={'readed': {'format': '%m-%Y'}}) + + return df + +def getBookChallenge(userid, year = None): + engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) + if year: + sql = 'SELECT * FROM book_challenge WHERE userid = ' + userid + ' AND year = ' + year + else: + sql = 'SELECT * FROM book_challenge WHERE userid = ' + userid + + df = pd.read_sql(sql, engine) return df diff --git a/ras/api/modules/pandas.py b/ras/api/modules/pandas.py index 6e115fc..613142e 100644 --- a/ras/api/modules/pandas.py +++ b/ras/api/modules/pandas.py @@ -15,7 +15,7 @@ def getYears(request): isLoggedIn = isAuthorized(request.headers.get('Authorization')); if(isLoggedIn): - df = filterData(getBooksData()) + df = filterData(getBooksData(request.headers.get('userid'))) df['readed'] = pd.to_datetime(df['readed'], errors='coerce') df['year']= df['readed'].dt.year years = df.groupby('year')['year'].count().reset_index(name="count") @@ -38,7 +38,7 @@ def books_per_genre_per_month(request): if(isLoggedIn): if request.META.get('HTTP_YEAR'): data = [] - df = filterData(getBooksData(), request.META.get('HTTP_YEAR')) + df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR')) booksPerMonth = df.groupby(['genre','readed'])['genre'].count().reset_index(name="count") booksPerMonth = booksPerMonth.sort_values(by=['genre', 'readed', 'count'], ascending=False) @@ -70,7 +70,7 @@ def countGenres(request): if request.META.get('HTTP_YEAR'): data = [] - df = filterData(getBooksData(), request.META.get('HTTP_YEAR')) + df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR')) genres = df.groupby('genre')['genre'].count().reset_index(name="count") genres = genres.sort_values(by='count', ascending=False) @@ -101,7 +101,7 @@ def getStats(request): if(isLoggedIn): if request.META.get('HTTP_YEAR'): data = [] - df = filterData(getBooksData(), request.META.get('HTTP_YEAR')) + df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR')) df = df.dropna() statsTotalBooks = df['name'].count() statsTotalGenres = df['genre'].nunique() @@ -133,7 +133,7 @@ def avg_ratings_per_month(request): if(isLoggedIn): if request.META.get('HTTP_YEAR'): data = [] - df = filterData(getBooksData(), request.META.get('HTTP_YEAR')) + df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR')) avgratingspermonth = df.groupby('readed')['rating'].mean().reset_index(name="rating") for index, row in avgratingspermonth.iterrows(): @@ -163,7 +163,7 @@ def countRatings(request): if(isLoggedIn): if request.META.get('HTTP_YEAR'): data = [] - df = filterData(getBooksData(), request.META.get('HTTP_YEAR')) + df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR')) countratings = df.groupby('rating')['rating'].count().reset_index(name="count") countratings = countratings.sort_values(by='rating', ascending=False) diff --git a/ras/api/modules/predictions.py b/ras/api/modules/predictions.py new file mode 100644 index 0000000..25fbc25 --- /dev/null +++ b/ras/api/modules/predictions.py @@ -0,0 +1,52 @@ +from rest_framework.decorators import api_view +import pandas as pd +import math +from rest_framework.response import Response +from sqlalchemy import create_engine +import ras.settings +from django.http import JsonResponse +from .functions import isAuthorized, getBooksData, filterData +from sklearn.linear_model import LinearRegression + +def getChallenges(): + engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) + df = pd.read_sql('SELECT * FROM book_challenge', engine) + + return df + +def train_model_challenges(data): + df = pd.DataFrame(data) + + X = df.index.values.reshape(-1, 1) + Y = df['nrofbooks'] + + model = LinearRegression() + model.fit(X, Y) + + return model + +def predict_challenge(model): + future_index = pd.RangeIndex(start=0, stop=1, step=1) + future_X = future_index.values.reshape(-1, 1) + predicted_books = model.predict(future_X) + + prediction_next_year = round(predicted_books[-1]) + return prediction_next_year + +@api_view(['GET']) +def predict_next_year(request): + if(request.headers.get('Authorization')): + isLoggedIn = isAuthorized(request.headers.get('Authorization')); + + if(isLoggedIn): + data = getChallenges() + + trained_model = train_model_challenges(data) + next_year_challenge = predict_challenge(trained_model) + return Response(f"Volgend jaar lees ik {next_year_challenge} boeken") + +# def train_model_books_per_month(): +# def predict_books_per_month(): + +# def train_model_genres(): +# def predict_genres(): \ No newline at end of file diff --git a/ras/api/static/books2.csv b/ras/api/static/books2.csv deleted file mode 100644 index a4c0e86..0000000 --- a/ras/api/static/books2.csv +++ /dev/null @@ -1,65 +0,0 @@ -book;author;genre;pages;readed;rating -Omnia in Omnibus;Lisa Pennings;Sciencefiction;166;2013-05-01;4 -Het leven van Pi;Yann Martel;Roman;317;2020-10-01;4 -Ze komt nooit meer terug;Hans Koppel;Thriller;220;2020-10-01;5 -Vriendschapsverzoek;Laura Marshall;Thriller;368;2020-10-01;4 -De analist;John Katzenbach;Thriller;518;2020-11-01;4 -Komt een vrouw bij de hacker;Maria Genova;Thriller;224;2020-11-01;4 -Niemand hoort het;Linwood Barclay;Thriller;304;2020-11-01;5 -Lift;Linwood Barclay;Thriller;480;2020-11-01;3 -Kijk niet weg;Linwood Barclay;Thriller;400;2020-12-01;5 -Het duistere net;Carmen Mola;Thriller;415;2020-12-01;5 -De 50/50-moorden;Steve Mosby;Thriller;344;2020-12-01;3 -Zonder een woord;Linwood Barclay;Thriller;368;2021-01-01;5 -Geen veilige plek;Linwood Barclay;Thriller;368;2021-01-01;3 -Op slot;Chris McGeorge;Thriller;320;2021-01-01;5 -Alles is eventueel / 1408;Stephen King;Thriller;462;2021-02-01;3 -Waarom je niet zomaar moet stemmen waar je ouders op stemmen;Titia Hoogendoorn&Nienke Schuitemaker;Non-fictie;125;2021-02-01;4 -Geloof je ogen;Linwood Barclay;Thriller;384;2021-02-01;4 -Voor ik ga slapen;SJ Watson;Thriller;333;2021-03-01;5 -Echo;Tamara Geraeds;Thriller;280;2021-03-01;5 -Niemand vertellen;Harlan Coben;Thriller;302;2021-03-01;4 -Ik zie je;Michael Berg;Thriller;320;2021-04-01;4 -Toevluchtsoord;Jerome Loubry;Thriller;355;2021-04-01;5 -In een donker donker bos;Ruth Ware;Thriller;320;2021-04-01;3 -Een voor een;Ruth Ware;Thriller;368;2021-04-01;4 -Vrees het ergste;Linwood Barclay;Thriller;400;2021-05-01;4 -Het poppenhuis;W.R. Dantz;Thriller;270;2021-05-01;3 -Malorie;Josh Malerman;Thriller;320;2021-05-01;4 -Opgejaagd;Gabriel Bergmoser;Thriller;256;2021-06-01;4 -Reset;Blake Crouch;Thriller;352;2021-06-01;4 -Wacht maar af;Loes den Hollander;Thriller;300;2021-06-01;4 -De Russische connectie;Gerrit Barendrecht;Thriller;320;2021-06-01;4 -Wat jij niet ziet;M.J. Arlidge;Thriller;95;2021-07-01;3 -Het ongeluk;Linwood Barclay;Thriller;382;2021-07-01;4 -Slapen in een zee van sterren;Christopher Paolini;Sciencefiction;880;2021-07-01;2 -Tik Tak;Chris McGeorge;Thriller;320;2021-07-01;4 -Gegijzeld;Clare Mackintosh;Thriller;397;2021-08-01;5 -Eindbestemming;Marjolein van der Gaag&Marcella Kleine;Thriller;158;2021-08-01;4 -Een kille rilling;Bernard Minier;Thriller;582;2021-09-01;4 -De nachtdienst;Esther Verhoef;Thriller;365;2021-09-01;5 -Kiekeboe;Chris McGeorge;Thriller;352;2021-10-01;3 -Noorderlicht;Mariska Overman;Thriller;313;2021-10-01;4 -De kleine getuige;Jilliane Hoffman;Thriller;368;2021-11-01;4 -De marathon;Stephen King;Thriller;261;2021-11-01;4 -Het appartement;Tatiana de Rosnay;Roman;215;2021-11-01;4 -De intrigant;Patricia Snel;Thriller;189;2021-12-01;4 -Een schuldig huis;Robert Goddard;Thriller;384;2021-12-01;5 -Te koop;Eva Monte;Thriller;350;2021-12-01;3 -Prison Break S1B1;Paul T. Scheuring;Thriller;221;2022-01-01;5 -Prison Break S1B2;Ed van Eeden;Thriller;272;2022-01-01;4 -Prison Break S1B3;Paul T. Scheuring;Thriller;285;2022-01-01;4 -Herfstlied;Simone van der Vlugt;Thriller;277;2022-02-01;5 -De gastenlijst;Lucy Foley;Thriller;352;2022-02-01;2 -Anomalie;Herve le Tellier;Thriller;302;2022-02-01;2 -Prison Break S2B1;Paul T. Scheuring;Thriller;207;2022-03-01;4 -Prison Break S2B2;Paul T. Scheuring;Thriller;205;2022-03-01;4 -Prison Break S2B3;Paul T. Scheuring;Thriller;245;2022-03-01;4 -Ik weet je wachtwoord;Daniel Verlaan;Non-fictie;347;2022-04-01;5 -De vrouw die een jaar in bed ging liggen;Sue Townsend;Roman;368;2022-04-01;3 -Moord in de bibliotheek;Agatha Christie;Thriller;256;2022-04-01;3 -Geestdrift;Daniel Hecht;Thriller;509;2022-05-01;1 -Moord in de Orient Expres;Agatha Christie;Thriller;222;2022-05-01;4 -Crash;Jack Bowman;Thriller;344;2022-05-01;3 -Erken mij;Esther Verhoef;Thriller;91;2022-06-01;4 -Gestrand;Sarah Goodwin;Thriller;352;2022-06-01;5 diff --git a/ras/api/static/books_data.csv b/ras/api/static/books_data.csv deleted file mode 100644 index a471197..0000000 --- a/ras/api/static/books_data.csv +++ /dev/null @@ -1,5 +0,0 @@ -year,books_read -2013,1 -2020,10 -2021,36 -2022,24 \ No newline at end of file diff --git a/ras/api/urls.py b/ras/api/urls.py index 14719fd..660857b 100644 --- a/ras/api/urls.py +++ b/ras/api/urls.py @@ -5,6 +5,7 @@ from .modules.auth import * from .modules.crud import * from .modules.challenges import * from .modules.pandas import * +from .modules.predictions import * urlpatterns = [ path('books/all', getAllBooks), @@ -25,4 +26,5 @@ urlpatterns = [ path('books/challenges', getAllChallenges), path('books/challenges/insert', addChallenge), path('books/challenges//delete', deleteChallenge), + path('books/challenges/prediction/train', predict_next_year), ] \ No newline at end of file diff --git a/ras/api/views.py b/ras/api/views.py index eeea395..f59a0b3 100644 --- a/ras/api/views.py +++ b/ras/api/views.py @@ -59,25 +59,4 @@ def getStats(request): return Response(data[0]) else: - return Response("No year header included") - - -@api_view(['GET']) -def predictAmountBooks(request): - books_data = pd.read_csv("api/static/books_data.csv") - - books_data = books_data.dropna() - - model = LinearRegression() - - X = books_data[['year']] - Y = books_data['books_read'] - model.fit(X.values, Y.values) - - current_year = 2023 - predict_books = model.predict([[current_year]]) - - return Response({ - "year": current_year, - "amount": math.floor(predict_books[0]) - }) \ No newline at end of file + return Response("No year header included") \ No newline at end of file diff --git a/ras/frontend/src/components/Data.js b/ras/frontend/src/components/Data.js index 3fa1073..5b7fe33 100644 --- a/ras/frontend/src/components/Data.js +++ b/ras/frontend/src/components/Data.js @@ -4,7 +4,8 @@ export const getAllBooks = () => { return fetch('/api/books/all', { "method": "GET", "headers": { - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') }, }) .then(response => response.json()) @@ -13,22 +14,13 @@ export const getAllBooks = () => { }) } -// export const getBooksByYear = (year) => { -// return fetch('/api/books', { -// "method": "GET", -// "headers": { -// "year": year -// } -// }) -// .then(response => response.json()) -// .then(data => { -// return data; -// }) -// } - export const getAllChallenges = () => { return fetch('/api/books/challenges', { "method": "GET", + "headers": { + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') + }, }) .then(response => response.json()) .then(data => { @@ -73,7 +65,8 @@ export const getStats = (year) => { "method": "GET", "headers": { "year": year, - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') } }) .then(response => response.json()) @@ -86,7 +79,8 @@ export const getChallenge = (year) => { return fetch('/api/books/challenge', { "method": "GET", "headers": { - "year": year + "year": year, + "userid": localStorage.getItem('id') } }) .then(response => response.json()) @@ -99,7 +93,8 @@ export const getReadingYears = () => { return fetch('/api/books/years', { "method": "GET", "headers": { - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') } }) .then(response => response.json()) @@ -108,39 +103,13 @@ export const getReadingYears = () => { }) } -// export const getCountries = (year) => { -// return fetch('/api/books/countries', { -// "method": "GET", -// "headers": { -// "year": year -// } -// }) -// .then(response => response.json()) -// .then(data => { -// return data; -// }) -// } - -// export const getShortestLongestBook = (year) => { -// return fetch('/api/books/pages/stats', { -// "method": "GET", -// "headers": { -// "year": year, -// "Authorization": "Bearer " + localStorage.getItem("token") -// } -// }) -// .then(response => response.json()) -// .then(data => { -// return data; -// }) -// } - export const getBooksPerYearPerGenres = (year) => { return fetch('/api/books/genres', { "method": "GET", "headers": { "year": year, - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') } }) .then(response => response.json()) @@ -154,7 +123,8 @@ export const getGenresCount = (year) => { "method": "GET", "headers": { "year": year, - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') } }) .then(response => response.json()) @@ -168,7 +138,8 @@ export const getAvgRatings = (year) => { "method": "GET", "headers": { "year": year, - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') } }) .then(response => response.json()) @@ -182,7 +153,8 @@ export const getRatingsCount = (year) => { "method": "GET", "headers": { "year": year, - "Authorization": "Bearer " + localStorage.getItem("token") + "Authorization": "Bearer " + localStorage.getItem("token"), + "userid": localStorage.getItem('id') } }) .then(response => response.json()) diff --git a/ras/frontend/static/.DS_Store b/ras/frontend/static/.DS_Store index 0dcca6ff047659cfae6f829d52023c140f63554e..2a9d96ca9a72035d2bb408be8d91131083e85358 100644 GIT binary patch delta 67 zcmZoMXfc=|#>B)qu~2NHo+2aP#(>?7jC`AUSY9%2mf_%Lnb^R-nVo~51E^%PAjfy+ V$^0UY91K9f$iTp|IYML&GXOYT4;TOd delta 204 zcmZoMXfc=|#>B!ku~2NHo+6|0#(>?7i&&T#g*Wpsy=1IsV#s1B_RPsoPRhwoVqjnp zU|?XB1=4!|!2rl&U;wMhNjD5m&d)6Xi$q4Qgo)?oySPC0a;&d=R={L+)Da<W*_ s17sd2)WE2OjfGu|o7p+|Ie>26{E_)P^JIPzM-E1i?Le?OLSzjy0M!gMn*aa+ diff --git a/ras/frontend/static/js/src_components_Data_js.js b/ras/frontend/static/js/src_components_Data_js.js index 5a14dc6..2ec4bec 100644 --- a/ras/frontend/static/js/src_components_Data_js.js +++ b/ras/frontend/static/js/src_components_Data_js.js @@ -1,2 +1,2 @@ /*! For license information please see src_components_Data_js.js.LICENSE.txt */ -"use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([["src_components_Data_js"],{"./src/Functions.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "initDataTable": () => (/* binding */ initDataTable),\n/* harmony export */ "readCookie": () => (/* binding */ readCookie)\n/* harmony export */ });\nconst readCookie = name => {\n var nameEQ = name + "=";\n var ca = document.cookie.split(\';\');\n for (var i = 0; i < ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == \' \') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n};\nconst initDataTable = () => {\n let table = new DataTable(\'#DataTable\');\n table.destroy();\n setTimeout(() => {\n table = new DataTable(\'#DataTable\', {\n language: {\n url: \'https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Dutch.json\',\n search: "",\n searchPlaceholder: "Zoeken"\n },\n dom: \'rt<"bottom"pl><"clear">\',\n order: []\n });\n }, 300);\n};\n\n//# sourceURL=webpack://frontend/./src/Functions.js?')},"./src/components/Data.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "deleteChallenge": () => (/* binding */ deleteChallenge),\n/* harmony export */ "getAllBooks": () => (/* binding */ getAllBooks),\n/* harmony export */ "getAllChallenges": () => (/* binding */ getAllChallenges),\n/* harmony export */ "getAvgRatings": () => (/* binding */ getAvgRatings),\n/* harmony export */ "getBooksPerYearPerGenres": () => (/* binding */ getBooksPerYearPerGenres),\n/* harmony export */ "getChallenge": () => (/* binding */ getChallenge),\n/* harmony export */ "getGenresCount": () => (/* binding */ getGenresCount),\n/* harmony export */ "getRatingsCount": () => (/* binding */ getRatingsCount),\n/* harmony export */ "getReadingYears": () => (/* binding */ getReadingYears),\n/* harmony export */ "getStats": () => (/* binding */ getStats),\n/* harmony export */ "insertChallenge": () => (/* binding */ insertChallenge)\n/* harmony export */ });\n/* harmony import */ var _Functions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Functions */ "./src/Functions.js");\n\nconst getAllBooks = () => {\n return fetch(\'/api/books/all\', {\n "method": "GET",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n// export const getBooksByYear = (year) => {\n// return fetch(\'/api/books\', {\n// "method": "GET",\n// "headers": {\n// "year": year\n// }\n// })\n// .then(response => response.json())\n// .then(data => {\n// return data;\n// })\n// }\n\nconst getAllChallenges = () => {\n return fetch(\'/api/books/challenges\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst insertChallenge = data => {\n return fetch(\'/api/books/challenges/insert\', {\n "method": "POST",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n \'Content-Type\': \'application/x-www-form-urlencoded\',\n "X-CSRFToken": (0,_Functions__WEBPACK_IMPORTED_MODULE_0__.readCookie)(\'csrftoken\')\n },\n "body": data\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst deleteChallenge = id => {\n return fetch(\'/api/books/challenges/\' + id + \'/delete\', {\n "method": "DELETE",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n \'Content-Type\': \'application/x-www-form-urlencoded\',\n "X-CSRFToken": (0,_Functions__WEBPACK_IMPORTED_MODULE_0__.readCookie)(\'csrftoken\'),\n "challengeid": id\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getStats = year => {\n return fetch(\'/api/books/stats\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getChallenge = year => {\n return fetch(\'/api/books/challenge\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getReadingYears = () => {\n return fetch(\'/api/books/years\', {\n "method": "GET",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n// export const getCountries = (year) => {\n// return fetch(\'/api/books/countries\', {\n// "method": "GET",\n// "headers": {\n// "year": year\n// }\n// })\n// .then(response => response.json())\n// .then(data => {\n// return data;\n// })\n// }\n\n// export const getShortestLongestBook = (year) => {\n// return fetch(\'/api/books/pages/stats\', {\n// "method": "GET",\n// "headers": {\n// "year": year,\n// "Authorization": "Bearer " + localStorage.getItem("token")\n// }\n// })\n// .then(response => response.json())\n// .then(data => {\n// return data;\n// })\n// }\n\nconst getBooksPerYearPerGenres = year => {\n return fetch(\'/api/books/genres\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getGenresCount = year => {\n return fetch(\'/api/books/genres/count\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getAvgRatings = year => {\n return fetch(\'/api/books/ratings\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getRatingsCount = year => {\n return fetch(\'/api/books/ratings/count\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token")\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n//# sourceURL=webpack://frontend/./src/components/Data.js?')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([["src_components_Data_js"],{"./src/Functions.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "initDataTable": () => (/* binding */ initDataTable),\n/* harmony export */ "readCookie": () => (/* binding */ readCookie)\n/* harmony export */ });\nconst readCookie = name => {\n var nameEQ = name + "=";\n var ca = document.cookie.split(\';\');\n for (var i = 0; i < ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == \' \') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n};\nconst initDataTable = () => {\n let table = new DataTable(\'#DataTable\');\n table.destroy();\n setTimeout(() => {\n table = new DataTable(\'#DataTable\', {\n language: {\n url: \'https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Dutch.json\',\n search: "",\n searchPlaceholder: "Zoeken"\n },\n dom: \'rt<"bottom"pl><"clear">\',\n order: []\n });\n }, 300);\n};\n\n//# sourceURL=webpack://frontend/./src/Functions.js?')},"./src/components/Data.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "deleteChallenge": () => (/* binding */ deleteChallenge),\n/* harmony export */ "getAllBooks": () => (/* binding */ getAllBooks),\n/* harmony export */ "getAllChallenges": () => (/* binding */ getAllChallenges),\n/* harmony export */ "getAvgRatings": () => (/* binding */ getAvgRatings),\n/* harmony export */ "getBooksPerYearPerGenres": () => (/* binding */ getBooksPerYearPerGenres),\n/* harmony export */ "getChallenge": () => (/* binding */ getChallenge),\n/* harmony export */ "getGenresCount": () => (/* binding */ getGenresCount),\n/* harmony export */ "getRatingsCount": () => (/* binding */ getRatingsCount),\n/* harmony export */ "getReadingYears": () => (/* binding */ getReadingYears),\n/* harmony export */ "getStats": () => (/* binding */ getStats),\n/* harmony export */ "insertChallenge": () => (/* binding */ insertChallenge)\n/* harmony export */ });\n/* harmony import */ var _Functions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Functions */ "./src/Functions.js");\n\nconst getAllBooks = () => {\n return fetch(\'/api/books/all\', {\n "method": "GET",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getAllChallenges = () => {\n return fetch(\'/api/books/challenges\', {\n "method": "GET",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst insertChallenge = data => {\n return fetch(\'/api/books/challenges/insert\', {\n "method": "POST",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n \'Content-Type\': \'application/x-www-form-urlencoded\',\n "X-CSRFToken": (0,_Functions__WEBPACK_IMPORTED_MODULE_0__.readCookie)(\'csrftoken\')\n },\n "body": data\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst deleteChallenge = id => {\n return fetch(\'/api/books/challenges/\' + id + \'/delete\', {\n "method": "DELETE",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n \'Content-Type\': \'application/x-www-form-urlencoded\',\n "X-CSRFToken": (0,_Functions__WEBPACK_IMPORTED_MODULE_0__.readCookie)(\'csrftoken\'),\n "challengeid": id\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getStats = year => {\n return fetch(\'/api/books/stats\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getChallenge = year => {\n return fetch(\'/api/books/challenge\', {\n "method": "GET",\n "headers": {\n "year": year,\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getReadingYears = () => {\n return fetch(\'/api/books/years\', {\n "method": "GET",\n "headers": {\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getBooksPerYearPerGenres = year => {\n return fetch(\'/api/books/genres\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getGenresCount = year => {\n return fetch(\'/api/books/genres/count\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getAvgRatings = year => {\n return fetch(\'/api/books/ratings\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getRatingsCount = year => {\n return fetch(\'/api/books/ratings/count\', {\n "method": "GET",\n "headers": {\n "year": year,\n "Authorization": "Bearer " + localStorage.getItem("token"),\n "userid": localStorage.getItem(\'id\')\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n//# sourceURL=webpack://frontend/./src/components/Data.js?')}}]); \ No newline at end of file