def put(self, request, pk): """PUT allows updating in-air status.""" try: user = User.objects.get(pk=int(pk)) except User.DoesNotExist: return HttpResponseBadRequest('Unknown team %s' % pk) try: data = json.loads(request.body) except ValueError: return HttpResponseBadRequest('Invalid JSON: %s' % request.body) # We ignore everything except 'in_air' if 'in_air' in data: in_air = data['in_air'] if in_air is not True and in_air is not False: return HttpResponseBadRequest('in_air must be boolean') currently_in_air = TakeoffOrLandingEvent.user_in_air(user) # New event only necessary if changing status if currently_in_air != in_air: event = TakeoffOrLandingEvent(user=user, uas_in_air=in_air) event.save() return HttpResponse( json.dumps(user_json(user)), content_type="application/json")
def put(self, request, pk): """PUT allows updating in-air status.""" try: user = User.objects.get(pk=int(pk)) except User.DoesNotExist: return HttpResponseBadRequest('Unknown team %s' % pk) try: data = json.loads(request.body) except ValueError: return HttpResponseBadRequest('Invalid JSON: %s' % request.body) # We ignore everything except 'in_air' if 'in_air' in data: in_air = data['in_air'] if in_air is not True and in_air is not False: return HttpResponseBadRequest('in_air must be boolean') currently_in_air = TakeoffOrLandingEvent.user_in_air(user) # New event only necessary if changing status if currently_in_air != in_air: event = TakeoffOrLandingEvent(user=user, uas_in_air=in_air) event.save() return HttpResponse(json.dumps(user_json(user)), content_type="application/json")
def create_data(self): """Create a basic sample dataset.""" self.user1 = User.objects.create_user('user1', '*****@*****.**', 'testpass') self.user1.save() self.user2 = User.objects.create_user('user2', '*****@*****.**', 'testpass') self.user2.save() # user1 is flying event = TakeoffOrLandingEvent(user=self.user1, uas_in_air=True) event.save() # user2 has landed event = TakeoffOrLandingEvent(user=self.user2, uas_in_air=True) event.save() event = TakeoffOrLandingEvent(user=self.user2, uas_in_air=False) event.save() # user2 is active self.timestamp = timezone.now() gps = GpsPosition(latitude=38.6462, longitude=-76.2452) gps.save() pos = AerialPosition(gps_position=gps, altitude_msl=0) pos.save() telem = UasTelemetry(user=self.user2, uas_position=pos, uas_heading=90) telem.save() telem.timestamp = self.timestamp telem.save()
def put(self, request, pk): """PUT allows updating status.""" try: user = User.objects.get(pk=int(pk)) except User.DoesNotExist: return HttpResponseBadRequest('Unknown team %s' % pk) try: data = json.loads(request.body) except ValueError: return HttpResponseBadRequest('Invalid JSON: %s' % request.body) # Potential events to update. takeoff_event = None clock_event = None # Update whether UAS is in air. if 'in_air' in data: in_air = data['in_air'] if not isinstance(in_air, bool): return HttpResponseBadRequest('in_air must be boolean') currently_in_air = TakeoffOrLandingEvent.user_in_air(user) # New event only necessary if changing status if currently_in_air != in_air: takeoff_event = TakeoffOrLandingEvent(user=user, uas_in_air=in_air) # Update whether UAS in on clock or timeout. if 'on_clock' in data or 'on_timeout' in data: currently_on_clock = MissionClockEvent.user_on_clock(user) currently_on_timeout = MissionClockEvent.user_on_timeout(user) on_clock = data.get('on_clock', currently_on_clock) on_timeout = data.get('on_timeout', currently_on_timeout) if (not isinstance(on_clock, bool) or not isinstance(on_timeout, bool)): return HttpResponseBadRequest( 'on_clock and on_timeout must be boolean.') if on_clock and on_timeout: return HttpResponseBadRequest( 'Cannot be on mission clock and on timeout.') # New event only necessary if changing status if (on_clock != currently_on_clock or on_timeout != currently_on_timeout): clock_event = MissionClockEvent(user=user, team_on_clock=on_clock, team_on_timeout=on_timeout) # Request was valid. Save updates. if takeoff_event: takeoff_event.save() if clock_event: clock_event.save() return HttpResponse( json.dumps(user_json(user)), content_type="application/json")
def put(self, request, pk): """PUT allows updating status.""" try: user = User.objects.get(pk=int(pk)) except User.DoesNotExist: return HttpResponseBadRequest('Unknown team %s' % pk) try: data = json.loads(request.body) except ValueError: return HttpResponseBadRequest('Invalid JSON: %s' % request.body) # Potential events to update. takeoff_event = None clock_event = None # Update whether UAS is in air. if 'in_air' in data: in_air = data['in_air'] if not isinstance(in_air, bool): return HttpResponseBadRequest('in_air must be boolean') currently_in_air = TakeoffOrLandingEvent.user_in_air(user) # New event only necessary if changing status if currently_in_air != in_air: takeoff_event = TakeoffOrLandingEvent(user=user, uas_in_air=in_air) # Update whether UAS in on clock or timeout. if 'on_clock' in data or 'on_timeout' in data: currently_on_clock = MissionClockEvent.user_on_clock(user) currently_on_timeout = MissionClockEvent.user_on_timeout(user) on_clock = data.get('on_clock', currently_on_clock) on_timeout = data.get('on_timeout', currently_on_timeout) if (not isinstance(on_clock, bool) or not isinstance(on_timeout, bool)): return HttpResponseBadRequest( 'on_clock and on_timeout must be boolean.') if on_clock and on_timeout: return HttpResponseBadRequest( 'Cannot be on mission clock and on timeout.') # New event only necessary if changing status if (on_clock != currently_on_clock or on_timeout != currently_on_timeout): clock_event = MissionClockEvent(user=user, team_on_clock=on_clock, team_on_timeout=on_timeout) # Request was valid. Save updates. if takeoff_event: takeoff_event.save() if clock_event: clock_event.save() return HttpResponse(json.dumps(user_json(user)), content_type="application/json")
def test_kml_simple(self): coordinates = [ (-76.0, 38.0, 0.0), (-76.0, 38.0, 10.0), (-76.0, 38.0, 20.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 100.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 60.0), ] # Create Coordinates start = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) start.save() for coord in coordinates: self.create_log_element(*coord) end = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) end.save() kml = Kml() UasTelemetry.kml(user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml) for coord in coordinates: tag = self.coord_format.format(coord[1], coord[0], units.feet_to_meters(coord[2])) self.assertTrue(tag in kml.kml())
def user_json(user): """Generate JSON-style dict for user.""" return { 'name': user.username, 'id': user.pk, 'in_air': TakeoffOrLandingEvent.user_in_air(user), 'active': UasTelemetry.user_active(user), }
def test_user_in_air_second_flight(self): """In-air during second flight.""" self.create_event(self.year2000, True) self.create_event(self.year2000 + self.ten_minutes, False) self.create_event(self.year2001, True) self.assertTrue(TakeoffOrLandingEvent.user_in_air(self.user1))
def create_event(self, time, uas_in_air): """Create a TakeoffOrLandingEvent for test user.""" event = TakeoffOrLandingEvent(user=self.user1, uas_in_air=uas_in_air) event.save() event.timestamp = time event.save() return event
def test_user_in_air_time(self): """In-air base time check.""" self.create_event(self.year2000, True) self.create_event(self.year2000 + 2 * self.ten_minutes, False) time = self.year2000 + self.ten_minutes self.assertTrue(TakeoffOrLandingEvent.user_in_air(self.user1, time=time))
def test_user_in_air_time(self): """In-air base time check.""" self.create_event(self.year2000, True) self.create_event(self.year2000 + 2 * self.ten_minutes, False) time = self.year2000 + self.ten_minutes self.assertTrue( TakeoffOrLandingEvent.user_in_air(self.user1, time=time))
def user_json(user): """Generate JSON-style dict for user.""" return { 'name': user.username, 'id': user.pk, 'on_clock': MissionClockEvent.user_on_clock(user), 'on_timeout': MissionClockEvent.user_on_timeout(user), 'in_air': TakeoffOrLandingEvent.user_in_air(user), 'active': UasTelemetry.user_active(user), }
def test_kml_filter(self): coordinates = [ (-76.0, 38.0, 0.0), (-76.0, 38.0, 10.0), (-76.0, 38.0, 20.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 100.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 60.0), ] filtered_out = [(0.1, 0.001, 100), (0.0, 0.0, 0)] # Create Coordinates start = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) start.save() for coord in coordinates: self.create_log_element(*coord) for coord in filtered_out: self.create_log_element(*coord) end = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) end.save() kml = Kml() UasTelemetry.kml(user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml) for filtered in filtered_out: tag = self.coord_format.format(filtered[1], filtered[0], filtered[2]) self.assertTrue(tag not in kml.kml()) for coord in coordinates: tag = self.coord_format.format(coord[1], coord[0], coord[2]) self.assertTrue(tag in kml.kml())
def test_actionable_submission(self): """Tests actionable_submission correctly filters submissions.""" # t1 created and updated before take off. t1 = Target(user=self.user, target_type=TargetType.standard) t1.save() t1.alphanumeric = 'A' t1.save() # t2 created before take off and updated in flight. t2 = Target(user=self.user, target_type=TargetType.standard) t2.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) event.save() t2.alphanumeric = 'A' t2.save() # t3 created and updated in flight. t3 = Target(user=self.user, target_type=TargetType.standard) t3.save() t3.alphanumeric = 'A' t3.save() # t4 created in flight and updated after landing. t4 = Target(user=self.user, target_type=TargetType.standard) t4.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) event.save() t4.alphanumeric = 'A' t4.save() # t5 created and updated after landing. t5 = Target(user=self.user, target_type=TargetType.standard) t5.save() t5.alphanumeric = 'A' t5.save() self.assertFalse(t1.actionable_submission()) self.assertFalse(t2.actionable_submission()) self.assertTrue(t3.actionable_submission()) self.assertFalse(t4.actionable_submission()) self.assertFalse(t5.actionable_submission())
def test_actionable_submission(self): """Tests actionable_submission correctly filters submissions.""" # t1 created and updated before take off. t1 = Target(user=self.user, target_type=TargetType.standard) t1.save() t1.alphanumeric = "A" t1.save() # t2 created before take off and updated in flight. t2 = Target(user=self.user, target_type=TargetType.standard) t2.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) event.save() t2.alphanumeric = "A" t2.save() # t3 created and updated in flight. t3 = Target(user=self.user, target_type=TargetType.standard) t3.save() t3.alphanumeric = "A" t3.save() # t4 created in flight and updated after landing. t4 = Target(user=self.user, target_type=TargetType.standard) t4.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) event.save() t4.alphanumeric = "A" t4.save() # t5 created and updated after landing. t5 = Target(user=self.user, target_type=TargetType.standard) t5.save() t5.alphanumeric = "A" t5.save() self.assertFalse(t1.actionable_submission()) self.assertFalse(t2.actionable_submission()) self.assertTrue(t3.actionable_submission()) self.assertFalse(t4.actionable_submission()) self.assertFalse(t5.actionable_submission())
def evaluate_periods(self, expected): """Check actual periods against expected.""" periods = TakeoffOrLandingEvent.flights(self.user1) self.assertSequenceEqual(expected, periods)
def test_user_in_air_after_landing(self): """Not in-air after landing.""" self.create_event(self.year2000, True) self.create_event(self.year2000 + self.ten_minutes, False) self.assertFalse(TakeoffOrLandingEvent.user_in_air(self.user1))
def test_user_in_air_before_landing(self): """In-air before landing.""" self.create_event(self.year2000, True) self.assertTrue(TakeoffOrLandingEvent.user_in_air(self.user1))
def test_unicode(self): """Tests the unicode method executes.""" log = TakeoffOrLandingEvent(user=self.user1, uas_in_air=True) log.save() self.assertIsNotNone(log.__unicode__())
def setUp(self): """Setup the test case.""" super(TestTargetEvaluator, self).setUp() self.user = User.objects.create_user('user', '*****@*****.**', 'pass') l1 = GpsPosition(latitude=38, longitude=-76) l1.save() l2 = GpsPosition(latitude=38.0003, longitude=-76) l2.save() l3 = GpsPosition(latitude=-38, longitude=76) l3.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) event.save() # A target worth full points. self.submit1 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.s, shape=Shape.square, background_color=Color.white, alphanumeric='ABC', alphanumeric_color=Color.black, description='Test target 1', autonomous=False, thumbnail_approved=True) self.submit1.save() self.real1 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.s, shape=Shape.square, background_color=Color.white, alphanumeric='ABC', alphanumeric_color=Color.black, description='Test target 1') self.real1.save() # A target worth less than full points. self.submit2 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.circle, background_color=Color.white, # alphanumeric set below alphanumeric_color=Color.black, description='Test target 2', autonomous=False, thumbnail_approved=True) self.submit2.save() self.real2 = Target(user=self.user, target_type=TargetType.standard, location=l2, orientation=Orientation.s, shape=Shape.triangle, background_color=Color.white, alphanumeric='ABC', alphanumeric_color=Color.black, description='Test target 2') self.real2.save() # A target worth no common traits, so unmatched. self.submit3 = Target(user=self.user, target_type=TargetType.qrc, location=l1, description='Incorrect description', autonomous=False, thumbnail_approved=True) self.submit3.save() self.real3 = Target(user=self.user, target_type=TargetType.qrc, location=l3, description='Test target 3') self.real3.save() # Unapproved image worth no points, so unmatched. self.submit4 = Target(user=self.user, target_type=TargetType.qrc, location=l1, description='Test target 4', autonomous=False, thumbnail_approved=False) self.submit4.save() self.real4 = Target(user=self.user, target_type=TargetType.qrc, location=l1, description='Test target 4') self.real4.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) event.save() # submit2 updated after landing. self.submit2.alphanumeric = 'ABC' self.submit2.save() self.submitted_targets = [self.submit1, self.submit2, self.submit3, self.submit4] self.real_targets = [self.real3, self.real1, self.real4, self.real2] self.real_matched_targets = [self.real1, self.real2]
def setUp(self): """Setup the test case.""" super(TestTargetEvaluator, self).setUp() self.user = User.objects.create_user("user", "*****@*****.**", "pass") l1 = GpsPosition(latitude=38, longitude=-76) l1.save() l2 = GpsPosition(latitude=38.0003, longitude=-76) l2.save() l3 = GpsPosition(latitude=-38, longitude=76) l3.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) event.save() # A target worth full points. self.submit1 = Target( user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.s, shape=Shape.square, background_color=Color.white, alphanumeric="ABC", alphanumeric_color=Color.black, description="Test target 1", autonomous=False, thumbnail_approved=True, ) self.submit1.save() self.real1 = Target( user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.s, shape=Shape.square, background_color=Color.white, alphanumeric="ABC", alphanumeric_color=Color.black, description="Test target 1", ) self.real1.save() # A target worth less than full points. self.submit2 = Target( user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.circle, background_color=Color.white, # alphanumeric set below alphanumeric_color=Color.black, description="Test target 2", autonomous=False, thumbnail_approved=True, ) self.submit2.save() self.real2 = Target( user=self.user, target_type=TargetType.standard, location=l2, orientation=Orientation.s, shape=Shape.triangle, background_color=Color.white, alphanumeric="ABC", alphanumeric_color=Color.black, description="Test target 2", ) self.real2.save() # A target worth no common traits, so unmatched. self.submit3 = Target( user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.circle, background_color=Color.blue, alphanumeric="XYZ", description="Incorrect description", autonomous=False, thumbnail_approved=True, ) self.submit3.save() self.real3 = Target( user=self.user, target_type=TargetType.standard, orientation=Orientation.e, shape=Shape.semicircle, background_color=Color.yellow, alphanumeric="LMN", location=l3, description="Test target 3", ) self.real3.save() # Targets without approved image may still match. self.submit4 = Target( user=self.user, target_type=TargetType.qrc, location=l1, description="Test target 4", autonomous=False, thumbnail_approved=False, ) self.submit4.save() self.real4 = Target(user=self.user, target_type=TargetType.qrc, location=l1, description="Test target 4") self.real4.save() # A target without location worth fewer points. self.submit5 = Target( user=self.user, target_type=TargetType.standard, orientation=Orientation.n, shape=Shape.trapezoid, background_color=Color.purple, alphanumeric="PQR", alphanumeric_color=Color.blue, description="Test target 5", autonomous=False, thumbnail_approved=True, ) self.submit5.save() self.real5 = Target( user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.trapezoid, background_color=Color.purple, alphanumeric="PQR", alphanumeric_color=Color.blue, description="Test target 5", ) self.real5.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) event.save() # submit2 updated after landing. self.submit2.alphanumeric = "ABC" self.submit2.save() self.submitted_targets = [self.submit1, self.submit2, self.submit3, self.submit4, self.submit5] self.real_targets = [self.real1, self.real2, self.real3, self.real4, self.real5] self.real_matched_targets = [self.real1, self.real2, self.real4, self.real5]
def test_user_in_air_no_logs(self): """Not in-air without logs.""" self.assertFalse(TakeoffOrLandingEvent.user_in_air(self.user1))
def setUp(self): """Setup the test case.""" super(TestTargetEvaluator, self).setUp() self.user = User.objects.create_user('user', '*****@*****.**', 'pass') l1 = GpsPosition(latitude=38, longitude=-76) l1.save() l2 = GpsPosition(latitude=38.0003, longitude=-76) l2.save() l3 = GpsPosition(latitude=-38, longitude=76) l3.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) event.save() # A target worth full points. self.submit1 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.s, shape=Shape.square, background_color=Color.white, alphanumeric='ABC', alphanumeric_color=Color.black, description='Test target 1', autonomous=False, thumbnail_approved=True) self.submit1.save() self.real1 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.s, shape=Shape.square, background_color=Color.white, alphanumeric='ABC', alphanumeric_color=Color.black, description='Test target 1') self.real1.save() # A target worth less than full points. self.submit2 = Target( user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.circle, background_color=Color.white, # alphanumeric set below alphanumeric_color=Color.black, description='Test target 2', autonomous=False, thumbnail_approved=True) self.submit2.save() self.real2 = Target(user=self.user, target_type=TargetType.standard, location=l2, orientation=Orientation.s, shape=Shape.triangle, background_color=Color.white, alphanumeric='ABC', alphanumeric_color=Color.black, description='Test target 2') self.real2.save() # A target worth no common traits, so unmatched. self.submit3 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.circle, background_color=Color.blue, alphanumeric='XYZ', description='Incorrect description', autonomous=False, thumbnail_approved=True) self.submit3.save() self.real3 = Target(user=self.user, target_type=TargetType.standard, orientation=Orientation.e, shape=Shape.semicircle, background_color=Color.yellow, alphanumeric='LMN', location=l3, description='Test target 3') self.real3.save() # Targets without approved image may still match. self.submit4 = Target(user=self.user, target_type=TargetType.qrc, location=l1, description='Test target 4', autonomous=False, thumbnail_approved=False) self.submit4.save() self.real4 = Target(user=self.user, target_type=TargetType.qrc, location=l1, description='Test target 4') self.real4.save() # A target without location worth fewer points. self.submit5 = Target(user=self.user, target_type=TargetType.standard, orientation=Orientation.n, shape=Shape.trapezoid, background_color=Color.purple, alphanumeric='PQR', alphanumeric_color=Color.blue, description='Test target 5', autonomous=False, thumbnail_approved=True) self.submit5.save() self.real5 = Target(user=self.user, target_type=TargetType.standard, location=l1, orientation=Orientation.n, shape=Shape.trapezoid, background_color=Color.purple, alphanumeric='PQR', alphanumeric_color=Color.blue, description='Test target 5') self.real5.save() event = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) event.save() # submit2 updated after landing. self.submit2.alphanumeric = 'ABC' self.submit2.save() self.submitted_targets = [ self.submit1, self.submit2, self.submit3, self.submit4, self.submit5 ] self.real_targets = [ self.real1, self.real2, self.real3, self.real4, self.real5 ] self.real_matched_targets = [ self.real1, self.real2, self.real4, self.real5 ]