Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

complete second module #127

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
name: 'Lint Code'

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
on: workflow_dispatch

# on:
# push:
# branches: [master, main]
# pull_request:
# branches: [master, main]

jobs: # list of things to do
lint_function_js:
Expand Down
Binary file added server/db.sqlite3
Binary file not shown.
14 changes: 14 additions & 0 deletions server/djangoapp/admin.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
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 = 6

# CarModelAdmin class
class CarModelAdmin(admin.ModelAdmin):
list_display = ['name', 'dealer_id', 'c_type', 'year']
search_fields = ['name']


# CarMakeAdmin class with CarModelInline
class CarMakeAdmin(admin.ModelAdmin):
inlines = [CarModelInline]
list_display = ['name', 'description']
search_fields = ['name']

# Register models here
admin.site.register(CarMake, CarMakeAdmin)
admin.site.register(CarModel)
63 changes: 63 additions & 0 deletions server/djangoapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
# - 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)
description = models.CharField(null=False, max_length=30)

def __str__(self):
return self.name + "" + self.description


# <HINT> Create a Car Model model `class CarModel(models.Model):`:
Expand All @@ -19,9 +25,66 @@
# - 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):
TYPES = (
("SEDAN", "Sedan"), ("SUV", "SUV"), ("WAGON", "Wagon"), ("LIMOUSINE", "Limousine"), ("BATMOBILE", "Batmobile")
)

make = models.ForeignKey(CarMake, on_delete=models.CASCADE)
name = models.CharField(null=False, max_length=30)
c_type = models.CharField(max_length=30, choices=TYPES)
dealer_id = models.IntegerField()
year = models.DateField()

def __str__(self):
return "Name: " + self.name + \
" Make Name: "+ self.make.name + \
" Type: " + self.c_type + \
" Dealer ID: " + str(self.dealer_id)+ \
" Year: " + str(self.year)



# <HINT> 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

# <HINT> Create a plain Python class `DealerReview` to hold review data
class DealerReview:
def __init__(self, dealership, name, purchase, review, purchase_date, car_make, car_model, car_year,sentiment, id):
self.dealership=dealership
self.name=name
self.purchase=purchase
self.review=review
self.purchase_date=purchase_date
self.car_make=car_make
self.car_model=car_model
self.car_year=car_year
self.sentiment=sentiment #Watson NLU service
self.id=id

def __str__(self):
return "Review: " + self.review +\
" Sentiment: " + self.sentiment
93 changes: 88 additions & 5 deletions server/djangoapp/restapis.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,117 @@
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))
json_data={}
try:
if "apikey" in kwargs:
response = requests.get(url, headers={'Content-Type':'application/json'}, params=kwargs, auth=HTTPBasicAuth("apikey", kwargs["apikey"]))
else:
response = requests.get(url, headers={'Content-Type':'application/json'}, params=kwargs)

status_code = response.status_code
print("With status {} ".format(status_code))
json_data = json.loads(response.text)
#print(json_data)
except Exception as e:
print("Error " ,e)

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(url)
print(payload)
print(kwargs)
try:
response = requests.post(url, params=kwargs, json=payload)
except Exception as e:
print("Error" ,e)
print("Status Code ", {response.status_code})
data = json.loads(response.text)
return 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)
#print(json_result)
if json_result:
# Get the row list in JSON as dealers
dealers = json_result["entries"]
# For each dealer object
for dealer_doc in dealers:
# Get its content in `doc` object
#dealer_doc = dealers["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
#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).


# 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, dealer_id):
results = []
# Call get_request with a URL parameter
json_result = get_request(url, dealerId=dealer_id)

if "entries" in json_result:
reviews = json_result["entries"]
# For each review object
for review in reviews:
review_obj = DealerReview(
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=analyze_review_sentiments(review["review"]),
id=review['id']
)
results.append(review_obj)
#print(results[0])
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(dealerreview, **kwargs):
API_KEY="MxFCXuNdAY4i7RdB1PTx0LGspyMbNVmVOKxtpJ5XPxkz"
#API_KEY="0614ccd0-1e9f-4d49-923e-e7741f963747:Q3ZX2R1b3oBEb0XebEO99rpulJ31yoY7X5GfjoQykN4RpM9eThYrrs14If0aOHtG"
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'
params = json.dumps({"text": dealerreview, "features": {"sentiment": {}}})
response = requests.post(NLU_URL,data=params,headers={'Content-Type':'application/json'},auth=HTTPBasicAuth("apikey", API_KEY))

#print(response.json())
try:
sentiment=response.json()['sentiment']['document']['label']
return sentiment
except:
return "neutral"
45 changes: 45 additions & 0 deletions server/djangoapp/templates/djangoapp/about.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dealership Review - About</title>
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://unpkg.com/[email protected]/dist/bootstrap-table.min.css" rel="stylesheet">
<script src="https://unpkg.com/[email protected]/dist/bootstrap-table.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/extensions/filter-control/bootstrap-table-filter-control.min.js"></script>

</head>

<body>
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<div class="me">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link active" aria-current="page" href="{% url 'djangoapp:index' %}">Home</a>
<a class="nav-link" href="{% url 'djangoapp:about' %}">About</a>
<a class="nav-link" href="{% url 'djangoapp:contact' %}">Contact</a>
</div>
</div>
</div>
</div>
</nav>
<main>
<div class="container">
<h1>About Us</h1>
<hr>
<p>
Welcome to Best Cars dealership, home to the best cars in North America. We sell domestic and imported cars at reasonable prices.
</p>
</div>
</main>
</body>
</html>
87 changes: 76 additions & 11 deletions server/djangoapp/templates/djangoapp/add_review.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% load static %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/css/bootstrap-datepicker.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/js/bootstrap-datepicker.js"></script>

</head>
<body>
<head>
<meta charset="UTF-8">
<title>Dealership Review - About</title>
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://unpkg.com/[email protected]/dist/bootstrap-table.min.css" rel="stylesheet">
<script src="https://unpkg.com/[email protected]/dist/bootstrap-table.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/extensions/filter-control/bootstrap-table-filter-control.min.js"></script>

</head>

<body>
<nav class="navbar navbar-expand-lg bg-primary mb-3" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Dealership Review<a>
<div class="me">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link active" aria-current="page" href="{% url 'djangoapp:index' %}">Home</a>
<a class="nav-link" href="{% url 'djangoapp:about' %}">About</a>
<a class="nav-link" href="{% url 'djangoapp:contact' %}">Contact</a>
{% if user.is_authenticated %}
<a class="nav-link" >( {{user.username}} )</a>
<a class="nav-link" href="{% url 'djangoapp:logout' %}">Sign Out</a>
{% else %}
<form action="{% url 'djangoapp:login' %}" method="POST" class="d-flex" role="login">
{% csrf_token %}
<input class="form-control me-2" type="text" placeholder="username" name="username" aria-label="username">
<input class="form-control me-2" type="password" placeholder="password" name="password" aria-label="password">
<button class="btn btn-success" type="submit">Login</button>
</form>
<a class="nav-link" href="{% url 'djangoapp:register' %}">Sign Up</a>
{% endif %}
</div>
</div>
</div>
</div>
</nav>
<!--Add review form here -->
<main>
<div class="container p-3">
<form class="border border-dark p-4 w-auto h-auto text-center bg-light" action="{% url 'djangoapp:add_review' dealer_id %}" method="post">
{% csrf_token %}

<h1 class="text-center">Review for {{dealer_name}}</h1><br>
<label for="name"><b>Name</b></label>
<br>
<input class="form-control" type="text" placeholder="Enter Your Name: " name="name" required>
<label for="content"><b>Review</b></label>
<br>
<textarea class="form-control" id="content" name="content" rows="2" required placeholder="Write your review here: "></textarea>
<br>
<input class="form-check-input" type="checkbox" name="purchasecheck" id="purchasecheck">
<label for="purchasecheck"><b>Did your purchase from this dealership?</b></label>
<br>
<label for="car"><b>Select vehicle (if purchased)</b></label>
<br>
<select name="car" id="car" class="form-select" required>
{% for car in cars %}
<option selected value="{{car.make.name}}|{{car.name}}|{{ car.year|date:'Y' }}">{{ car.year|date:"Y" }} {{car.make.name}} {{car.name}}</option>
{% endfor %}
</select>

<br>
<label for="purchase_date"><b>When was this purchased?</b></label>
<input class="date-own form-control" type="date" name="purchase_date" id="purchase_date">
<br>
<button class="btn btn-warning btn-lg" type="submit">Submit Review</button>
</form>
</div>
</main>
</body>
</html>
Loading