mirror of
https://github.com/caperren/school_archives.git
synced 2025-11-09 21:51:15 +00:00
Added new coursework, cleaned up structure
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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...")
|
||||
@@ -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))
|
||||
|
||||
@@ -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...")
|
||||
@@ -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"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@@ -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.
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user