From 8f7d789bcabfbd027f8699762a970d1b431b1d4d Mon Sep 17 00:00:00 2001 From: Marvin Date: Sat, 1 Jul 2023 14:27:20 -0400 Subject: [PATCH 1/8] Week 1 Changes --- server/db.sqlite3 | Bin 0 -> 131072 bytes .../djangoapp/templates/djangoapp/about.html | 29 ++++++++++++++++ .../templates/djangoapp/contact.html | 31 ++++++++++++++++++ .../djangoapp/templates/djangoapp/index.html | 12 +++++-- server/djangoapp/urls.py | 4 +++ server/djangoapp/views.py | 12 +++++-- 6 files changed, 82 insertions(+), 6 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..e4e0b9273ffa6cfa8c4f5e9bc9e8f6de9f5f3f6e GIT binary patch literal 131072 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 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..186f75da49 --- /dev/null +++ b/server/djangoapp/templates/djangoapp/about.html @@ -0,0 +1,29 @@ + + + + + Dealership Review + + + + + + + + + + + + +

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

+ diff --git a/server/djangoapp/templates/djangoapp/contact.html b/server/djangoapp/templates/djangoapp/contact.html new file mode 100644 index 0000000000..8b15777ca6 --- /dev/null +++ b/server/djangoapp/templates/djangoapp/contact.html @@ -0,0 +1,31 @@ + + + + + Dealership Review + + + + + + + + + + + +
    +
  • Person #1: 123-456-7890
  • +
  • Person #2: 098-765-4321
  • +
  • Person #3: 102-938-4756
  • +
+ + \ No newline at end of file diff --git a/server/djangoapp/templates/djangoapp/index.html b/server/djangoapp/templates/djangoapp/index.html index 1a9ee6e39a..1e539bbc92 100644 --- a/server/djangoapp/templates/djangoapp/index.html +++ b/server/djangoapp/templates/djangoapp/index.html @@ -14,10 +14,16 @@ - - This is the index page of your Django app! - + diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 37b1c89d01..55b123ea16 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -11,8 +11,12 @@ # 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 # path for login diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index 61cc664da0..45a54154f1 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -18,12 +18,18 @@ # 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 2e448b526207ecf46343063def02986c5c9999d3 Mon Sep 17 00:00:00 2001 From: Marvin Wu Date: Thu, 27 Jul 2023 15:49:18 -0400 Subject: [PATCH 2/8] user management added --- server/db.sqlite3 | Bin 131072 -> 131072 bytes .../djangoapp/templates/djangoapp/about.html | 20 ++++++ .../templates/djangoapp/contact.html | 20 ++++++ .../templates/djangoapp/dealer_details.html | 1 + .../djangoapp/templates/djangoapp/index.html | 20 ++++++ .../templates/djangoapp/registration.html | 24 ++++++- server/djangoapp/urls.py | 8 +-- server/djangoapp/views.py | 60 ++++++++++++++++-- 8 files changed, 142 insertions(+), 11 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index e4e0b9273ffa6cfa8c4f5e9bc9e8f6de9f5f3f6e..11ba488160df8c1359821dbcba07b793afde9f67 100644 GIT binary patch delta 720 zcmZwFO>7cD6ae5I7A-Vk#}*r6twPPFNz;_h&i<2_xKv3Cp(%8MLQD!&SeE~Pkqc}* zdJ#RCc=YTAIe0MMJvRPaswd;ci)W7l(F7Y_=H*Rh-r>ue>Gv)DzUAq45FV`Ug77f; z%6auAaT&G=_!EAH?_e7~fv;g_Xe8nD_71&45XAC0XTnC2PLOIfb0@7vrcOF8kt}$z zo&)yLryT|@l9Y>p_o?@kYiKM}J!6%$5yqxsaoBAZt75OF3lFmRq>)QuUZ61}AcSa! z@g{0VrFtYEXwt{nC#t6ke|zS;}36RgxPH* zZe!8K$R1Ag@T{BV7zqjWN~Os*D!uZ&7L0f-p=zdXteO7mmL|Gub9GAkP}TRn`PQ+_ z(OON(aM@UNSI@>2sZ$7V#oKCzJ7QzyW=iz#)%@v5P4?x{{=JE=H_PKaSa4&W=LB)W z!?D%{+_VA794GR@RK2a2jdd{fSyybER;yy0>rL>I>=csRx_$n1DF6W=87XsME3be~pAvsB50 z$4hogqAc^=;`nor@CN~Z!(Zd_UyPi|5AcSSbb#rDkpFhrv_P&{Cug=1s4iSFQRhSB xBV_^`L*o{BR<)Smx6xAa3k3AQaJ}i9U60LYZ_Q`G>@vac|t4JyFJ)QF>#-B6*P&3~c;m4E!(ouki2YFXQj#pT%FXu`z*va+$u0 z8V?_{JV#<_Nk)8WacU6*1A{OSBLi_(W@EAbout Us Contact Us + diff --git a/server/djangoapp/templates/djangoapp/contact.html b/server/djangoapp/templates/djangoapp/contact.html index 8b15777ca6..db966ac2b7 100644 --- a/server/djangoapp/templates/djangoapp/contact.html +++ b/server/djangoapp/templates/djangoapp/contact.html @@ -20,6 +20,26 @@ About Us Contact Us +
    diff --git a/server/djangoapp/templates/djangoapp/dealer_details.html b/server/djangoapp/templates/djangoapp/dealer_details.html index 25bd9a223d..c836fdde19 100644 --- a/server/djangoapp/templates/djangoapp/dealer_details.html +++ b/server/djangoapp/templates/djangoapp/dealer_details.html @@ -10,6 +10,7 @@ + diff --git a/server/djangoapp/templates/djangoapp/index.html b/server/djangoapp/templates/djangoapp/index.html index 1e539bbc92..6d94f755ba 100644 --- a/server/djangoapp/templates/djangoapp/index.html +++ b/server/djangoapp/templates/djangoapp/index.html @@ -22,6 +22,26 @@ About Us Contact Us + diff --git a/server/djangoapp/templates/djangoapp/registration.html b/server/djangoapp/templates/djangoapp/registration.html index ae11ea4b71..00622fa5b6 100644 --- a/server/djangoapp/templates/djangoapp/registration.html +++ b/server/djangoapp/templates/djangoapp/registration.html @@ -6,6 +6,28 @@ - +
    +
    + {% csrf_token %} +

    Sign Up

    +
    +
    + + + + + + + + + {% if message %} +
    + {{ message }} +
    + {% endif %} + +
    +
    +
    \ No newline at end of file diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 55b123ea16..0121471542 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -8,22 +8,22 @@ # route is a string contains a URL pattern # view refers to the view function # name the URL + path(route='', view=views.get_dealerships, name='index'), # 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 + 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='', view=views.get_dealerships, name='index'), + path(route='logout', view=views.logout_request, name='logout') # path for dealer reviews view diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index 45a54154f1..b9a089c292 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -32,16 +32,64 @@ def contact(request): # Create a `login_request` view to handle sign in request -# def login_request(request): -# ... +def login_request(request): + context = {} + # 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 render(request, 'djangoapp/login.html', context) + else: + return render(request, 'djangoapp/login.html', context) # Create a `logout_request` view to handle sign out request -# def logout_request(request): -# ... +def logout_request(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): -# ... +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) # Update the `get_dealerships` view to render the index page with a list of dealerships def get_dealerships(request): From d99bb234b4e7a8b51a07e00c65f817610a3b46ea Mon Sep 17 00:00:00 2001 From: TheRandomGuy146275 <135289032+TheRandomGuy146275@users.noreply.github.com> Date: Mon, 28 Aug 2023 11:02:04 -0400 Subject: [PATCH 3/8] Create get-dealership.js --- functions/get-dealership.js | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 functions/get-dealership.js diff --git a/functions/get-dealership.js b/functions/get-dealership.js new file mode 100644 index 0000000000..a0a7df9e8d --- /dev/null +++ b/functions/get-dealership.js @@ -0,0 +1,52 @@ +const express = require('express'); +const app = express(); +const port = process.env.PORT || 3000; +const Cloudant = require('@cloudant/cloudant'); +// Initialize Cloudant connection with IAM authentication +async function dbCloudantConnect() { + try { + const cloudant = Cloudant({ + plugins: { iamauth: { iamApiKey: 'r6c5foCGS8FS4_7b-CGoKf_w6MMRMK9K5PzXjn4GdmSK' } }, // Replace with your IAM API key + url: 'https://8715b253-759d-4f15-b10e-c0d9e133d048-bluemix.cloudantnosqldb.appdomain.cloud', // Replace with your Cloudant URL + }); + const db = cloudant.use('dealerships'); + console.info('Connect success! Connected to DB'); + return db; + } catch (err) { + console.error('Connect failure: ' + err.message + ' for Cloudant DB'); + throw err; + } +} +let db; +(async () => { + db = await dbCloudantConnect(); +})(); +app.use(express.json()); +// Define a route to get all dealerships with optional state and ID filters +app.get('/dealerships/get', (req, res) => { + const { state, id } = req.query; + // Create a selector object based on query parameters + const selector = {}; + if (state) { + selector.state = state; + } + if (id) { + selector._id = id; + } + const queryOptions = { + selector, + limit: 10, // Limit the number of documents returned to 10 + }; + db.find(queryOptions, (err, body) => { + if (err) { + console.error('Error fetching dealerships:', err); + res.status(500).json({ error: 'An error occurred while fetching dealerships.' }); + } else { + const dealerships = body.docs; + res.json(dealerships); + } + }); +}); +app.listen(port, () => { + console.log(`Server is running on port ${port}`); +}); From 5e2c8ce35b913acc9d5aec605d10c9bcf0a1f116 Mon Sep 17 00:00:00 2001 From: TheRandomGuy146275 <135289032+TheRandomGuy146275@users.noreply.github.com> Date: Mon, 28 Aug 2023 11:03:19 -0400 Subject: [PATCH 4/8] Create reviews.py --- functions/reviews.py | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 functions/reviews.py diff --git a/functions/reviews.py b/functions/reviews.py new file mode 100644 index 0000000000..376a2b885e --- /dev/null +++ b/functions/reviews.py @@ -0,0 +1,72 @@ +from cloudant.client import Cloudant +from cloudant.query import Query +from flask import Flask, jsonify, request +import atexit + +#Add your Cloudant service credentials here +cloudant_username = '8715b253-759d-4f15-b10e-c0d9e133d048-bluemix' +cloudant_api_key = 'r6c5foCGS8FS4_7b-CGoKf_w6MMRMK9K5PzXjn4GdmSK' +cloudant_url = 'https://8715b253-759d-4f15-b10e-c0d9e133d048-bluemix.cloudantnosqldb.appdomain.cloud' +client = Cloudant.iam(cloudant_username, cloudant_api_key, connect=True, url=cloudant_url) + +session = client.session() +print('Databases:', client.all_dbs()) + +db = client['reviews'] + +app = Flask(__name__) + +@app.route('/api/get_reviews', methods=['GET']) +def get_reviews(): + dealership_id = request.args.get('id') + + # Check if "id" parameter is missing + if dealership_id is None: + return jsonify({"error": "Missing 'id' parameter in the URL"}), 400 + + # Convert the "id" parameter to an integer (assuming "id" should be an integer) + try: + dealership_id = int(dealership_id) + except ValueError: + return jsonify({"error": "'id' parameter must be an integer"}), 400 + + # Define the query based on the 'dealership' ID + selector = { + 'dealership': dealership_id + } + + # Execute the query using the query method + result = db.get_query_result(selector) + + # Create a list to store the documents + data_list = [] + + # Iterate through the results and add documents to the list + for doc in result: + data_list.append(doc) + + # Return the data as JSON + return jsonify(data_list) + + +@app.route('/api/post_review', methods=['POST']) +def post_review(): + if not request.json: + abort(400, description='Invalid JSON data') + + # Extract review data from the request JSON + review_data = request.json + + # Validate that the required fields are present in the review data + required_fields = ['id', 'name', 'dealership', 'review', 'purchase', 'purchase_date', 'car_make', 'car_model', 'car_year'] + for field in required_fields: + if field not in review_data: + abort(400, description=f'Missing required field: {field}') + + # Save the review data as a new document in the Cloudant database + db.create_document(review_data) + + return jsonify({"message": "Review posted successfully"}), 201 + +if __name__ == '__main__': + app.run(debug=True) From 14a3f85699ba78432ac1888efa04f0487c9b9c70 Mon Sep 17 00:00:00 2001 From: Marvin Wu Date: Mon, 28 Aug 2023 17:51:47 -0400 Subject: [PATCH 5/8] Week 3, added models --- server/db.sqlite3 | Bin 131072 -> 143360 bytes server/djangoapp/admin.py | 15 +++++++++++---- server/djangoapp/models.py | 21 ++++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 11ba488160df8c1359821dbcba07b793afde9f67..1134e2f1bf91debca12a6e84ffd58d894ac2d44d 100644 GIT binary patch delta 2784 zcmbVNeQXnD7{9mIt=E%b(cRi(T-UW-+kF%z z-C@*(CCV~Q|3nfKW8xpyX&NIW#27G|=wcudf*-*@h>DWnADF1o_d2?@8*22DzSsWx zyWjiV^ZcIonVX~LzNOC9R16aYp~s*6)w!_OgoZOC=YgtIV^FKAUR0Df%2d@E@ot&b ztSuqx8=Zk57aogn(I~?(tWO9F34se48KcR-*bPQIZDbuL)?s1x*~~0!GA{MiyeqGy zz(c_Ia1B0yX_$w%U<5oFkpb7%a*{=>l0H8dn}`JX5LpRiv$7cH#(8Zixd(AmiIcu4 zADa;3aUl|>7w4NjrIeN=4a&tE%{#Yg%W&)z94Fvs_!Mr!C3p>{;5f`@#5OQ&mDks< zZJ6JW+9I#7DTeWOipBW@NgVqy0YAYF_yjJ(c{mFR7|w`pFl?dZM1AdQka?|21%_*i zV63%xw)YfCt4}W~`q*-fTK%i~JN2^qlKKtxg8Fnuw5U^BIogG&X@Q?vO#{6}j`ko5 zCxlP%t7!cS>OYAKv4+-dmZL^Qae=@pu{H-ORwZ#5+biX$2`LH`F<2vkdZZ{&#AtPe z9APjoh>>ke^~Wz%ROZWUwmK}feI}dPWV0__i!gL4(%d98H#6e0CUr)SO1hsLaPo|4 z+A@A}`h;BwkK4jrg!PY(S?%mZaw-yxgkt;nj@cu@)_Cts(Aj^G_X&qW<3_99z>Nnj z;dsyJ(bj(J*x~j`uPfYU5<2=_#-RU{%{q`A9h~kNv~-7p)|si~WXx-0xd`5baoTL& zKu0RU_A$O#_erj$(>FQh9rB+_`g*KW9=j)WB-X+voHqZdqa8_Cn>pfak3Tio?(}vK zdHP*r{X++5oI=0f8*>kO+G4XEv;Bw1W-Y-1!%UyM*E`zgU?;h8^N_=6_8X(jL`O2@ z@fr<5Lu?>)&>Zn41pkS?u(5r{?mT4mxw}Wrhds`f{%A3o0{-I$?NQ5Xlx7O#@y4+eT zt%~irwI;V#=hkgYQ{TKiq62i5fCkMM%Il>cs%JKxEv+mWl)tKapgcgiRr|@0(beqE zC(#9zy%R*A%ajK;E2_o~NQ|dZ7plu%YDErGM)WO+UD;?DokQ8{?Z}I?Tl443+CBZ= z1iG00wG$~T*|IxC1u;pK?N`1@eMN09{Q>VfA$vg1lb2;5q0eM5A{#NO5!E*zJ}xYX zjw6)xLv%f+sA_ITXDkVBG{moVT+aX4t{Z?IuETDp*G+q!2fN&~Zo~iS@#crm;GoL zJ`M=kFB$QkEG0HPuBbZ3BC%Zv2l(0I0HkwI3f(t>WA_OGpWSX@{rm}bBTfJCMcR8> z-9zhNTO1iulP=u5D0jt4o3l!}$^{GEW`mn!D&K?QalNh+1nbVQnELbIF^ui&%J zfXWCbSe}a`rLuSwnp+$uW}ne+GPSg@E-prQ=_+CVfld0K|gc)^j^B) zr!JQ%M=lR^ZY=8Xi$q3)ygz~Ix*lv)M|UKU;zL-dbn85{_#|TW3UMWtC-VMWA0B4z*oK*UL*ZmDiVah;Be&4&+EN6! z3Al}|`z7qIC7lnw`KU3Jb2Qu~;4Wt02Hj>PC-m9^pJGc%91>n3;A?mvUcuw)1xV>h zil{|ZJG4q{#9X<_L2fJ(Uh4wBs7r-{RBG{$ z5kf*vH!7u{?uIclvy77Jah8fJZHT_(CJVc)bjwR#5in2i8*bw&=264vc+X@RY*qz& z3MO-RZ(N(ZerIMno1LD$9W=Dglpv^-MkQmXGt#Wcj-r4X!JqgJcX1sbqh_*sG_=9{ zJ^_maf8Y+j#Wh^UqRH}T6h|M>ptsEs(=n6nd#tvJ6@MTRjVD5}{$x*IvM1Kj*WVpK z(`9YXc7+7uBgDIFvMnzM5tFsU;xCEAn&mH45yCnPJ*oI!RCpf^V$KjZ9nAr>a$goQ z?J~baFznrGstT_?^X{S$IC6zwave6n{k9|LUb^ treFa;wxIrJ)bYDm;%U&GDT|xn_&w>iGc|as{)-CtoMb*BwCY30{sOSOoZA2Z diff --git a/server/djangoapp/admin.py b/server/djangoapp/admin.py index b1039e16b8..3ee421215f 100644 --- a/server/djangoapp/admin.py +++ b/server/djangoapp/admin.py @@ -1,13 +1,20 @@ 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 + extra = 5 # CarModelAdmin class - +class CarModelAdmin(admin.ModelAdmin): + list_display = ('car_make', 'name', "dealer_id", "car_type", "year", ) # CarMakeAdmin class with CarModelInline - +class CarMakeAdmin(admin.ModelAdmin): + inlines=[CarModelInline] + list_display=("name", "description") # Register models here +admin.site.register(CarModel,CarModelAdmin) +admin.site.register(CarMake,CarMakeAdmin) diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index 27d96f4eff..8b9d742c2b 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -3,12 +3,20 @@ # Create your models here. - +CHOICES = [ + ("SUv", "SUV"), + ("Wagon", "Wagon"), +] # 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 +class CarMake(models.Model): + name = models.CharField(null=False, max_length=30, default='new car make') + description = models.CharField(null=False, max_length=500) + def __str__(self): + return "Car Make:" + self.name # Create a Car Model model `class CarModel(models.Model):`: @@ -19,9 +27,16 @@ # - Year (DateField) # - Any other fields you would like to include in car model # - __str__ method to print a car make object - +class CarModel(models.Model): + car_make = models.ForeignKey(CarMake, null=True, on_delete=models.CASCADE) + name = models.CharField(null=False, max_length=30, default='new car model') + dealer_id = models.IntegerField() + car_type = models.CharField(null=False, max_length=100, choices=CHOICES) + year = models.DateField(default=now) + description = models.CharField(null=False, max_length=500) + def __str__(self): + return "Name:" + self.name + "Description:" + self.description # Create a plain Python class `CarDealer` to hold dealer data - # Create a plain Python class `DealerReview` to hold review data From 24ae495efc4576133e1f5ec55563da0815e6007f Mon Sep 17 00:00:00 2001 From: Marvin Date: Tue, 29 Aug 2023 15:55:53 -0400 Subject: [PATCH 6/8] Week 3, proxy services --- server/djangoapp/models.py | 32 +++++++++++ server/djangoapp/restapis.py | 108 +++++++++++++++++++++++++++++++++-- server/djangoapp/urls.py | 4 +- server/djangoapp/views.py | 41 ++++++++++--- 4 files changed, 171 insertions(+), 14 deletions(-) diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index 8b9d742c2b..e56a742d94 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -39,4 +39,36 @@ 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 +class DealerReview: + def __init__(self, dealership, name, purchase, review): + self.dealership = dealership + self.name = name + self.purchase = purchase + self.review = review + def __str__(self): + return "Dealer name: " + self.name + diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index b4d13f596a..beeac430e3 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -1,34 +1,130 @@ import requests import json # import related models here +from .models import CarDealer, DealerReview from requests.auth import HTTPBasicAuth - +from ibm_cloud_sdk_core.authenticators import IAMAuthenticator +from ibm_watson import NaturalLanguageUnderstandingV1 +from ibm_watson.natural_language_understanding_v1 import Features,SentimentOptions +import time # 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): + + # If argument contain API KEY + api_key = kwargs.get("api_key") + print("GET from {} ".format(url)) + try: + 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"] + response = requests.get(url, params=params, headers={'Content-Type': 'application/json'}, + auth=HTTPBasicAuth('apikey', api_key)) + else: + # 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) - +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): # - 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 + # For each dealer object + for dealer in dealers: + # Get its content in `doc` object + dealer_doc = dealer + # 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): + 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: + print("line 105",json_result) + reviews = json_result + 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"] + + sentiment = analyze_review_sentiments(review_obj.review) + print(sentiment) + review_obj.sentiment = sentiment + results.append(review_obj) - + return results # Create an `analyze_review_sentiments` method to call Watson NLU and analyze text # def analyze_review_sentiments(text): # - Call get_request() with specified arguments # - Get the returned sentiment label such as Positive or Negative - +def analyze_review_sentiments(text): + url = "https://api.us-east.natural-language-understanding.watson.cloud.ibm.com/instances/82a35a10-4051-4212-abd4-a1cd904ec957" + api_key = "5ZftXhylD7h-NR5ACWviXM1TRl2WOmhzoe9nXDXBZioq" + authenticator = IAMAuthenticator(api_key) + natural_language_understanding = NaturalLanguageUnderstandingV1(version='2021-08-01',authenticator=authenticator) + natural_language_understanding.set_service_url(url) + response = natural_language_understanding.analyze( text=text+"hello hello hello",features=Features(sentiment=SentimentOptions(targets=[text+"hello hello hello"]))).get_result() + label=json.dumps(response, indent=2) + label = response['sentiment']['document']['label'] + + + return(label) diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 0121471542..fba65a2dc1 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -23,10 +23,12 @@ path(route='login', view=views.login_request, name='login'), # path for logout - path(route='logout', view=views.logout_request, name='logout') + path(route='logout', view=views.logout_request, name='logout'), # path for dealer reviews view + path(route='dealer//', view=views.get_dealer_details, name='dealer_details'), # path for add a review view + 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 b9a089c292..15bb92bea2 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -6,6 +6,7 @@ # from .restapis import related methods from django.contrib.auth import login, logout, authenticate from django.contrib import messages +from .restapis import get_request, post_request, get_dealers_from_cf, get_dealer_reviews_from_cf from datetime import datetime import logging import json @@ -93,16 +94,42 @@ 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": - return render(request, 'djangoapp/index.html', context) - + url = "https://mwu0614-3000.theiadocker-0-labs-prod-theiak8s-4-tor01.proxy.cognitiveclass.ai/dealerships/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 -# def get_dealer_details(request, dealer_id): -# ... +def get_dealer_details(request, dealer_id): + if request.method == "GET": + url = "https://mwu0614-5000.theiadocker-0-labs-prod-theiak8s-4-tor01.proxy.cognitiveclass.ai/api/get_reviews?id=" + str(dealer_id) + reviews = get_dealer_reviews_from_cf(url) + dealer_names = ' '.join([dealer.name for dealer in reviews]) + return HttpResponse(dealer_names) + # Create a `add_review` view to submit a review -# def add_review(request, dealer_id): -# ... +def add_review(request, dealer_id): + 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: + review = dict() + json_payload["review"] = review + review["time"] = datetime.utcnow().isoformat() + review["dealership"] = 11 + review["review"] = "This is a great car dealer" + result = post_request(url, json_payload, dealerId=dealer_id) + return HttpResponse(result) + else: + return render(request, 'djangoapp/login.html', context) + else: + return render(request, 'djangoapp/login.html', context) From ae6e63d5bbef18f6fd1dfda2ff0bca98a6d629de Mon Sep 17 00:00:00 2001 From: Marvin Date: Tue, 29 Aug 2023 22:48:52 -0400 Subject: [PATCH 7/8] Week 4, dynamic pages in progress --- server/db.sqlite3 | Bin 143360 -> 143360 bytes server/djangoapp/models.py | 6 ++- server/djangoapp/restapis.py | 4 ++ .../templates/djangoapp/add_review.html | 16 ++++++ .../templates/djangoapp/dealer_details.html | 50 +++++++++++++++++- .../djangoapp/templates/djangoapp/index.html | 35 ++++++++++-- server/djangoapp/urls.py | 2 +- server/djangoapp/views.py | 36 ++++--------- 8 files changed, 116 insertions(+), 33 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 1134e2f1bf91debca12a6e84ffd58d894ac2d44d..28f72c9eb6b9dfdaacabd7cc96bd30a594139082 100644 GIT binary patch delta 294 zcmZp8z|ru4V}dke!bBNo#)ORtN%=y?1_}m-R;K1wM#g$ZMuuiaMw_qX8z^uv@or(@ zyT!X@W8(^5jV5I#R^R4O$IOD<^z=fLWP=RTr1ZkFE;_5 z7#ZstSn3)YBfG@h)Y5YEt$A9E98CP%8Tjw;Z{I9fu$o_0h1r*pkTaN?@2uZ`XFa2a g15oo}2L4CMI3O}HIy5#qH8(CZH#9RhIJ4AmFdzm2 z4%z??+OdJq4zt>xDgg!o58MC`+_MpI(hq~&ueaQ<0VqHQ0T1E;58|^CfY=YW;{O32 EFiesn>Hq)$ diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index e56a742d94..5291b8b7c0 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -64,11 +64,15 @@ def __str__(self): # Create a plain Python class `DealerReview` to hold review data class DealerReview: - def __init__(self, dealership, name, purchase, review): + def __init__(self, dealership, name, purchase, purchase_date, car_year, car_make, car_model, review): self.dealership = dealership self.name = name self.purchase = purchase + self.purchase_date = purchase_date self.review = review + self.car_year = car_year + self.car_make = car_make + self.car_model = car_model def __str__(self): return "Dealer name: " + self.name diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index beeac430e3..d3fbf410b7 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -92,6 +92,10 @@ def get_dealer_reviews_from_cf(url, **kwargs): name=dealer_review["name"], purchase=dealer_review["purchase"], review=dealer_review["review"], + purchase_date=dealer_review["purchase_date"], + car_year=dealer_review["car_year"], + car_make=dealer_review["car_make"], + car_model=dealer_review["car_model"] ) if "id" in dealer_review: review_obj.id = dealer_review["id"] diff --git a/server/djangoapp/templates/djangoapp/add_review.html b/server/djangoapp/templates/djangoapp/add_review.html index 768ddf508c..e113e937f4 100644 --- a/server/djangoapp/templates/djangoapp/add_review.html +++ b/server/djangoapp/templates/djangoapp/add_review.html @@ -12,5 +12,21 @@ +
    + + + + + + + \ No newline at end of file diff --git a/server/djangoapp/templates/djangoapp/dealer_details.html b/server/djangoapp/templates/djangoapp/dealer_details.html index c836fdde19..81b1d8c939 100644 --- a/server/djangoapp/templates/djangoapp/dealer_details.html +++ b/server/djangoapp/templates/djangoapp/dealer_details.html @@ -10,10 +10,56 @@ - +
    - +
    + {% for review in review_list %} +
    + {% if review.sentiment == "positive" %} + + {% elif review.sentiment == "negative" %} + + {% else %} + + {% endif %} +
    +
    {{review.car_model}}, {{review.car_make}}
    +
    {{review.purchase_date}}
    +

    {{review.review}}

    +
    +
    + {% endfor %} +
    \ No newline at end of file diff --git a/server/djangoapp/templates/djangoapp/index.html b/server/djangoapp/templates/djangoapp/index.html index 6d94f755ba..152921bae9 100644 --- a/server/djangoapp/templates/djangoapp/index.html +++ b/server/djangoapp/templates/djangoapp/index.html @@ -12,7 +12,6 @@ - - + + + + + + + + + + ... + + + + {% for dealer in dealership_list %} + + + + + + + + + {% 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 fba65a2dc1..0241636b24 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -29,6 +29,6 @@ path(route='dealer//', view=views.get_dealer_details, name='dealer_details'), # path for add a review view - path(route='dealer//', view=views.get_dealer_details, name='dealer_details') + path(route='add_review', view=views.add_review, name='add_review') ] + 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 15bb92bea2..b5d638b586 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -94,42 +94,28 @@ 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://mwu0614-3000.theiadocker-0-labs-prod-theiak8s-4-tor01.proxy.cognitiveclass.ai/dealerships/get" + url = "https://mwu0614-3000.theiadocker-1-labs-prod-theiak8s-4-tor01.proxy.cognitiveclass.ai/dealerships/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]) + context["dealership_list"] = dealerships # Return a list of dealer short name - return HttpResponse(dealer_names) + 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): + context = {} if request.method == "GET": - url = "https://mwu0614-5000.theiadocker-0-labs-prod-theiak8s-4-tor01.proxy.cognitiveclass.ai/api/get_reviews?id=" + str(dealer_id) + url = "https://mwu0614-5000.theiadocker-1-labs-prod-theiak8s-4-tor01.proxy.cognitiveclass.ai/api/get_reviews?id=" + str(dealer_id) reviews = get_dealer_reviews_from_cf(url) - dealer_names = ' '.join([dealer.name for dealer in reviews]) - return HttpResponse(dealer_names) + context["review_list"] = reviews + return render(request, 'djangoapp/dealer_details.html', context) # Create a `add_review` view to submit a review def add_review(request, dealer_id): - 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: - review = dict() - json_payload["review"] = review - review["time"] = datetime.utcnow().isoformat() - review["dealership"] = 11 - review["review"] = "This is a great car dealer" - result = post_request(url, json_payload, dealerId=dealer_id) - return HttpResponse(result) - else: - return render(request, 'djangoapp/login.html', context) - else: - return render(request, 'djangoapp/login.html', context) + context = {} + if request.method == "GET": + return render(request, 'djangoapp/add_review.html', context) From 2e56abdfa92647e2f76bfd35cf2e51956be88e4b Mon Sep 17 00:00:00 2001 From: Marvin Date: Wed, 30 Aug 2023 11:49:38 -0400 Subject: [PATCH 8/8] Week 4, in progess 2 --- server/djangoapp/admin.py | 4 +- server/djangoapp/models.py | 18 ++++--- server/djangoapp/restapis.py | 16 +++++- .../templates/djangoapp/add_review.html | 3 +- .../templates/djangoapp/dealer_details.html | 2 +- server/djangoapp/urls.py | 4 +- server/djangoapp/views.py | 54 ++++++++++++++++--- 7 files changed, 80 insertions(+), 21 deletions(-) diff --git a/server/djangoapp/admin.py b/server/djangoapp/admin.py index 3ee421215f..0305dae32b 100644 --- a/server/djangoapp/admin.py +++ b/server/djangoapp/admin.py @@ -10,7 +10,9 @@ class CarModelInline(admin.StackedInline): # CarModelAdmin class class CarModelAdmin(admin.ModelAdmin): - list_display = ('car_make', 'name', "dealer_id", "car_type", "year", ) + list_display = ('name', "id", "type", "year", ) + list_filter = ['id'] + search_fields = ['name'] # CarMakeAdmin class with CarModelInline class CarMakeAdmin(admin.ModelAdmin): inlines=[CarModelInline] diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index 5291b8b7c0..33d68d8441 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -28,10 +28,10 @@ def __str__(self): # - Any other fields you would like to include in car model # - __str__ method to print a car make object class CarModel(models.Model): - car_make = models.ForeignKey(CarMake, null=True, on_delete=models.CASCADE) + make = models.ForeignKey(CarMake, on_delete=models.CASCADE) name = models.CharField(null=False, max_length=30, default='new car model') - dealer_id = models.IntegerField() - car_type = models.CharField(null=False, max_length=100, choices=CHOICES) + id = models.IntegerField(default=1,primary_key=True) + type = models.CharField(null=False, max_length=100, choices=CHOICES) year = models.DateField(default=now) description = models.CharField(null=False, max_length=500) def __str__(self): @@ -64,15 +64,17 @@ def __str__(self): # Create a plain Python class `DealerReview` to hold review data class DealerReview: - def __init__(self, dealership, name, purchase, purchase_date, car_year, car_make, car_model, review): + def __init__(self, dealership, name, purchase, review, purchase_date, car_make, car_model, car_year, id): self.dealership = dealership self.name = name self.purchase = purchase - self.purchase_date = purchase_date self.review = review - self.car_year = car_year - self.car_make = car_make - self.car_model = car_model + self.purchase_date = "" + self.car_make = "" + self.car_model = "" + self.car_year = "" + self.sentiment = "" + self.id = "" def __str__(self): return "Dealer name: " + self.name diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index d3fbf410b7..188158b4fb 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -73,6 +73,19 @@ def get_dealers_from_cf(url, **kwargs): results.append(dealer_obj) return results +def get_dealer_by_id_from_cf(url, id, **kwargs): + results = [] + json_result = get_request(url, id=id) + if json_result: + for dealer in json_result: + if (dealer["id"] == dealerId): + 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 # - Call get_request() with specified arguments # - Parse JSON results into a DealerView object list @@ -95,7 +108,8 @@ def get_dealer_reviews_from_cf(url, **kwargs): purchase_date=dealer_review["purchase_date"], car_year=dealer_review["car_year"], car_make=dealer_review["car_make"], - car_model=dealer_review["car_model"] + car_model=dealer_review["car_model"], + id=dealer_review["id"] ) if "id" in dealer_review: review_obj.id = dealer_review["id"] diff --git a/server/djangoapp/templates/djangoapp/add_review.html b/server/djangoapp/templates/djangoapp/add_review.html index e113e937f4..f68a29211d 100644 --- a/server/djangoapp/templates/djangoapp/add_review.html +++ b/server/djangoapp/templates/djangoapp/add_review.html @@ -12,7 +12,7 @@ -
    +