Skip to content

Commit a051078

Browse files
add dynamic page
1 parent e3d4392 commit a051078

File tree

7 files changed

+379
-32
lines changed

7 files changed

+379
-32
lines changed

server/db.sqlite3

0 Bytes
Binary file not shown.

server/djangoapp/restapis.py

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,117 @@
11
import requests
22
import json
33
# import related models here
4+
from .models import CarDealer, DealerReview
45
from requests.auth import HTTPBasicAuth
56

67

8+
79
# Create a `get_request` to make HTTP GET requests
810
# e.g., response = requests.get(url, params=params, headers={'Content-Type': 'application/json'},
911
# auth=HTTPBasicAuth('apikey', api_key))
12+
def get_request(url, **kwargs):
13+
#print(kwargs)
14+
print("GET from {} ".format(url))
15+
json_data={}
16+
try:
17+
if "apikey" in kwargs:
18+
response = requests.get(url, headers={'Content-Type':'application/json'}, params=kwargs, auth=HTTPBasicAuth("apikey", kwargs["apikey"]))
19+
else:
20+
response = requests.get(url, headers={'Content-Type':'application/json'}, params=kwargs)
1021

22+
status_code = response.status_code
23+
print("With status {} ".format(status_code))
24+
json_data = json.loads(response.text)
25+
#print(json_data)
26+
except Exception as e:
27+
print("Error " ,e)
28+
29+
return json_data
1130

1231
# Create a `post_request` to make HTTP POST requests
1332
# e.g., response = requests.post(url, params=kwargs, json=payload)
14-
33+
def post_request(url, payload, **kwargs):
34+
print(url)
35+
print(payload)
36+
print(kwargs)
37+
try:
38+
response = requests.post(url, params=kwargs, json=payload)
39+
except Exception as e:
40+
print("Error" ,e)
41+
print("Status Code ", {response.status_code})
42+
data = json.loads(response.text)
43+
return data
1544

1645
# Create a get_dealers_from_cf method to get dealers from a cloud function
1746
# def get_dealers_from_cf(url, **kwargs):
1847
# - Call get_request() with specified arguments
1948
# - Parse JSON results into a CarDealer object list
49+
def get_dealers_from_cf(url, **kwargs):
50+
results = []
51+
# Call get_request with a URL parameter
52+
json_result = get_request(url)
53+
#print(json_result)
54+
if json_result:
55+
# Get the row list in JSON as dealers
56+
dealers = json_result["entries"]
57+
# For each dealer object
58+
for dealer_doc in dealers:
59+
# Get its content in `doc` object
60+
#dealer_doc = dealers["doc"]
61+
# Create a CarDealer object with values in `doc` object
62+
dealer_obj = CarDealer(address=dealer_doc["address"], city=dealer_doc["city"], full_name=dealer_doc["full_name"],
63+
id=dealer_doc["id"], lat=dealer_doc["lat"], long=dealer_doc["long"],
64+
short_name=dealer_doc["short_name"],
65+
st=dealer_doc["st"], zip=dealer_doc["zip"])
66+
results.append(dealer_obj)
67+
68+
return results
69+
#Coding practice: create a get_dealer_by_id or get_dealers_by_state method in restapis.py. HINT, the only difference from the get_dealers_from_cf method is adding a dealer id or state URL parameter argument when calling the def get_request(url, **kwargs): method such as get_request(url, dealerId=dealerId).
2070

2171

2272
# Create a get_dealer_reviews_from_cf method to get reviews by dealer id from a cloud function
2373
# def get_dealer_by_id_from_cf(url, dealerId):
2474
# - Call get_request() with specified arguments
2575
# - Parse JSON results into a DealerView object list
26-
76+
def get_dealer_reviews_from_cf(url, dealer_id):
77+
results = []
78+
# Call get_request with a URL parameter
79+
json_result = get_request(url, dealerId=dealer_id)
80+
81+
if "entries" in json_result:
82+
reviews = json_result["entries"]
83+
# For each review object
84+
for review in reviews:
85+
review_obj = DealerReview(
86+
dealership=review["dealership"],
87+
name=review["name"],
88+
purchase=review["purchase"],
89+
review=review["review"],
90+
purchase_date=review["purchase_date"],
91+
car_make=review["car_make"],
92+
car_model=review["car_model"],
93+
car_year=review["car_year"],
94+
sentiment=analyze_review_sentiments(review["review"]),
95+
id=review['id']
96+
)
97+
results.append(review_obj)
98+
#print(results[0])
99+
return results
27100

28101
# Create an `analyze_review_sentiments` method to call Watson NLU and analyze text
29102
# def analyze_review_sentiments(text):
30103
# - Call get_request() with specified arguments
31104
# - Get the returned sentiment label such as Positive or Negative
32-
33-
34-
105+
def analyze_review_sentiments(dealerreview, **kwargs):
106+
API_KEY="MxFCXuNdAY4i7RdB1PTx0LGspyMbNVmVOKxtpJ5XPxkz"
107+
#API_KEY="0614ccd0-1e9f-4d49-923e-e7741f963747:Q3ZX2R1b3oBEb0XebEO99rpulJ31yoY7X5GfjoQykN4RpM9eThYrrs14If0aOHtG"
108+
NLU_URL='https://api.us-south.natural-language-understanding.watson.cloud.ibm.com/instances/93a549ab-8f15-404e-a8ed-97f6fb8a35aa/v1/analyze?version=2020-08-01'
109+
params = json.dumps({"text": dealerreview, "features": {"sentiment": {}}})
110+
response = requests.post(NLU_URL,data=params,headers={'Content-Type':'application/json'},auth=HTTPBasicAuth("apikey", API_KEY))
111+
112+
#print(response.json())
113+
try:
114+
sentiment=response.json()['sentiment']['document']['label']
115+
return sentiment
116+
except:
117+
return "neutral"
Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,81 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
{% load static %}
6-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
7-
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/css/bootstrap-datepicker.css" rel="stylesheet">
8-
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
9-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
10-
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/js/bootstrap-datepicker.js"></script>
11-
12-
</head>
13-
<body>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Dealership Review - About</title>
6+
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> -->
7+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
8+
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
9+
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
10+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
11+
<link href="https://unpkg.com/[email protected]/dist/bootstrap-table.min.css" rel="stylesheet">
12+
<script src="https://unpkg.com/[email protected]/dist/bootstrap-table.min.js"></script>
13+
<script src="https://unpkg.com/[email protected]/dist/extensions/filter-control/bootstrap-table-filter-control.min.js"></script>
14+
15+
</head>
16+
17+
<body>
18+
<nav class="navbar navbar-expand-lg bg-primary mb-3" data-bs-theme="dark">
19+
<div class="container-fluid">
20+
<a class="navbar-brand" href="#">Dealership Review<a>
21+
<div class="me">
22+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
23+
<span class="navbar-toggler-icon"></span>
24+
</button>
25+
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
26+
<div class="navbar-nav">
27+
<a class="nav-link active" aria-current="page" href="{% url 'djangoapp:index' %}">Home</a>
28+
<a class="nav-link" href="{% url 'djangoapp:about' %}">About</a>
29+
<a class="nav-link" href="{% url 'djangoapp:contact' %}">Contact</a>
30+
{% if user.is_authenticated %}
31+
<a class="nav-link" >( {{user.username}} )</a>
32+
<a class="nav-link" href="{% url 'djangoapp:logout' %}">Sign Out</a>
33+
{% else %}
34+
<form action="{% url 'djangoapp:login' %}" method="POST" class="d-flex" role="login">
35+
{% csrf_token %}
36+
<input class="form-control me-2" type="text" placeholder="username" name="username" aria-label="username">
37+
<input class="form-control me-2" type="password" placeholder="password" name="password" aria-label="password">
38+
<button class="btn btn-success" type="submit">Login</button>
39+
</form>
40+
<a class="nav-link" href="{% url 'djangoapp:register' %}">Sign Up</a>
41+
{% endif %}
42+
</div>
43+
</div>
44+
</div>
45+
</div>
46+
</nav>
1447
<!--Add review form here -->
48+
<main>
49+
<div class="container p-3">
50+
<form class="border border-dark p-4 w-auto h-auto text-center bg-light" action="{% url 'djangoapp:add_review' dealer_id %}" method="post">
51+
{% csrf_token %}
52+
53+
<h1 class="text-center">Review for {{dealer_name}}</h1><br>
54+
<label for="name"><b>Name</b></label>
55+
<br>
56+
<input class="form-control" type="text" placeholder="Enter Your Name: " name="name" required>
57+
<label for="content"><b>Review</b></label>
58+
<br>
59+
<textarea class="form-control" id="content" name="content" rows="2" required placeholder="Write your review here: "></textarea>
60+
<br>
61+
<input class="form-check-input" type="checkbox" name="purchasecheck" id="purchasecheck">
62+
<label for="purchasecheck"><b>Did your purchase from this dealership?</b></label>
63+
<br>
64+
<label for="car"><b>Select vehicle (if purchased)</b></label>
65+
<br>
66+
<select name="car" id="car" class="form-select" required>
67+
{% for car in cars %}
68+
<option selected value="{{car.make.name}}|{{car.name}}|{{ car.year|date:'Y' }}">{{ car.year|date:"Y" }} {{car.make.name}} {{car.name}}</option>
69+
{% endfor %}
70+
</select>
71+
72+
<br>
73+
<label for="purchase_date"><b>When was this purchased?</b></label>
74+
<input class="date-own form-control" type="date" name="purchase_date" id="purchase_date">
75+
<br>
76+
<button class="btn btn-warning btn-lg" type="submit">Submit Review</button>
77+
</form>
78+
</div>
79+
</main>
1580
</body>
1681
</html>
Lines changed: 113 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,119 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<title>Dealership Review</title>
6-
{% load static %}
7-
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
8-
</head>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Dealership Review - About</title>
6+
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> -->
7+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
8+
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
9+
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
10+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
11+
<link href="https://unpkg.com/[email protected]/dist/bootstrap-table.min.css" rel="stylesheet">
12+
<script src="https://unpkg.com/[email protected]/dist/bootstrap-table.min.js"></script>
13+
<script src="https://unpkg.com/[email protected]/dist/extensions/filter-control/bootstrap-table-filter-control.min.js"></script>
14+
15+
</head>
16+
17+
<body>
18+
<nav class="navbar navbar-expand-lg bg-primary mb-3" data-bs-theme="dark">
19+
<div class="container-fluid">
20+
<a class="navbar-brand" href="#">Dealership Review<a>
21+
<div class="me">
22+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
23+
<span class="navbar-toggler-icon"></span>
24+
</button>
25+
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
26+
<div class="navbar-nav">
27+
<a class="nav-link active" aria-current="page" href="{% url 'djangoapp:index' %}">Home</a>
28+
<a class="nav-link" href="{% url 'djangoapp:about' %}">About</a>
29+
<a class="nav-link" href="{% url 'djangoapp:contact' %}">Contact</a>
30+
{% if user.is_authenticated %}
31+
<a class="nav-link" >( {{user.username}} )</a>
32+
<a class="nav-link" href="{% url 'djangoapp:logout' %}">Sign Out</a>
33+
{% else %}
34+
<form action="{% url 'djangoapp:login' %}" method="POST" class="d-flex" role="login">
35+
{% csrf_token %}
36+
<input class="form-control me-2" type="text" placeholder="username" name="username" aria-label="username">
37+
<input class="form-control me-2" type="password" placeholder="password" name="password" aria-label="password">
38+
<button class="btn btn-success" type="submit">Login</button>
39+
</form>
40+
<a class="nav-link" href="{% url 'djangoapp:register' %}">Sign Up</a>
41+
{% endif %}
42+
</div>
43+
</div>
44+
</div>
45+
</div>
46+
</nav>
947

10-
<body>
48+
<main>
49+
<div class="container p-3">
50+
{% if reviews %}
51+
<div class="card-columns row mb-3 g-5">
52+
{% for review in reviews %}
53+
<div class="col-4">
1154

12-
<!--Add a nav bar here -->
13-
14-
<!-- Add reviews as cards -->
15-
16-
</body>
55+
<div class="card" >
56+
<div class="card-header">
57+
<img class="card-img-left" src="{{MEDIA_URL}}/emoji/{{review.sentiment}}.png" width="40" height="40">
58+
</div>
59+
60+
<div class="card-body text-center">
61+
<h5 class="card-title">{{review.name}}</h5>
62+
<p class="card-text">{{review.review}}</p>
63+
</div>
64+
<div class="card-footer text-muted text-center" style="min-height: 74px;">
65+
{% if review.purchase == True%}
66+
{{review.car_year}} {{review.car_make}} {{review.car_model}}
67+
<br>
68+
Purchased on: {{review.purchase_date}}
69+
{% else %}
70+
<br>
71+
Reviewer did not make a purchase.
72+
{% endif %}
73+
</div>
74+
</div>
75+
</div>
76+
{% endfor %}
77+
<div class="card mt-3 pt-3">
78+
<div class="card-header">
79+
<h5 class="card-title text-center pt-1">Write Your Own Review!</h5>
80+
</div>
81+
<div class="card-body text-center">
82+
<p class="card-text">Want to review this dealership?</p>
83+
<p class="card-text">Click the button below!</p>
84+
</div>
85+
<div class="card-footer text-center" style="min-height: 74px;">
86+
{% if user.is_authenticated %}
87+
<a class="btn btn-warning btn-lg" type="submit" href="{% url 'djangoapp:add_review' dealer_id %}">Write a Review!</a>
88+
{% else %}
89+
<p class="btn btn-success btn-lg" disabled>Login to write a review!</p>
90+
{% endif %}
91+
</div>
92+
93+
</div>
94+
</div>
95+
{% else %}
96+
<div class="card mt-3 pt-3 col-4">
97+
<div class="card-header">
98+
<h5 class="card-title text-center">No Reviews</h5>
99+
</div>
100+
<div class="card-body">
101+
102+
103+
<p class="card-text text-center">There are no reviews for this dealership. Be the first to write one!</p>
17104

105+
</div>
106+
<div class="card-footer text-center" style="min-height: 74px;">
107+
{% if user.is_authenticated %}
108+
<a class="btn btn-warning btn-lg" type="submit" href="{% url 'djangoapp:add_review' dealer_id %}">Write a Review!</a>
109+
{% else %}
110+
<p class="btn btn-success nohover">Login to write a review!</p>
111+
{% endif %}
112+
</div>
113+
114+
</div>
115+
{% endif %}
116+
</div>
117+
</main>
118+
</body>
18119
</html>

0 commit comments

Comments
 (0)