def test_new_instance_should_be_added_in_collection(self): self.assertEqual(set(Bike.collection()), set()) bike = Bike() self.assertEqual(set(Bike.collection()), set()) bike1 = Bike(name="trotinette") self.assertEqual(set(Bike.collection()), set([bike1._pk])) bike2 = Bike(name="tommasini") self.assertEqual(set(Bike.collection()), set([bike1._pk, bike2._pk]))
def get(self): error_list = [] profile = get_profile() template_values = make_user_links(self.request.uri) key = self.request.get('key') # below test is a bit of a hack because an empty key is returned as the string 'None' sometimes if key and (key != 'None'): b_key = ndb.Key(urlsafe=key) bike = b_key.get() template_values['submitValue'] = 'Update' if bike: if b_key.parent() != profile.key: error_list.append('Attempt to edit bike not owned by user') else: error_list.append('Bike not found') else: key = None bike = Bike() template_values['submitValue'] = 'Create' if len(error_list) > 0: logging.info('%s' % error_list) self.redirect('user/errorPage') else: template = jinjaEnvironment.get_template('template/bikeentry.html') template_values['menu'] = make_menu(page='user/bikeentry') bike_form = BikeForm(obj=bike) bike_form.bikeType.choices = [(bikeType.key.urlsafe(), bikeType.name) for bikeType in BikeType.query().fetch()] bike_form.bikeType.data = (bike.bikeType.urlsafe() if bike.bikeType else 0) template_values['form'] = bike_form template_values['key'] = key self.response.out.write(template.render(template_values))
def get(self): profile = get_profile() template_values = make_user_links(self.request.uri) error_list = [] key = self.request.get('key') if key and (key != 'None'): r_key = ndb.Key(urlsafe=key) bike_ride = r_key.get() template_values['submitValue'] = 'Update' if bike_ride: if r_key.parent() != profile.key: error_list.append('Attempt to edit bikeRide not owned by user') else: error_list.append('bikeRide not found') else: key = None bike_ride = BikeRide() template_values['submitValue'] = 'Create' if len(error_list) > 0: logging.info('%s' % error_list) self.redirect('/user/errorPage') else: bike_ride_form = BikeRideForm(obj=bike_ride) bike_ride_form.bike.choices = [(bike.key.urlsafe(), bike.brand + ' ' + bike.model) for bike in Bike.query(ancestor=profile.key).fetch()] bike_ride_form.bike.data = (bike_ride.bike.urlsafe() if bike_ride.bike else 0) bike_ride_form.rideType.choices = [(rideType.key.urlsafe(), rideType.name) for rideType in RideType.query().fetch()] bike_ride_form.rideType.data = (bike_ride.rideType.urlsafe() if bike_ride.rideType else 0) template_values['form'] = bike_ride_form template = jinjaEnvironment.get_template('template/rideentry.html') template_values['menu'] = make_menu(page='user/rideentry') template_values['key'] = key self.response.out.write(template.render(template_values))
def post(self): try: id = int(self.request.get('_id')) bike = Bike.get(db.Key.from_path('Bike', id)) except ValueError: bike = None id = None data = BikeForm(data=self.request.POST, instance=bike) if data.is_valid(): # Save and redirect to admin home page entity = data.save(commit=False) entity.bikeRider = users.get_current_user() entity.put() self.redirect('/user/bikeoverview') else: # back to form for editing path = os.path.join(os.path.dirname(__file__), 'template/bikeentry.html') template_values = makeUserLinks(self.request.uri) template_values['menu'] = makeMenu(page='user/bikeentry') template_values['submitValue'] = 'Fix' template_values['form'] = data template_values['id'] = id self.response.out.write(template.render(path, template_values))
def get(self): profile = get_profile() template = jinjaEnvironment.get_template('template/bikeoverview.html') template_values = make_user_links(self.request.uri) template_values['menu'] = make_menu(page='user/bikeoverview') template_values['bikes'] = Bike.query(ancestor=profile.key).fetch() template_values['biketypes'] = BikeType.query().fetch() self.response.out.write(template.render(template_values))
def get(self): path = os.path.join(os.path.dirname(__file__), 'template/bikeoverview.html') template_values = makeUserLinks(self.request.uri) template_values['menu'] = makeMenu(page='user/bikeoverview') template_values['bikes'] = Bike.all().filter('bikeRider = ', users.get_current_user()) template_values['biketypes'] = BikeType.all() self.response.out.write(template.render(path, template_values))
def test_end_update_local_bike(result): """ This function will be used as a post_callback when setting a new name of the local bike object. It tests than, as we updated a lockable field, we only have the local bike in redis as for now, the one in the thread should have waited for the local save to be finished. """ self.assertEqual(len(Bike.collection()), 1) return result
def post(self): error_list = [] profile = get_profile() key = self.request.get('key') if key and (key != 'None'): b_key = ndb.Key(urlsafe=key) bike = b_key.get() if bike: if b_key.parent() != profile.key: error_list.append('Attempt to edit bike not owned by user') else: error_list.append('Bike not found') else: bike = Bike(parent=profile.key) if len(error_list) > 0: logging.info('%s' % error_list) self.redirect('user/errorPage') else: form_data = BikeForm(self.request.POST, bike) form_data.bikeType.choices = [(bikeType.key.urlsafe(), bikeType.name) for bikeType in BikeType.query().fetch()] logging.info('%s' % form_data.bikeType.data) if form_data.validate(): # Save and redirect to bike overview page form_data.bikeType.data = ndb.Key( urlsafe=form_data.bikeType.data) # translate urlsafe key string to actual key form_data.populate_obj(bike) bike.put() self.redirect('/user/bikeoverview') else: # back to form for editing template = jinjaEnvironment.get_template('template/bikeentry.html') template_values = make_user_links(self.request.uri) template_values['menu'] = make_menu(page='user/bikeentry') template_values['submitValue'] = 'Fix' template_values['form'] = form_data template_values['key'] = key self.response.out.write(template.render(template_values))
def get(self): template_values = makeUserLinks(self.request.uri) try: id = int(self.request.get('id')) bike = Bike.get(db.Key.from_path('Bike', id)) template_values['submitValue'] = 'Update' except ValueError: id = None bike = None template_values['submitValue'] = 'Create' path = os.path.join(os.path.dirname(__file__), 'template/bikeentry.html') template_values['menu'] = makeMenu(page='user/bikeentry') template_values['form'] = BikeForm(instance=bike) template_values['id'] = id self.response.out.write(template.render(path, template_values))
def stations_to_db(data): session = Session() stations = json.loads(data) print(type(stations), len(stations)) for station in stations: timestamp = station.get('last_update') time_standard = timestamp_convert(timestamp) kwargs = {'station_id': int(station.get('number')), 'bike_stands': int(station.get('bike_stands')), 'available_bike_stands': int(station.get('available_bike_stands')), 'available_bikes': int(station.get('available_bikes')), 'status': station.get('status'), 'last_update': time_standard } row_bike = Bike(**kwargs) session.add(row_bike) session.commit() session.close() return
def post(self): error_list = [] profile = get_profile() key = self.request.get('key') if key and (key != 'None'): r_key = ndb.Key(urlsafe=key) bike_ride = r_key.get() if bike_ride: if r_key.parent() != profile.key: error_list.append('Attempt to edit bikeRide not owned by user') else: error_list.append('bikeRide not found') else: bike_ride = BikeRide(parent=profile.key) if len(error_list) > 0: logging.info('%s' % error_list) self.redirect('/user/errorPage') else: form_data = BikeRideForm(self.request.POST, bike_ride) form_data.bike.choices = [(bike.key.urlsafe(), bike.brand) for bike in Bike.query().fetch()] form_data.rideType.choices = [(rideType.key.urlsafe(), rideType.name) for rideType in RideType.query().fetch()] logging.info("data from bikeride form is: %s", form_data) logging.info("data from the bikeride request is: %s", self.request) if form_data.validate(): form_data.bike.data = ndb.Key(urlsafe=form_data.bike.data) form_data.rideType.data = ndb.Key(urlsafe=form_data.rideType.data) form_data.populate_obj(bike_ride) bike_ride.put() self.redirect('/user/rideroverview') else: template = jinjaEnvironment.get_template('template/rideentry.html') template_values = make_user_links(self.request.uri) template_values['menu'] = make_menu(page='user/rideentry') template_values['submitValue'] = 'Fix' template_values['form'] = form_data template_values['key'] = key self.response.out.write(template.render(template_values))
def add_bike(): """ Takes bike object from BikeIndex API and adds bike info to db""" bike_JSON= request.form.get("bike") # Get JSON bike object from ajax ({bike: bikedata}) bike = json.loads(bike_JSON) # JSON string --> Python dictionary if bike["stolen"]: return "Stolen bike! Do not add." # Create new bike instance for bike table new_bike = Bike() # Populate bike attributes new_bike.id = bike["id"] new_bike.user_id = g.user new_bike.serial = bike["serial"] new_bike.size = bike["frame_size"] new_bike.manufacturer = bike["manufacturer_name"] new_bike.rear_tire_narrow = bike["rear_tire_narrow"] new_bike.type_of_cycle = bike["type_of_cycle"] new_bike.bikeindex_url = bike["url"] new_bike.photo = bike["photo"] new_bike.thumb = bike["thumb"] new_bike.title = bike["manufacturer_name"] + " " + bike["frame_model"] new_bike.frame_model = bike["frame_model"] new_bike.year = bike["year"] new_bike.paint_description = bike["paint_description"] new_bike.front_tire_narrow = bike["front_tire_narrow"] # list of valid size categories valid_sizes = ['xs','s','m','l','xl'] # normalizing frame size measurements if len(new_bike.size) > 0 and new_bike.size not in valid_sizes: if new_bike.size.endswith('in'): # converting inches to centimeters size_convert = float(new_bike.size[:-2]) * 2.54 elif new_bike.size.endswith('cm'): # floating the cm size_convert = float(new_bike.size[:-2]) else: size_convert = "no need to convert" new_bike.size_category = new_bike.size # putting sizes into categories if type(size_convert) is float: if size_convert < 50: new_bike.size_category = "xs" elif size_convert >= 50 and size_convert <= 53: new_bike.size_category = "s" elif size_convert > 53 and size_convert <= 56: new_bike.size_category = "m" elif size_convert > 56 and size_convert <= 59: new_bike.size_category = "l" elif size_convert > 59: new_bike.size_category = "xl" # changing size abbrevation for display size_to_display = {"xs": "Extra Small", "s":"Small", "m":"Medium", "l":"Large", "xl": "Extra Lsarge" } if new_bike.size in valid_sizes: new_bike.size = size_to_display[new_bike.size] # breaking frame colors out of list format new_bike.frame_colors = "" for color in bike["frame_colors"]: new_bike.frame_colors += color if bike["handlebar_type"] != None: new_bike.handlebar_type = bike["handlebar_type"].get("name", None) if bike["frame_material"] != None: new_bike.frame_material = bike["frame_material"].get("name", None) if bike["rear_wheel_size"] != None: new_bike.rear_wheel_size = bike["rear_wheel_size"].get("name", None) new_bike.rear_wheel_size_iso_bsd = bike["rear_wheel_size"].get("iso_bsd", None) if bike["front_wheel_size"] != None: new_bike.front_wheel_size = bike["front_wheel_size"].get("name", None) new_bike.front_wheel_size_iso_bsd = bike["front_wheel_size"].get("iso_bsd", None) if bike["front_gear_type"] != None: new_bike.front_gear_type = bike["front_gear_type"].get("name", None) if bike["rear_gear_type"] != None: new_bike.rear_gear_type = bike["rear_gear_type"].get("name", None) # Add bike to session and commit changes db.session.add(new_bike) db.session.commit() # Store bike id in flask session (to remember it for listing) flask_session["bike"] = bike["id"] return "Added bike to database"
def test_two_updates_of_same_indexable_field_should_be_done_one_after_the_other(self): """ Will test that when a lockable field is updated, an external update on the same field (in this instance or another instance) wait for the first update to be finished. """ class BikeLockThread(LockTest.LockModelThread): methods = ['test_create_new_bike'] def test_create_new_bike(self): """ Create a new instance of the thread's model """ # test that we have a lock self.test_lock('name') # create the instance (does nothing in redis) bike = self.model() def test_before_update(name, *args, **kwargs): """ This function will be used as a pre_callback when setting a new name of the thread's bike object. It will test that we already have a bike in the collection. """ self.test.assertEqual(len(self.model.collection()), 1) return (args, kwargs) # set a name (will wait for lock to be released) bike.name.set('velocipede', _pre_callback=test_before_update) # start a new thread to work on the model Bike thread = BikeLockThread(self, Bike) thread.start() def ping_thread(name, *args, **kwargs): """ This function will be used as a pre_callback when setting a new name of the local bike object. It send a ping telling the thread that it must create a new bike, with a name. As the name of a bike is indexable, a Lock will occurs, so the new bike in the thread should only be created after the name of the local bike is really saved and indexed. """ time.sleep(0.1) # wait for thread to be ready LockTest.ping('test_create_new_bike') time.sleep(0.1) # to be sure the we can test lock in the thread return (args, kwargs) def test_end_update_local_bike(result): """ This function will be used as a post_callback when setting a new name of the local bike object. It tests than, as we updated a lockable field, we only have the local bike in redis as for now, the one in the thread should have waited for the local save to be finished. """ self.assertEqual(len(Bike.collection()), 1) return result # create a new bike (does nothing in redis) bike = Bike() # set a name to the bike and use pre/post callbacks to: # - ping the thread when the lock will be set # - test the thread did nothing just before the release of the lock bike.name.set('rosalie', _pre_callback=ping_thread, _post_callback=test_end_update_local_bike) # wait before thread exit if thread.is_alive(): LockTest.wait_for_ping('thread_end', None) # now we should have the both bikes fully created self.assertEqual(len(Bike.collection()), 2)
import uvicorn from fastapi import FastAPI from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse from typing import List from model import BikeState, BikeType, Bike, Station # Data for our small world. bike1 = Bike(id="B1", type=BikeType.NORMAL, stationed_at="S1", state=BikeState.FREE, battery=49) bike2 = Bike(id="B2", type=BikeType.FAST, stationed_at="S2", state=BikeState.FREE, battery=100) bike3 = Bike(id="B3", type=BikeType.NORMAL, stationed_at="S1", state=BikeState.BROKEN, battery=0) bikes = {} bikes[bike1.id] = bike1 bikes[bike2.id] = bike2 bikes[bike3.id] = bike3