Added new coursework, cleaned up structure

This commit is contained in:
2017-11-29 10:11:54 -08:00
parent b300c76103
commit 808a0f1724
345 changed files with 126653 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
import webapp2
from google.appengine.ext import ndb
import json
from SlipHandlerCore import Slip
REQUIRED_POST_VALUES = {"name", "type", "length"}
DESIRED_BOAT_LIST_KEYS = ["name", "type", "length", "at_sea", "id"]
AVAILABLE_KEYS_TO_REPLACE_MODIFY = ["name", "type", "length", "at_sea"]
class Boat(ndb.Model):
name = ndb.StringProperty(required=True)
type = ndb.StringProperty(required=True)
length = ndb.IntegerProperty(required=True)
at_sea = ndb.BooleanProperty(required=True)
id = ndb.StringProperty()
class BoatHandler(webapp2.RequestHandler):
def get(self, boat_id=None):
# If we have an id, show only the one boat
if boat_id:
key = ndb.Key(urlsafe=boat_id)
boat_to_view_raw = key.get()
if not boat_to_view_raw:
self.error(404)
return
boat_to_view_dict = boat_to_view_raw.to_dict()
self.response.write(json.dumps(boat_to_view_dict))
# If we have no id, show all boats
else:
boats = Boat.query().fetch()
output_array = []
for boat in boats:
boat_dict = boat.to_dict()
temp_dict = {current_key: boat_dict[current_key] for current_key in DESIRED_BOAT_LIST_KEYS}
output_array.append(temp_dict)
self.response.write(json.dumps(output_array))
def post(self):
parsed_json = json.loads(self.request.body)
if not REQUIRED_POST_VALUES <= set(parsed_json):
self.error(404)
self.response.write("POST missing one or more required fields...")
return
boat_name = parsed_json["name"]
boat_type = parsed_json["type"]
boat_length = parsed_json["length"]
new_boat = Boat(name=boat_name, type=boat_type, length=boat_length, at_sea=True)
new_boat.put()
new_boat.id = new_boat.key.urlsafe()
new_boat.put()
self.response.write(json.dumps(new_boat.to_dict()))
def delete(self, boat_id):
# Check to make sure the boat is valid.
key = ndb.Key(urlsafe=boat_id)
boat_to_delete = key.get()
if not boat_to_delete:
self.error(404)
return
# Check if the boat is currently docked in a slip, if so, undock it.
slips = Slip.query(Slip.current_boat == boat_id).fetch()
for slip in slips:
slip.current_boat = None
slip.arrival_date = None
slip.put()
boat_to_delete.key.delete()
def put(self, boat_id):
key = ndb.Key(urlsafe=boat_id)
boat_to_replace_raw = key.get()
if not boat_to_replace_raw:
self.error(404)
return
parsed_json = json.loads(self.request.body)
if not len(parsed_json):
self.error(404)
self.response.write("PUT missing parameters to replace...")
return
if "at_sea" in parsed_json:
if parsed_json["at_sea"] is True and boat_to_replace_raw.at_sea is False:
# Undock the ship, as we're leaving
slips = Slip.query(Slip.current_boat == boat_id).fetch()
for slip in slips:
slip.current_boat = None
slip.arrival_date = None
slip.put()
temp_dict = {current_key: parsed_json[current_key] for current_key in AVAILABLE_KEYS_TO_REPLACE_MODIFY}
boat_to_replace_raw.populate(**temp_dict)
boat_to_replace_raw.put()
self.response.write(json.dumps(boat_to_replace_raw.to_dict()))
def patch(self, boat_id):
key = ndb.Key(urlsafe=boat_id)
boat_to_modify_raw = key.get()
if not boat_to_modify_raw:
self.error(404)
return
parsed_json = json.loads(self.request.body)
if not len(parsed_json) or len(parsed_json) > 1:
self.error(404)
self.response.write("PATCH has incorrect number of parameters to modify...")
return
key, _ = parsed_json.items()[0]
if key in AVAILABLE_KEYS_TO_REPLACE_MODIFY:
if "at_sea" in parsed_json:
if parsed_json["at_sea"] is True and boat_to_modify_raw.at_sea is False:
# Undock the ship, as we're leaving
slips = Slip.query(Slip.current_boat == boat_id).fetch()
for slip in slips:
slip.current_boat = None
slip.arrival_date = None
slip.put()
boat_to_modify_raw.populate(**parsed_json)
boat_to_modify_raw.put()
self.response.write(json.dumps(boat_to_modify_raw.to_dict()))
else:
self.error(404)
self.response.write("PATCH parameter not valid...")

View File

@@ -0,0 +1,70 @@
import webapp2
from google.appengine.ext import ndb
import json
REQUIRED_POST_VALUES = {"slip_id", "arrival_date"}
class MarinaHandler(webapp2.RequestHandler):
def post(self, boat_id):
parsed_json = json.loads(self.request.body)
if not REQUIRED_POST_VALUES <= set(parsed_json):
self.error(404)
self.response.write("POST missing one or more required fields...")
return
# First check to make sure the boat exists, and if so, get a reference to it.
key = ndb.Key(urlsafe=boat_id)
boat_to_dock = key.get()
if not boat_to_dock:
self.error(404)
return
# Then, we're also going to check to make sure the slip exists, and if so get a reference to it.
key = ndb.Key(urlsafe=parsed_json["slip_id"])
slip_to_view_raw = key.get()
if not slip_to_view_raw:
self.error(404)
return
# Now, we're going to check to make sure the slip isn't already occupied.
if slip_to_view_raw.current_boat:
self.error(403)
return
# Since all the data is valid, we're going to dock the boat.
# Fist assign the boat to the slip, and update the arrival date
slip_to_view_raw.current_boat = boat_to_dock.id
slip_to_view_raw.arrival_date = parsed_json["arrival_date"]
slip_to_view_raw.put()
# Now change the boat to NOT be at sea anymore
boat_to_dock.at_sea = False
boat_to_dock.put()
# Let's return the boat and slip information just for verification
output_dict = {"slip": slip_to_view_raw.to_dict(), "boat": boat_to_dock.to_dict()}
self.response.write(json.dumps(output_dict))
def get(self, slip_id):
key = ndb.Key(urlsafe=slip_id)
slip_to_view_raw = key.get()
if not slip_to_view_raw:
self.error(404)
return
if not slip_to_view_raw.current_boat:
self.error(404)
return
key = ndb.Key(urlsafe=slip_to_view_raw.current_boat)
boat_to_view_raw = key.get()
boat_to_view_dict = boat_to_view_raw.to_dict()
self.response.write(json.dumps(boat_to_view_dict))

View File

@@ -0,0 +1,140 @@
import webapp2
from google.appengine.ext import ndb
import json
REQUIRED_POST_VALUES = {"number"}
DESIRED_BOAT_LIST_KEYS = ["number", "current_boat", "arrival_date", "id"]
AVAILABLE_KEYS_TO_REPLACE_MODIFY = ["number", "current_boat", "arrival_date"]
class Slip(ndb.Model):
number = ndb.IntegerProperty(required=True)
current_boat = ndb.StringProperty()
arrival_date = ndb.StringProperty()
id = ndb.StringProperty()
class SlipHandler(webapp2.RequestHandler):
def get(self, slip_id=None):
# If we have an id, show only the one boat
if slip_id:
key = ndb.Key(urlsafe=slip_id)
slip_to_view_raw = key.get()
if not slip_to_view_raw:
self.error(404)
return
slip_to_view_dict = slip_to_view_raw.to_dict()
self.response.write(json.dumps(slip_to_view_dict))
# If we have no id, show all boats
else:
slips = Slip.query().fetch()
output_array = []
for slip in slips:
slip_dict = slip.to_dict()
temp_dict = {current_key: slip_dict[current_key] for current_key in DESIRED_BOAT_LIST_KEYS}
output_array.append(temp_dict)
self.response.write(json.dumps(output_array))
def post(self):
parsed_json = json.loads(self.request.body)
if not REQUIRED_POST_VALUES <= set(parsed_json):
self.error(404)
self.response.write("POST missing one or more required fields...")
return
desired_slip_number = parsed_json["number"]
slip_number_exists = len(Slip.query(Slip.number == desired_slip_number).fetch()) > 0
if slip_number_exists:
self.error(404)
self.response.write("POST for slip number " + str(desired_slip_number) + " failed. Slip already exists.")
return
new_slip = Slip(number=desired_slip_number, current_boat=None, arrival_date=None)
new_slip.put()
new_slip.id = new_slip.key.urlsafe()
new_slip.put()
self.response.write(json.dumps(new_slip.to_dict()))
def delete(self, slip_id):
key = ndb.Key(urlsafe=slip_id)
slip_to_delete = key.get()
if not slip_to_delete:
self.error(404)
return
# Put boat at sea if slip occupied
if slip_to_delete.current_boat:
key = ndb.Key(urlsafe=slip_to_delete.current_boat)
boat_to_undock = key.get()
if boat_to_undock:
boat_to_undock.at_sea = True
boat_to_undock.put()
slip_to_delete.key.delete()
def put(self, slip_id):
key = ndb.Key(urlsafe=slip_id)
slip_to_replace_raw = key.get()
if not slip_to_replace_raw:
self.error(404)
return
parsed_json = json.loads(self.request.body)
if not len(parsed_json):
self.error(404)
self.response.write("PUT missing parameters to replace...")
return
temp_dict = {current_key: parsed_json[current_key] for current_key in AVAILABLE_KEYS_TO_REPLACE_MODIFY}
slip_to_replace_raw.populate(**temp_dict)
slip_to_replace_raw.put()
self.response.write(json.dumps(slip_to_replace_raw.to_dict()))
def patch(self, slip_id):
key = ndb.Key(urlsafe=slip_id)
slip_to_modify_raw = key.get()
if not slip_to_modify_raw:
self.error(404)
return
parsed_json = json.loads(self.request.body)
if not len(parsed_json) or len(parsed_json) > 1:
self.error(404)
self.response.write("PATCH has incorrect number of parameters to modify...")
return
key, _ = parsed_json.items()[0]
if key in AVAILABLE_KEYS_TO_REPLACE_MODIFY:
slip_to_modify_raw.populate(**parsed_json)
slip_to_modify_raw.put()
self.response.write(json.dumps(slip_to_modify_raw.to_dict()))
else:
self.error(404)
self.response.write("PATCH parameter not valid...")

View File

@@ -0,0 +1,15 @@
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: .*
script: main.app
libraries:
- name: webapp2
version: "2.5.2"

View File

@@ -0,0 +1,11 @@
indexes:
# AUTOGENERATED
# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED"). If you want to manage some indexes
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env python
# Breakdown of required URLS
# /boats/{id} -- Specific boat
# /boats -- All boats
# /slips/{id} -- Specific slip
# /slips -- All slips
# Operations Needed
# Add (POST)
# Delete (DELETE)
# Modify (PATCH)
# Replace (PUT)
# View (GET)
import webapp2
from BoatHandleCore import BoatHandler
from SlipHandlerCore import SlipHandler
from MarinaHandlerCore import MarinaHandler
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write(
"This is the main page for the REST Implementation and Planning assignment in CS496."
"<br>Written by Corwin Perren.")
allowed_methods = webapp2.WSGIApplication.allowed_methods
new_allowed_methods = allowed_methods.union(('PATCH',))
webapp2.WSGIApplication.allowed_methods = new_allowed_methods
app = webapp2.WSGIApplication([
webapp2.Route("/", MainHandler, "main-handler"),
webapp2.Route("/slips", SlipHandler, "slip-handler"),
webapp2.Route("/slips/<slip_id>", SlipHandler, "slip-handler"),
webapp2.Route("/slips/<slip_id>/boat", MarinaHandler, "marina-handler"),
webapp2.Route("/boats", BoatHandler, "boat-handler"),
webapp2.Route("/boats/<boat_id>", BoatHandler, "boat-handler"),
webapp2.Route("/boats/<boat_id>/slip", MarinaHandler, "marina-handler")
], debug=True)