From 84a0be36039630bbaea780b91901863b702d9e18 Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Sat, 12 Aug 2023 11:10:11 -0400 Subject: [PATCH 01/10] static pages --- server/db.sqlite3 | Bin 0 -> 131072 bytes .../djangoapp/templates/djangoapp/about.html | 5 +++ .../templates/djangoapp/contact.html | 15 +++++++++ .../djangoapp/templates/djangoapp/index.html | 31 ++++++++++++++++-- server/djangoapp/urls.py | 2 ++ server/djangoapp/views.py | 11 +++++-- 6 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 server/db.sqlite3 create mode 100644 server/djangoapp/templates/djangoapp/about.html create mode 100644 server/djangoapp/templates/djangoapp/contact.html diff --git a/server/db.sqlite3 b/server/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..5ccc57f1d5bcfe4d278dd16c0f46df62d4e702bc GIT binary patch literal 131072 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 GA@Ki}k@rXd literal 0 HcmV?d00001 diff --git a/server/djangoapp/templates/djangoapp/about.html b/server/djangoapp/templates/djangoapp/about.html new file mode 100644 index 0000000000..bb525d5275 --- /dev/null +++ b/server/djangoapp/templates/djangoapp/about.html @@ -0,0 +1,5 @@ + +

+Welcome to Best Cars dealership, home to the best cars in North America. We sell domestic and imported cars at reasonable prices. +

+ \ No newline at end of file diff --git a/server/djangoapp/templates/djangoapp/contact.html b/server/djangoapp/templates/djangoapp/contact.html new file mode 100644 index 0000000000..289c139c79 --- /dev/null +++ b/server/djangoapp/templates/djangoapp/contact.html @@ -0,0 +1,15 @@ + + + +
+

+ Contact information +

+
+
    Phone No: 555 834 6626
+
    Email: EpicCars11@gmail.com"
+
    Address:1818 West Way Ct.
+
+
+ + \ No newline at end of file diff --git a/server/djangoapp/templates/djangoapp/index.html b/server/djangoapp/templates/djangoapp/index.html index 1a9ee6e39a..135f3b0953 100644 --- a/server/djangoapp/templates/djangoapp/index.html +++ b/server/djangoapp/templates/djangoapp/index.html @@ -14,9 +14,36 @@ - - This is the index page of your Django app! + diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 37b1c89d01..74ec8bac82 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -10,8 +10,10 @@ # name the URL # path for about view + path(route='about/', view=views.about, name='about'), # path for contact us view + path(route='contact/', view=views.contact, name='contact'), # path for registration diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index 61cc664da0..a0a3ac37d7 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -18,12 +18,17 @@ # Create an `about` view to render a static about page -# def about(request): -# ... +def about(request): + context = {} + if request.method == "GET": + return render(request, 'djangoapp/about.html', context) # Create a `contact` view to return a static contact page -#def contact(request): +def contact(request): + context = {} + if request.method == "GET": + return render(request, 'djangoapp/contact.html', context) # Create a `login_request` view to handle sign in request # def login_request(request): From b29538027e6746d04226376c16ee2d3b5e54025b Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Sun, 13 Aug 2023 11:02:42 -0400 Subject: [PATCH 02/10] login/logout --- server/db.sqlite3 | Bin 131072 -> 131072 bytes .../djangoapp/templates/djangoapp/about.html | 52 ++++++++++++-- .../templates/djangoapp/contact.html | 40 +++++++++++ .../djangoapp/templates/djangoapp/index.html | 6 +- .../templates/djangoapp/registration.html | 27 +++++++ server/djangoapp/urls.py | 4 ++ server/djangoapp/views.py | 67 +++++++++++++++--- 7 files changed, 178 insertions(+), 18 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 5ccc57f1d5bcfe4d278dd16c0f46df62d4e702bc..cb191c68e26734b3d62fb2e671eaaf23b2f0fd64 100644 GIT binary patch delta 2459 zcmai!-H+pD6~>eC%xEb!I30~vqhF6SezK?y6!m6 z@|g}m7HNjUC~RF_y|wlEaQEN%|HJj1zFzXAz7bW#y;<3+xQ*_@(3`UuEax)CViUmK%|H zwG&P!Vj^gc#ETHJkih-h3Dub3%XuVQdI%}c4q{!3EQd4=XpJv?7Esz1wia-jAJ?XB z2CGTa^P~1*jjhQO9aOp#Tk3}+wQ_LY^-h&j*Tkwfu#h8(A|wFBDF0T1)d_dx*|9O# zFm^doM?nB6YdldRDw+Y+WEWT1D#>Z%%0X#1Y>az+Ngowry=ynk3Nde$rw0r9tfJRr zR}+sHYB;%p#W@TVNyxAS>F*?1Y@$1wXKONsn-Uc>a|XuYQd*2>fd&a|ieF&`z?I2C zsiKnM0yA{4RGUz}g?QXE%pQ+-RJn8{N)?4}PVmC3#xifaOcAMK7;GxoJA2yukseKl!H6}b|&GK>6 zEnyRC97`T{hgqQ^4X=q}^)v`vPvri(OT8<35F1rhY(Ugfe@0Y#dv`duE##5cd zP8LdmCQfNqx{k$24p2pmge*h8|4w>G{9&8dZPhn)mted_6cDO1nNM&R_^KgaXftO{ z7nNGnGb@#oxxqJE%CLm%g614Ag*r=8!h(;wo;GS@9wo|a?*x9?R|`YdCk&!)^n+80 zjoLxg@XIDUb~?=BsCz`69|35zVKAF_;vU`-3NQv%t#H;HLYfk^I`I8=b$IABFRBM- zL`Ez@mHVbN5lns>gJx5sD#uHW5n2wJ%q{%BSCZyxLvvA!7PvNt8*N*1_?@+_;@IZQA^KF29vDZJKiVKUZ#; zawq9}v4`YfJ862E;*q53Mf&_sBG9dO5i$ERF(v8#p9k-M{QHm7+i$;~L9;3JujohU zZ_pp1Dtd^13(e;Lak=^=pMLO|e{=Z_gil`=@MaWeo>Sh4%-hc?Z$#UzXUm%rw6iWp fH{hFDvHk4pV8heMv*k_iZM}u?+3TBO8=Cts)%U^x delta 126 zcmZo@;Am*zm>|t4JyFJ)QF>#-B6*P&3~c;m4E!(ouki2YFXQj#pT%FXu`z*va+$u0 z8V?_{JV#<_Nk)8WacU6*1A{OSBLi_(W@E -

-Welcome to Best Cars dealership, home to the best cars in North America. We sell domestic and imported cars at reasonable prices. -

+ + + + + Dealership Review + + + + + + + + + + + +

+ Welcome to Best Cars dealership, home to the best cars in North America. We sell domestic and imported cars at reasonable prices. +

+ \ No newline at end of file diff --git a/server/djangoapp/templates/djangoapp/contact.html b/server/djangoapp/templates/djangoapp/contact.html index 289c139c79..37f4d1cf48 100644 --- a/server/djangoapp/templates/djangoapp/contact.html +++ b/server/djangoapp/templates/djangoapp/contact.html @@ -1,6 +1,46 @@ + + + Dealership Review + + + + + + + + +

Contact information diff --git a/server/djangoapp/templates/djangoapp/index.html b/server/djangoapp/templates/djangoapp/index.html index 135f3b0953..0e01dde302 100644 --- a/server/djangoapp/templates/djangoapp/index.html +++ b/server/djangoapp/templates/djangoapp/index.html @@ -26,17 +26,17 @@ {% if user.is_authenticated %}

  • {{ user.first_name }}({{ user.username }}) - Logout + Logout
  • {% else %}
  • -
    + {% csrf_token %}
    - Sign Up + Sign Up
  • diff --git a/server/djangoapp/templates/djangoapp/registration.html b/server/djangoapp/templates/djangoapp/registration.html index ae11ea4b71..f33fd2c561 100644 --- a/server/djangoapp/templates/djangoapp/registration.html +++ b/server/djangoapp/templates/djangoapp/registration.html @@ -7,5 +7,32 @@ + +
    +
    +

    Sign Up

    +
    + + + + + + + + +
    + {% csrf_token %} + +
    +
    +
    \ No newline at end of file diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 74ec8bac82..deec333119 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -16,11 +16,15 @@ path(route='contact/', view=views.contact, name='contact'), # path for registration + path(route='registration/', view=views.registration_request, name='registration'), # path for login + path(route='login/', view=views.login_request, name='login'), # path for logout + path(route='logout/', view=views.logout_request, name='logout'), + #path for home path(route='', view=views.get_dealerships, name='index'), # path for dealer reviews view diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index a0a3ac37d7..b039e888a6 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -31,16 +31,35 @@ def contact(request): return render(request, 'djangoapp/contact.html', context) # Create a `login_request` view to handle sign in request -# def login_request(request): -# ... +def login_request(request): + # Handles POST request + if request.method == "POST": + # Get username and password from request.POST dictionary + username = request.POST['username'] + password = request.POST['psw'] + # Try to check if provide credential can be authenticated + user = authenticate(username=username, password=password) + if user is not None: + # If user is valid, call login method to login current user + login(request, user) + return redirect('djangoapp:index') + else: + # If not, return to login page again + return redirect('djangoapp:index') + else: + return redirect('djangoapp:index') # Create a `logout_request` view to handle sign out request -# def logout_request(request): -# ... +def logout_request(request): + # Get the user object based on session id in request + print("Log out the user `{}`".format(request.user.username)) + # Logout user in the request + logout(request) + # Redirect user back to course list view + return redirect('djangoapp:index') -# Create a `registration_request` view to handle sign up request -# def registration_request(request): -# ... + +# Create a `get_dealer_details` view to render the reviews of a dealer # Update the `get_dealerships` view to render the index page with a list of dealerships def get_dealerships(request): @@ -48,10 +67,36 @@ def get_dealerships(request): if request.method == "GET": return render(request, 'djangoapp/index.html', context) - -# Create a `get_dealer_details` view to render the reviews of a dealer -# def get_dealer_details(request, dealer_id): -# ... +# Create a `registration_request` view to handle sign up request +def registration_request(request): + context = {} + # If it is a GET request, just render the registration page + if request.method == 'GET': + return render(request, 'djangoapp/registration.html', context) + # If it is a POST request + elif request.method == 'POST': + # Get user information from request.POST + username = request.POST['username'] + password = request.POST['psw'] + first_name = request.POST['firstname'] + last_name = request.POST['lastname'] + user_exist = False + try: + # Check if user already exists + User.objects.get(username=username) + user_exist = True + except: + # If not, simply log this is a new user + logger.debug("{} is new user".format(username)) + # If it is a new user + if not user_exist: + # Create user in auth_user table + user = User.objects.create_user(username=username, first_name=first_name, last_name=last_name, password=password) + # Login the user and redirect to course list page + login(request, user) + return redirect("djangoapp:index") + else: + return render(request, 'djangoapp/registration.html', context) # Create a `add_review` view to submit a review # def add_review(request, dealer_id): From 0081e306d7f495f0ba9aded39e30187d27949750 Mon Sep 17 00:00:00 2001 From: JPigeon252 <112897252+JPigeon252@users.noreply.github.com> Date: Sun, 13 Aug 2023 10:11:56 -0500 Subject: [PATCH 03/10] Update linter.yml --- .github/workflows/linter.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 05ca50d23b..9ddbb6b27f 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -15,14 +15,11 @@ jobs: # list of things to do uses: actions/setup-node@v3 with: node-version: 16 - - name: Code Checkout uses: actions/checkout@v3 - - name: Install Dependencies run: npm install working-directory: functions/sample/nodejs - - name: Code Linting run: npm run lint working-directory: functions/sample/nodejs From 9d316843c01e972cf0e261648bdca89832aeb261 Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Thu, 17 Aug 2023 09:56:11 -0400 Subject: [PATCH 04/10] reviews and dealerships --- functions/sample/get-dealership.js | 86 ++++++++++++++++++++++++++++++ functions/sample/get-review.py | 31 +++++++++++ functions/sample/post-review.py | 34 ++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 functions/sample/get-dealership.js create mode 100644 functions/sample/get-review.py create mode 100644 functions/sample/post-review.py diff --git a/functions/sample/get-dealership.js b/functions/sample/get-dealership.js new file mode 100644 index 0000000000..1872ad78b9 --- /dev/null +++ b/functions/sample/get-dealership.js @@ -0,0 +1,86 @@ +const { CloudantV1 } = require('@ibm-cloud/cloudant'); +const { IamAuthenticator } = require('ibm-cloud-sdk-core'); + +async function main(params) { + const authenticator = new IamAuthenticator({ apikey: params.IAM_API_KEY }) + const cloudant = CloudantV1.newInstance({ + authenticator: authenticator + }); + cloudant.setServiceUrl(params.COUCH_URL); + + let { state, id } = params; + var dealershipList; + var dealershipListPromise; + + if (state) { + dealershipListPromise = await getMatchingRecords(cloudant, "dealerships", {state: state}) + // dealershipList = formatEntriesMatch(dealershipListPromise); + } else if (id) { + id = parseInt(id) + dealershipListPromise = await getMatchingRecords(cloudant, "dealerships", {id: id}) + } else { + dealershipListPromise = await getAllRecords(cloudant, "dealerships"); + // dealershipList = formatEntries(dealershipListPromise); + } + + return { + 'headers': {'Content-Type':'application/json'}, + 'body': dealershipListPromise + }; +} + +function getAllRecords(cloudant,dbname) { + return new Promise((resolve, reject) => { + cloudant.postAllDocs({ db: dbname, includeDocs: true, limit: 10 }) + .then((result)=>{ + resolve({rows: result.result.rows}); + }) + .catch(err => { + console.log(err); + reject({ err: err }); + }); + }) +} + +function getMatchingRecords(cloudant,dbname, selector) { + return new Promise((resolve, reject) => { + cloudant.postFind({db:dbname,selector:selector}) + .then((result)=>{ + resolve({rows: result.result.docs}); + }) + .catch(err => { + console.log(err); + reject({ err: err }); + }); + }) +} + +function formatEntries(entries) { + let result = entries.result.map((row) => { return { + id: row.doc.id, + city: row.doc.city, + state: row.doc.state, + st: row.doc.st, + address: row.doc.address, + zip: row.doc.zip, + lat: row.doc.lat, + long: row.doc.long, + }}); + + return {dealerships: result}; +} + +function formatEntriesMatch(entries) { + let result = entries.result.map((row) => { return { + id: row.id, + city: row.city, + state: row.state, + st: row.st, + address: row.address, + zip: row.zip, + lat: row.lat, + long: row.long, + }}); + + return {dealerships: result}; +} \ No newline at end of file diff --git a/functions/sample/get-review.py b/functions/sample/get-review.py new file mode 100644 index 0000000000..0baafbb6e2 --- /dev/null +++ b/functions/sample/get-review.py @@ -0,0 +1,31 @@ +import sys + +from ibmcloudant.cloudant_v1 import CloudantV1 +from ibm_cloud_sdk_core.authenticators import IAMAuthenticator + +def main(param_dict): + authenticator = IAMAuthenticator(param_dict["IAM_API_KEY"]) + service = CloudantV1(authenticator=authenticator) + service.set_service_url(param_dict["COUCH_URL"]) + + selector = {} + if param_dict["dealerId"] is not None and param_dict["dealerId"] != "": + selector = {'dealership': {'$eq': int(param_dict["dealerId"])}} + + try: + response = service.post_find( + db='reviews', + selector=selector, + ).get_result() + # result_by_filter=my_database.get_query_result(selector,raw_result=True) + result= { + 'headers': {'Content-Type':'application/json'}, + 'body': {'data':response["bookmark"]} + } + return response + except: + return { + 'statusCode': 404, + 'message':"dealerId does not exist" + } + \ No newline at end of file diff --git a/functions/sample/post-review.py b/functions/sample/post-review.py new file mode 100644 index 0000000000..fe24dbde68 --- /dev/null +++ b/functions/sample/post-review.py @@ -0,0 +1,34 @@ +import sys + +from ibmcloudant.cloudant_v1 import CloudantV1, Document +from ibm_cloud_sdk_core.authenticators import IAMAuthenticator +from ibm_cloud_sdk_core import ApiException + +def main(param_dict): + authenticator = IAMAuthenticator(param_dict["IAM_API_KEY"]) + service = CloudantV1(authenticator=authenticator) + service.set_service_url(param_dict["COUCH_URL"]) + + + try: + response = service.post_document( + db='reviews', + document=param_dict["review"], + ).get_result() + # result_by_filter=my_database.get_query_result(selector,raw_result=True) + result= { + 'headers': {'Content-Type':'application/json'}, + 'body': {'data':response} + } + return result + except ApiException as ae: + errorBody = {"error": ae.message} + if ("reason" in ae.http_response.json()): + errorBody["reason"] = ae.http_response.json()["reason"] + + return errorBody + except: + return { + 'statusCode': 500, + 'message': "Something went wrong on the server" + } \ No newline at end of file From e2c1e57703a74117786df0f523d37f276e8d5305 Mon Sep 17 00:00:00 2001 From: JPigeons252 Date: Fri, 18 Aug 2023 08:34:10 -0400 Subject: [PATCH 05/10] carmake --- server/db.sqlite3 | Bin 131072 -> 143360 bytes server/djangoapp/admin.py | 11 ++++++++++- server/djangoapp/models.py | 36 +++++++++++++++++++++--------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index cb191c68e26734b3d62fb2e671eaaf23b2f0fd64..22b415d9b5c8ebce5fdaa9280b068223db6fafa7 100644 GIT binary patch delta 2957 zcmb7GeQaA-6@S;yiQlvHe3Lk7)TE7HoOoT-I(g4uaomp1O`Xh1{Lv&$nryA(j~Dy- zJGSG**&_E9B&1e|mIzs5NTUM&Kthu&7g>T0O$ZnQv`&akD-^X7n#LwzXlN8cVch4$ zu9FlhEcx2+oZtQ3-#z!-bKd34#O3?M^`5pDFbwNQ-`Z#D#t8#>p|t!8Bzh@iR4KZ* zWvyC?qPrygQQm4)HDPM4Eg117LP=jLwS80F*=C_xy_Gdt8RHPkGDg-^_VnD6b`a2j z!4IJU{s89SHTYe)3>_t*2l5>_t^+$1USBZIC%my_NYdGgvt*sv8}Oy$$siZ&fcWq} zvoFf2n(^bnx0VfiQ(QXEXEJ;;K~ogoM^ufWbaE{Pf4%+n;ofFxR}*dk#lA35*$K3x z&e~S%znuUduIY*Mp|mfH*fJ_P0ub;L2LB9y0e=Huhu?sgU>0603FA=LDOLCE&Ou=i z#UfS2A*uT4UaPnT+4i;5c@&O|82l5w1Ah)*gRj7=Fas}^1UuAq5K>ItQ{VY6SEmeF zkM6OGT-#UOn>bBvZOc4ttFndq8+D)hCG~yk+thVxt0b7HZS|$50+Hjn^=b%_D!M}o z1_6O4b6KutRPPuAVRVpnV{e-j^aH{d4Ax*rRZ?&a$m(>Wgd?3&a2&`Q_(W^Zjy` zSM=UY*rzv{2lT9&VVHq&Pt-QUuh=4!j_iOb=I~tD7)dRz8dziU{J4L3#o1F@&cy(t&*cYrt%ct@}-t8 z#Z7skBn0IJa79fvIX~~T#W(Yj&7?VyViLxHDVkqhiKS!fY$Wdw<}HaxbcmbWn2*@) z?seXF&gSus>6dKdJ?cA>S;MGCNl`15pnbW|tz9Ir~CnWi}fgxsY+s zZrB$>ZjU}c>)CV$7b8saxl}G%h~NVO$SQPw701qcaxUWNs{+IFn0ovu-!bX4W{5S?isecLxlCRECf4oWiJ%Va1xU zdkSU~J7O%~d^sRJL@IA#@Hyoj_!Za>?<)VTyag*TUJ|~h)DGZI@T35e?72ECQn&jKqh!8|vF=}IaAu7k=u4loB)hw3$`{-^l8IC!n{_bEVju<{SEHf$A> zpCZ3Q{EldE{s^ramps6);crNO4BnD_5sYA~%5PE+cW3iA1naz5<1k_Dq^xUr7+f)B zef}6%FC(>keZbH+HeH1&C!slReRI9zA#7xr)Dzw&4bwA=MKw1$3K)3C5+ z@XFFDSr^NKFL)mlS&{#sB+dVdtvCfOQdCUx&iLG0=4e1zXgV&8HepL*Ec+ z1juu~w1y7)vRvaC)wWVR7XzBMy;4zVi=R!RaxX7~`#3{L;HMb;C;YVBcKJhynkc$9 z5-AQyLTro&ozkikm2lD7jG%zm!QRtTivgi@yFB% zG-%k@!bKQL9@Nwy0eg3V)h=9b>mqQ+QU~@OMZkU?QK&U$w2BBrk9Cap2*Mm=_cs5% z+Qj4?>_M>Orv2{&`_)yU-8;}n@;+CM<9>l6w*N4~YKQl{IqXp=f-1{*!M9X6sr;xS z`wRHJQr(N&cC+kpJ%%ijpMeK*@mK)7jltWflm7&s90pQMJJpzhPsqO=g7+}^9wK-P s>YoBKOe^W>BO6nI8Fe~bj(MBwQErMC2f&9Ie2DJU$51Aw2Tqdz0mph^DgXcg delta 654 zcmXw%Uq}>j5XXPBzjb%ryWKf=O%DX^N-Z#x5(y$PE7CAJAB5;7?@+nUx;yba%?P^R z>s_ViA@@*W7rg`_EL-e@3gSypR2unkWt`DCvp~HAj0|bX6Iw(qXojJ>xY22MK<~_c(=vn8c@e-C#bf z)&*Jv{@B2k&c2@hP%s(|M#64Ip&sck4D?50eT1a%*Od#jw1Cz_=I1HUn+2WHTB*C& z9}Yx1{oSEpxbs>hum@-z{D+}npx-}WcZ+JWtw+El!Eg8qKi~{L#H7K7Fr91~b_tju zxQ;n|iPJcN34;w{I^n%R-D*WzY(HYK6~(N$`~_sHY6LH+ld5JgUNyDwhRrZfa0BzW zY8J&8(9GYea+OGqEKxtIJ<4}wSfS24&QeEKzG<*-nFISG9x$`_y7&@F%@J%>b2x_k zaY@}q3qu$(*aH=+Qp{uKCTl#@jj^;iZ>wlTGnOCm?UVU&f|csK!bM?D8FD6s;)09( zxMOSAxnEZGNyvgR`i7HPlO~p4tpyg%z)Vg zjou~N?mPU;nPe9<@OFJP#SUAuU2s6OUNpm7F4NcsQ`Xs57y*z?Sl;nInstqh^3?70 nWyE=~_dV#ed`s|HrxF%g;t%+&{%KT^YA(yHZG)WAcVPWD_L9Yn diff --git a/server/djangoapp/admin.py b/server/djangoapp/admin.py index b1039e16b8..763f4c73ca 100644 --- a/server/djangoapp/admin.py +++ b/server/djangoapp/admin.py @@ -1,13 +1,22 @@ from django.contrib import admin -# from .models import related models +from .models import CarMake, CarModel # Register your models here. # CarModelInline class +class CarModelInline(admin.StackedInline): + model = CarModel # CarModelAdmin class +class CarModelAdmin(admin.ModelAdmin): + list_display = ('name',) # CarMakeAdmin class with CarModelInline +class CarMakeAdmin(admin.ModelAdmin): + inlines = [CarModelInline] + list_display = ('name',) # Register models here +admin.site.register(CarMake, CarMakeAdmin) +admin.site.register(CarModel, CarModelAdmin) diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index 27d96f4eff..17a4a72990 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -4,21 +4,27 @@ # Create your models here. -# Create a Car Make model `class CarMake(models.Model)`: -# - Name -# - Description -# - Any other fields you would like to include in car make model -# - __str__ method to print a car make object - - -# Create a Car Model model `class CarModel(models.Model):`: -# - Many-To-One relationship to Car Make model (One Car Make has many Car Models, using ForeignKey field) -# - Name -# - Dealer id, used to refer a dealer created in cloudant database -# - Type (CharField with a choices argument to provide limited choices such as Sedan, SUV, WAGON, etc.) -# - Year (DateField) -# - Any other fields you would like to include in car model -# - __str__ method to print a car make object +# Create a Car Make model +class CarMake(models.Model): + name = models.CharField(max_length=50) + description = models.CharField(max_length=500) + + def __str__(self): + return self.name + ": " + self.description + + + +# Create a Car Model model +class CarModel(models.Model): + car_make = models.ForeignKey(CarMake, on_delete=models.CASCADE) + name = models.CharField(max_length=50) + dealer_id = models.IntegerField() + car_type = models.CharField(max_length=20, choices=(('SEDAN', 'SEDAN',), ('SUV', 'SUV'), ('HATCHBACK', 'HATCHBACK'),('WAGON', 'WAGON'),('MINIVAN', 'MINIVAN'))) + year = models.DateField() + + def __str__(self): + return self.name + # Create a plain Python class `CarDealer` to hold dealer data From 54c1165c47870022bda7ea3f55b99d0ec93ba6db Mon Sep 17 00:00:00 2001 From: JPigeons252 Date: Fri, 18 Aug 2023 09:43:56 -0400 Subject: [PATCH 06/10] tbc --- server/djangoapp/models.py | 23 +++++++++++++++++++++++ server/djangoapp/restapis.py | 35 +++++++++++++++++++++++++++++++++-- server/djangoapp/views.py | 22 +++++++++++++--------- 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index 17a4a72990..3becc9162b 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -28,6 +28,29 @@ def __str__(self): # Create a plain Python class `CarDealer` to hold dealer data +class CarDealer: + + def __init__(self, address, city, full_name, id, lat, long, short_name, st, zip): + # Dealer address + self.address = address + # Dealer city + self.city = city + # Dealer Full Name + self.full_name = full_name + # Dealer id + self.id = id + # Location lat + self.lat = lat + # Location long + self.long = long + # Dealer short name + self.short_name = short_name + # Dealer state + self.st = st + # Dealer zip + self.zip = zip + def __str__(self): + return "Dealer name: " + self.full_name # Create a plain Python class `DealerReview` to hold review data diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index b4d13f596a..f418cc5e39 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -1,13 +1,26 @@ import requests import json -# import related models here +from .models import CarDealer, DealerReview from requests.auth import HTTPBasicAuth # Create a `get_request` to make HTTP GET requests # e.g., response = requests.get(url, params=params, headers={'Content-Type': 'application/json'}, # auth=HTTPBasicAuth('apikey', api_key)) - +def get_request(url, **kwargs): + print(kwargs) + print("GET from {} ".format(url)) + try: + # Call get method of requests library with URL and parameters + response = requests.get(url, headers={'Content-Type': 'application/json'}, + params=kwargs) + except: + # If any error occurs + print("Network exception occurred") + status_code = response.status_code + print("With status {} ".format(status_code)) + json_data = json.loads(response.text) + return json_data # Create a `post_request` to make HTTP POST requests # e.g., response = requests.post(url, params=kwargs, json=payload) @@ -17,7 +30,25 @@ # def get_dealers_from_cf(url, **kwargs): # - Call get_request() with specified arguments # - Parse JSON results into a CarDealer object list +def get_dealers_from_cf(url, **kwargs): + results = [] + # Call get_request with a URL parameter + json_result = get_request(url) + if json_result: + # Get the row list in JSON as dealers + dealers = json_result["rows"] + # For each dealer object + for dealer in dealers: + # Get its content in `doc` object + dealer_doc = dealer["doc"] + # Create a CarDealer object with values in `doc` object + dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], full_name=dealer_doc["full_name"], + id=dealer_doc["id"], lat=dealer_doc["lat"], long=dealer_doc["long"], + short_name=dealer_doc["short_name"], + st=dealer_doc["st"], zip=dealer_doc["zip"]) + results.append(dealer_obj) + return results # Create a get_dealer_reviews_from_cf method to get reviews by dealer id from a cloud function # def get_dealer_by_id_from_cf(url, dealerId): diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index b039e888a6..0af432c454 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -58,15 +58,6 @@ def logout_request(request): # Redirect user back to course list view return redirect('djangoapp:index') - -# Create a `get_dealer_details` view to render the reviews of a dealer - -# Update the `get_dealerships` view to render the index page with a list of dealerships -def get_dealerships(request): - context = {} - if request.method == "GET": - return render(request, 'djangoapp/index.html', context) - # Create a `registration_request` view to handle sign up request def registration_request(request): context = {} @@ -98,6 +89,19 @@ def registration_request(request): else: return render(request, 'djangoapp/registration.html', context) +# Update the `get_dealerships` view to render the index page with a list of dealerships +def get_dealerships(request): + if request.method == "GET": + url = "your-cloud-function-domain/dealerships/dealer-get" + # Get dealers from the URL + dealerships = get_dealers_from_cf(url) + # Concat all dealer's short name + dealer_names = ' '.join([dealer.short_name for dealer in dealerships]) + # Return a list of dealer short name + return HttpResponse(dealer_names) + +# Create a `get_dealer_details` view to render the reviews of a dealer + # Create a `add_review` view to submit a review # def add_review(request, dealer_id): # ... From cae1b4251f08a0c33dd7689c76af4748c0810692 Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Sat, 19 Aug 2023 13:49:38 -0400 Subject: [PATCH 07/10] cleaned out some files --- functions/sample/get-dealership.js | 86 ------------------------------ functions/sample/get-review.py | 31 ----------- functions/sample/post-review.py | 34 ------------ 3 files changed, 151 deletions(-) delete mode 100644 functions/sample/get-dealership.js delete mode 100644 functions/sample/get-review.py delete mode 100644 functions/sample/post-review.py diff --git a/functions/sample/get-dealership.js b/functions/sample/get-dealership.js deleted file mode 100644 index 1872ad78b9..0000000000 --- a/functions/sample/get-dealership.js +++ /dev/null @@ -1,86 +0,0 @@ -const { CloudantV1 } = require('@ibm-cloud/cloudant'); -const { IamAuthenticator } = require('ibm-cloud-sdk-core'); - -async function main(params) { - const authenticator = new IamAuthenticator({ apikey: params.IAM_API_KEY }) - const cloudant = CloudantV1.newInstance({ - authenticator: authenticator - }); - cloudant.setServiceUrl(params.COUCH_URL); - - let { state, id } = params; - var dealershipList; - var dealershipListPromise; - - if (state) { - dealershipListPromise = await getMatchingRecords(cloudant, "dealerships", {state: state}) - // dealershipList = formatEntriesMatch(dealershipListPromise); - } else if (id) { - id = parseInt(id) - dealershipListPromise = await getMatchingRecords(cloudant, "dealerships", {id: id}) - } else { - dealershipListPromise = await getAllRecords(cloudant, "dealerships"); - // dealershipList = formatEntries(dealershipListPromise); - } - - return { - 'headers': {'Content-Type':'application/json'}, - 'body': dealershipListPromise - }; -} - -function getAllRecords(cloudant,dbname) { - return new Promise((resolve, reject) => { - cloudant.postAllDocs({ db: dbname, includeDocs: true, limit: 10 }) - .then((result)=>{ - resolve({rows: result.result.rows}); - }) - .catch(err => { - console.log(err); - reject({ err: err }); - }); - }) -} - -function getMatchingRecords(cloudant,dbname, selector) { - return new Promise((resolve, reject) => { - cloudant.postFind({db:dbname,selector:selector}) - .then((result)=>{ - resolve({rows: result.result.docs}); - }) - .catch(err => { - console.log(err); - reject({ err: err }); - }); - }) -} - -function formatEntries(entries) { - let result = entries.result.map((row) => { return { - id: row.doc.id, - city: row.doc.city, - state: row.doc.state, - st: row.doc.st, - address: row.doc.address, - zip: row.doc.zip, - lat: row.doc.lat, - long: row.doc.long, - }}); - - return {dealerships: result}; -} - -function formatEntriesMatch(entries) { - let result = entries.result.map((row) => { return { - id: row.id, - city: row.city, - state: row.state, - st: row.st, - address: row.address, - zip: row.zip, - lat: row.lat, - long: row.long, - }}); - - return {dealerships: result}; -} \ No newline at end of file diff --git a/functions/sample/get-review.py b/functions/sample/get-review.py deleted file mode 100644 index 0baafbb6e2..0000000000 --- a/functions/sample/get-review.py +++ /dev/null @@ -1,31 +0,0 @@ -import sys - -from ibmcloudant.cloudant_v1 import CloudantV1 -from ibm_cloud_sdk_core.authenticators import IAMAuthenticator - -def main(param_dict): - authenticator = IAMAuthenticator(param_dict["IAM_API_KEY"]) - service = CloudantV1(authenticator=authenticator) - service.set_service_url(param_dict["COUCH_URL"]) - - selector = {} - if param_dict["dealerId"] is not None and param_dict["dealerId"] != "": - selector = {'dealership': {'$eq': int(param_dict["dealerId"])}} - - try: - response = service.post_find( - db='reviews', - selector=selector, - ).get_result() - # result_by_filter=my_database.get_query_result(selector,raw_result=True) - result= { - 'headers': {'Content-Type':'application/json'}, - 'body': {'data':response["bookmark"]} - } - return response - except: - return { - 'statusCode': 404, - 'message':"dealerId does not exist" - } - \ No newline at end of file diff --git a/functions/sample/post-review.py b/functions/sample/post-review.py deleted file mode 100644 index fe24dbde68..0000000000 --- a/functions/sample/post-review.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys - -from ibmcloudant.cloudant_v1 import CloudantV1, Document -from ibm_cloud_sdk_core.authenticators import IAMAuthenticator -from ibm_cloud_sdk_core import ApiException - -def main(param_dict): - authenticator = IAMAuthenticator(param_dict["IAM_API_KEY"]) - service = CloudantV1(authenticator=authenticator) - service.set_service_url(param_dict["COUCH_URL"]) - - - try: - response = service.post_document( - db='reviews', - document=param_dict["review"], - ).get_result() - # result_by_filter=my_database.get_query_result(selector,raw_result=True) - result= { - 'headers': {'Content-Type':'application/json'}, - 'body': {'data':response} - } - return result - except ApiException as ae: - errorBody = {"error": ae.message} - if ("reason" in ae.http_response.json()): - errorBody["reason"] = ae.http_response.json()["reason"] - - return errorBody - except: - return { - 'statusCode': 500, - 'message': "Something went wrong on the server" - } \ No newline at end of file From 59f28a63a62a1e5ed68b631883cf51803e085ace Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Sat, 19 Aug 2023 15:06:02 -0400 Subject: [PATCH 08/10] backend jazz --- server/djangoapp/models.py | 22 ++++++++++ server/djangoapp/restapis.py | 83 ++++++++++++++++++++++++++++++------ server/djangoapp/urls.py | 4 +- server/djangoapp/views.py | 57 ++++++++++++++++++++++--- 4 files changed, 147 insertions(+), 19 deletions(-) diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index 3becc9162b..27e4f6cd0d 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -54,3 +54,25 @@ def __str__(self): return "Dealer name: " + self.full_name # Create a plain Python class `DealerReview` to hold review data +class DealerReview: + + def __init__(self, dealership, name, purchase, review): + # Required attributes + self.dealership = dealership + self.name = name + self.purchase = purchase + self.review = review + # Optional attributes + self.purchase_date = "" + self.car_make = "" + self.car_model = "" + self.car_year = "" + self.sentiment = "" + self.id = "" + + def __str__(self): + return "Review: " + self.review + + def to_json(self): + return json.dumps(self, default=lambda o: o.__dict__, + sort_keys=True, indent=4) \ No newline at end of file diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index f418cc5e39..1f97a2cc41 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -1,6 +1,6 @@ import requests import json -from .models import CarDealer, DealerReview +from .models import CarDealer from requests.auth import HTTPBasicAuth @@ -8,11 +8,19 @@ # e.g., response = requests.get(url, params=params, headers={'Content-Type': 'application/json'}, # auth=HTTPBasicAuth('apikey', api_key)) def get_request(url, **kwargs): - print(kwargs) + api_key = kwargs.get("api_key") print("GET from {} ".format(url)) try: - # Call get method of requests library with URL and parameters - response = requests.get(url, headers={'Content-Type': 'application/json'}, + if api_key: + params = dict() + params["text"] = kwargs["text"] + params["version"] = kwargs["version"] + params["features"] = kwargs["features"] + params["return_analyzed_text"] = kwargs["return_analyzed_text"] + requests.get(url, params=params, headers={'Content-Type': 'application/json'}, + auth=HTTPBasicAuth('apikey', api_key)) + else: + response = requests.get(url, headers={'Content-Type': 'application/json'}, params=kwargs) except: # If any error occurs @@ -24,7 +32,15 @@ def get_request(url, **kwargs): # Create a `post_request` to make HTTP POST requests # e.g., response = requests.post(url, params=kwargs, json=payload) - +def post_request(url, payload, **kwargs): + print(kwargs) + print("POST to {} ".format(url)) + print(payload) + response = requests.post(url, params=kwargs, json=payload) + status_code = response.status_code + print("With status {} ".format(status_code)) + json_data = json.loads(response.text) + return json_data # Create a get_dealers_from_cf method to get dealers from a cloud function # def get_dealers_from_cf(url, **kwargs): @@ -32,28 +48,69 @@ def get_request(url, **kwargs): # - Parse JSON results into a CarDealer object list def get_dealers_from_cf(url, **kwargs): results = [] - # Call get_request with a URL parameter - json_result = get_request(url) + state = kwargs.get("state") + if state: + json_result = get_request(url, state=state) + else: + json_result = get_request(url) + if json_result: - # Get the row list in JSON as dealers - dealers = json_result["rows"] - # For each dealer object + dealers=json_result for dealer in dealers: - # Get its content in `doc` object dealer_doc = dealer["doc"] - # Create a CarDealer object with values in `doc` object dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], full_name=dealer_doc["full_name"], id=dealer_doc["id"], lat=dealer_doc["lat"], long=dealer_doc["long"], short_name=dealer_doc["short_name"], st=dealer_doc["st"], zip=dealer_doc["zip"]) results.append(dealer_obj) - return results +def get_dealer_by_id_from_cf(url, id): + json_result = get_request(url, id=id) + if json_result: + dealers=json_result + for dealer_doc in dealers: + dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], + id=dealer_doc["id"], short_name=dealer_doc["short_name"], + lat=dealer_doc["lat"], long=dealer_doc["long"], full_name=dealer_doc["full_name"], + st=dealer_doc["st"], zip=dealer_doc["zip"]) + return dealer_obj + # Create a get_dealer_reviews_from_cf method to get reviews by dealer id from a cloud function # def get_dealer_by_id_from_cf(url, dealerId): # - Call get_request() with specified arguments # - Parse JSON results into a DealerView object list +def get_dealer_reviews_from_cf(url, **kwargs): + results = [] + id = kwargs.get("id") + if id: + json_result = get_request(url, id=id) + else: + json_result = get_request(url) + # print(json_result) + if json_result: + reviews = json_result["data"]["docs"] + for dealer_review in reviews: + review_obj = DealerReview(dealership=dealer_review["dealership"], + name=dealer_review["name"], + purchase=dealer_review["purchase"], + review=dealer_review["review"]) + if "id" in dealer_review: + review_obj.id = dealer_review["id"] + if "purchase_date" in dealer_review: + review_obj.purchase_date = dealer_review["purchase_date"] + if "car_make" in dealer_review: + review_obj.car_make = dealer_review["car_make"] + if "car_model" in dealer_review: + review_obj.car_model = dealer_review["car_model"] + if "car_year" in dealer_review: + review_obj.car_year = dealer_review["car_year"] + + review_obj.sentiment = analyze_review_sentiments(review_obj.review) + results.append(review_obj) + + return results + # Create an `analyze_review_sentiments` method to call Watson NLU and analyze text diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index deec333119..7935918a08 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -27,8 +27,10 @@ #path for home path(route='', view=views.get_dealerships, name='index'), - # path for dealer reviews view + # path for dealer reviews + path('dealer//', views.get_dealer_details, name='dealer_details'), # path for add a review view + path('dealer//', views.get_dealer_details, name='dealer_details') ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index 0af432c454..2aa39a4061 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -2,8 +2,8 @@ from django.http import HttpResponseRedirect, HttpResponse from django.contrib.auth.models import User from django.shortcuts import get_object_or_404, render, redirect -# from .models import related models -# from .restapis import related methods +from .models import CarModel, CarMake, CarDealer +from .restapis import get_dealers_from_cf, get_request, get_dealer_reviews_from_cf, get_dealer_by_id_from_cf, post_request from django.contrib.auth import login, logout, authenticate from django.contrib import messages from datetime import datetime @@ -92,7 +92,7 @@ def registration_request(request): # Update the `get_dealerships` view to render the index page with a list of dealerships def get_dealerships(request): if request.method == "GET": - url = "your-cloud-function-domain/dealerships/dealer-get" + url = "https://us-south.functions.appdomain.cloud/api/v1/web/3a5a06a6-46c3-4e9e-815b-cc07f4a836f1/dealership-package/get-dealership" # Get dealers from the URL dealerships = get_dealers_from_cf(url) # Concat all dealer's short name @@ -100,9 +100,56 @@ def get_dealerships(request): # Return a list of dealer short name return HttpResponse(dealer_names) -# Create a `get_dealer_details` view to render the reviews of a dealer +# Create a `get_dealer_details` view to render the reviews of a dealer +def get_dealer_details(request, id): + if request.method == "GET": + context = {} + dealer_url = "https://us-south.functions.appdomain.cloud/api/v1/web/3a5a06a6-46c3-4e9e-815b-cc07f4a836f1/dealership-package/get-dealership" + dealer = get_dealer_by_id_from_cf(dealer_url, id=id) + context["dealer"] = dealer + + review_url = "https://us-south.functions.appdomain.cloud/api/v1/web/3a5a06a6-46c3-4e9e-815b-cc07f4a836f1/dealership-package/get-review" + reviews = get_dealer_reviews_from_cf(review_url, id=id) + print(reviews) + context["reviews"] = reviews + + return render(request, 'djangoapp/dealer_details.html', context) # Create a `add_review` view to submit a review # def add_review(request, dealer_id): -# ... +def add_review(request, id): + context = {} + dealer_url = "https://us-south.functions.appdomain.cloud/api/v1/web/agamanmon_default/dealership-package/get-dealership" + dealer = get_dealer_by_id_from_cf(dealer_url, id=id) + context["dealer"] = dealer + if request.method == 'GET': + cars = CarModel.objects.all() + print(cars) + context["cars"] = cars + return render(request, 'djangoapp/add_review.html', context) + elif request.method == 'POST': + if request.user.is_authenticated: + username = request.user.username + print(request.POST) + payload = dict() + car_id = request.POST["car"] + car = CarModel.objects.get(pk=car_id) + payload["time"] = datetime.utcnow().isoformat() + payload["name"] = username + payload["dealership"] = id + payload["id"] = id + payload["review"] = request.POST["content"] + payload["purchase"] = False + if "purchasecheck" in request.POST: + if request.POST["purchasecheck"] == 'on': + payload["purchase"] = True + payload["purchase_date"] = request.POST["purchasedate"] + payload["car_make"] = car.make.name + payload["car_model"] = car.name + payload["car_year"] = int(car.year.strftime("%Y")) + new_payload = {} + new_payload["review"] = payload + review_post_url = "https://us-south.functions.appdomain.cloud/api/v1/web/agamanmon_default/dealership-package/post-review" + post_request(review_post_url, new_payload, id=id) + return redirect("djangoapp:dealer_details", id=id) From 962f281afbcc83074a322d2fbf9db23459334ec7 Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Sat, 19 Aug 2023 15:10:47 -0400 Subject: [PATCH 09/10] backend jazz --- server/djangoapp/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index 2aa39a4061..488eac0482 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -119,7 +119,7 @@ def get_dealer_details(request, id): # def add_review(request, dealer_id): def add_review(request, id): context = {} - dealer_url = "https://us-south.functions.appdomain.cloud/api/v1/web/agamanmon_default/dealership-package/get-dealership" + dealer_url = "https://us-south.functions.appdomain.cloud/api/v1/web/3a5a06a6-46c3-4e9e-815b-cc07f4a836f1/dealership-package/get-dealership" dealer = get_dealer_by_id_from_cf(dealer_url, id=id) context["dealer"] = dealer if request.method == 'GET': @@ -149,7 +149,7 @@ def add_review(request, id): payload["car_year"] = int(car.year.strftime("%Y")) new_payload = {} new_payload["review"] = payload - review_post_url = "https://us-south.functions.appdomain.cloud/api/v1/web/agamanmon_default/dealership-package/post-review" + review_post_url = "https://us-south.functions.appdomain.cloud/api/v1/web/3a5a06a6-46c3-4e9e-815b-cc07f4a836f1/dealership-package/post-review" post_request(review_post_url, new_payload, id=id) return redirect("djangoapp:dealer_details", id=id) From 81eaed18100067e4ab2751f3b73b8fddfdef7b3f Mon Sep 17 00:00:00 2001 From: JPigeon252 Date: Sun, 20 Aug 2023 11:56:17 -0400 Subject: [PATCH 10/10] half way --- server/db.sqlite3 | Bin 143360 -> 143360 bytes server/djangoapp/restapis.py | 91 ++++++++++-------- .../templates/djangoapp/dealer_details.html | 47 +++++++++ .../djangoapp/templates/djangoapp/index.html | 33 ++++++- server/djangoapp/urls.py | 4 +- server/djangoapp/views.py | 11 ++- 6 files changed, 136 insertions(+), 50 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 22b415d9b5c8ebce5fdaa9280b068223db6fafa7..fd2361b9608bfcdfa91582b4d384c3d46b7236b5 100644 GIT binary patch delta 319 zcmZp8z|ru4V}dke{6raN#`uj1A^Ac^1`38IR)&UF#^!nkW(KB~7MqXd+bKwJaYixl z-R4W>ea~CT%gocuBhI~$tDZAzW1}6XMw1d3t8a6#qh+pHnMr11a)oKBQE{qeRYjqN zg{5(BX;Q99aYbcP%4FvGo4q2kEW@naoSn=4!qO^SEp*L&(^K;U%Y4(F{PH6_G7Fs2 zQo|B0y`2JlD+3H%lZuTDjEr>+EOiZxkz8hOU~Fo%xqenFD;F1EKLfu9-%Y;$%{&Vl z`BYVyeHjTkgsXYWy6s!mF$OqFaPggH;D5w_n12a>D}NflJHG}$C*Lc+(;FMt^G$#C QkC9gh!(OiKKyfic0BVY2CjbBd delta 141 zcmV;80CN9;;0S==2#^~AT#+0@0bH?QRBsY7GaxZEIyE^uGcztZGB-FdHnYZWJ|Gqe z3V#3&+YV(7?+tkk0}PD}7Ym^Zf3bmN3IPGLf0~5_2ni0f01rqG*|QFyfew+7Cxf)E vx3sPSP(c<64(b38;t#_Qqz{D;W)DXXC=Uq^>al^)4wuXR0S&kJ{s9Rw>IyC4 diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index 1f97a2cc41..aed12ee31a 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -48,16 +48,16 @@ def post_request(url, payload, **kwargs): # - Parse JSON results into a CarDealer object list def get_dealers_from_cf(url, **kwargs): results = [] - state = kwargs.get("state") - if state: - json_result = get_request(url, state=state) - else: - json_result = get_request(url) - + # Call get_request with a URL parameter + json_result = get_request(url) if json_result: - dealers=json_result + # Get the row list in JSON as dealers + dealers = json_result["rows"] + # For each dealer object for dealer in dealers: + # Get its content in `doc` object dealer_doc = dealer["doc"] + # Create a CarDealer object with values in `doc` object dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], full_name=dealer_doc["full_name"], id=dealer_doc["id"], lat=dealer_doc["lat"], long=dealer_doc["long"], short_name=dealer_doc["short_name"], @@ -66,51 +66,60 @@ def get_dealers_from_cf(url, **kwargs): return results def get_dealer_by_id_from_cf(url, id): - json_result = get_request(url, id=id) + result = {} + # Call get_request with a URL parameter + json_result = get_request(url, did=id) if json_result: - dealers=json_result - for dealer_doc in dealers: - dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], - id=dealer_doc["id"], short_name=dealer_doc["short_name"], - lat=dealer_doc["lat"], long=dealer_doc["long"], full_name=dealer_doc["full_name"], - st=dealer_doc["st"], zip=dealer_doc["zip"]) - return dealer_obj + # Get the row list in JSON as dealers + dealers = json_result["rows"] + # For each dealer object + dealer = dealers[0] + # Create a CarDealer object with values in `doc` object + dealer_obj = CarDealer(address=dealer["address"], city=dealer["city"], full_name=dealer["full_name"], + id=dealer["id"], lat=dealer["lat"], long=dealer["long"], + short_name=dealer["short_name"], + st=dealer["st"], zip=dealer["zip"]) + result = dealer_obj + return result + +def get_dealers_by_state_from_cf(url, state, **kwargs): + results = [] + # Call get_request with a URL parameter + json_result = get_request(url, state=state) + if json_result: + # Get the row list in JSON as dealers + dealers = json_result["rows"] + # For each dealer object + for dealer in dealers: + dealer_doc = dealer["doc"] + # Create a CarDealer object with values in `doc` object + dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], full_name=dealer_doc["full_name"], + id=dealer_doc["id"], lat=dealer_doc["lat"], long=dealer_doc["long"], + short_name=dealer_doc["short_name"], + st=dealer_doc["st"], zip=dealer_doc["zip"]) + results.append(dealer_obj) + return results # Create a get_dealer_reviews_from_cf method to get reviews by dealer id from a cloud function # def get_dealer_by_id_from_cf(url, dealerId): # - Call get_request() with specified arguments # - Parse JSON results into a DealerView object list -def get_dealer_reviews_from_cf(url, **kwargs): +def get_dealer_reviews_from_cf(url, id): results = [] - id = kwargs.get("id") - if id: - json_result = get_request(url, id=id) - else: - json_result = get_request(url) - # print(json_result) + # Call get_request with a URL parameter + json_result = get_request(url, did=id) if json_result: - reviews = json_result["data"]["docs"] - for dealer_review in reviews: - review_obj = DealerReview(dealership=dealer_review["dealership"], - name=dealer_review["name"], - purchase=dealer_review["purchase"], - review=dealer_review["review"]) - if "id" in dealer_review: - review_obj.id = dealer_review["id"] - if "purchase_date" in dealer_review: - review_obj.purchase_date = dealer_review["purchase_date"] - if "car_make" in dealer_review: - review_obj.car_make = dealer_review["car_make"] - if "car_model" in dealer_review: - review_obj.car_model = dealer_review["car_model"] - if "car_year" in dealer_review: - review_obj.car_year = dealer_review["car_year"] - + # Get the row list in JSON as dealers + reviews = json_result["rows"] + # For each dealer object + for review in reviews: + # Create a CarDealer object with values in `doc` object + review_obj = DealerReview(id=review["id"], dealership=review["dealership"], name=review["name"], purchase=review["purchase"], + review=review["review"], purchase_date=review["purchase_date"], car_make=review["car_make"], + car_model=review["car_model"], car_year=review["car_year"], sentiment="") review_obj.sentiment = analyze_review_sentiments(review_obj.review) results.append(review_obj) - return results - # Create an `analyze_review_sentiments` method to call Watson NLU and analyze text diff --git a/server/djangoapp/templates/djangoapp/dealer_details.html b/server/djangoapp/templates/djangoapp/dealer_details.html index 25bd9a223d..1c132f6dfc 100644 --- a/server/djangoapp/templates/djangoapp/dealer_details.html +++ b/server/djangoapp/templates/djangoapp/dealer_details.html @@ -10,8 +10,55 @@ + +
    + {% for review in reviews %} +
    +
    {{review.name}}
    + +
    +
    {{ review.car_make }}, {{ review.car_model }}
    +
    {{ review.car_year }}
    +

    {{ review.review }}

    +
    +
    + {% endfor %} {% if reviews|length == 0 %} +

    This dealership has no reviews to show

    + {% endif %} +
    diff --git a/server/djangoapp/templates/djangoapp/index.html b/server/djangoapp/templates/djangoapp/index.html index 0e01dde302..6b225c4475 100644 --- a/server/djangoapp/templates/djangoapp/index.html +++ b/server/djangoapp/templates/djangoapp/index.html @@ -46,7 +46,36 @@ - +
    + + + + + + + + + + + + + {% for dealer in dealerships %} + + + + + + + + + {% endfor %} + +
    IDDealer NameCityAddressZipState
    {{dealer.id}}{{dealer.full_name}}{{dealer.city}}{{dealer.address}}{{dealer.zip}}{{dealer.st}}
    +
    - + diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 7935918a08..96030db258 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -28,9 +28,9 @@ path(route='', view=views.get_dealerships, name='index'), # path for dealer reviews - path('dealer//', views.get_dealer_details, name='dealer_details'), + path('dealer//', views.get_dealer_details, name='dealer_details'), # path for add a review view - path('dealer//', views.get_dealer_details, name='dealer_details') + path(route='dealer//', view=views.get_dealer_details, name='dealer_details') ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index 488eac0482..b290324367 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -91,14 +91,15 @@ def registration_request(request): # Update the `get_dealerships` view to render the index page with a list of dealerships def get_dealerships(request): + context = {} if request.method == "GET": url = "https://us-south.functions.appdomain.cloud/api/v1/web/3a5a06a6-46c3-4e9e-815b-cc07f4a836f1/dealership-package/get-dealership" # Get dealers from the URL - dealerships = get_dealers_from_cf(url) - # Concat all dealer's short name - dealer_names = ' '.join([dealer.short_name for dealer in dealerships]) - # Return a list of dealer short name - return HttpResponse(dealer_names) + context = { + "dealerships": get_dealers_from_cf(url), + } + return render(request, 'djangoapp/index.html', context) + # Create a `get_dealer_details` view to render the reviews of a dealer def get_dealer_details(request, id):