def user_login(request): error = '' if request.method == 'POST': json_data = json.loads(request.POST['json_data']) user = login(request, json_data['username'], json_data['password']) if isinstance(user, PortcullisUser): greeting_page = loader.get_template('greeting.html') greeting_c = RequestContext(request, {}) nav_t = loader.get_template('nav_bar.html') nav_c = RequestContext(request, {}) data = { 'greeting': greeting_page.render(greeting_c), 'nav': nav_t.render(nav_c) } return cors_http_response_json(data) else: return cors_http_response_json({'error': user}) return cors_http_response_json({'error': error})
def render_graph(request): ''' Takes a single datastream id and a time frame and generates json for the data. ''' jsonData = request.REQUEST.get('json_data', None) if jsonData is None: return cors_http_response_json({'error': "Unrecognized data."}) return cors_http_response_json(get_stream_data(json.loads(jsonData), request.user))
def get_data_by_ds_column(request): ''' ' This view will take a column name/value and a time range (in epoch secs), ' and return a json response containing all the matching sensor data points. ' ' returns - HttpResponse containing jsondata {'echo of query', 'streams': [[<ds_id>, <value>, <timestamp>]] } ''' # TODO: Check perms, etc. import time beg_time = time.time() jsonData = request.REQUEST.get('jsonData', None) if jsonData is None: return cors_http_response_json({'errors': 'Error: No jsonData received.'}) try: jsonData = json.loads(jsonData) except Exception as e: return cors_http_response_json({'errors': 'Error: Invalid JSON: ' + str(e)}) try: column = jsonData['column'] value = jsonData['value'] time_start = jsonData['start'] time_end = jsonData['end'] except KeyError as e: return cors_http_response_json({'errors': 'Error: KeyError: ' + str(e)}) # Scrub column, so it is safe to use in query ds_columns = [x.get_attname_column()[1] for x in DataStream._meta.fields] if column not in ds_columns: return cors_http_response_json({'errors': 'Error: Column Name %s not in DataStream table.' % column}) kwargs = { 'timestamp__gte': time_start, 'timestamp__lte': time_end, 'datastream__'+column+'__contains': value } data_points = list(SensorReading.objects.select_related().filter(**kwargs).values_list('datastream', 'value', 'timestamp')) elapsed_time = time.time() - beg_time print 'Took: %f seconds before JSON' % elapsed_time # Echo back query, and send data data = { 'column': column, 'value': value, 'start': time_start, 'end': time_end, 'streams': data_points, 'time': elapsed_time } resp = HttpResponse(json.dumps(data, cls=DecimalEncoder), mimetype='application/json') resp['Access-Control-Allow-Origin'] = '*' return resp
def post(self, request): ''' ' Accepts a list of sensors and their data as json and will make sure they are claimed. ' User credentials are necessary to claiming unclaimed sensors unless the sensor is already claimed ' in which case the sensor will simply update itself. ' ' Owner must provide their email and password for authentication to create and claim sensor. ''' returnData = { 'errors': [] ,'sensors': [] } try: jsonData = json.loads(request.body) except KeyError: returnData['errors'].append('No json sent') return cors_http_response_json(returnData, 404) except (TypeError, ValueError): returnData['errors'].append('Bad Json') return cors_http_response_json(returnData, 404) sensors = jsonData.get('sensors', []) if len(sensors) == 0: returnData['errors'].append('There was no sensor data sent') return cors_http_response_json(returnData, 404) user = None try: email = jsonData['email'] user = User.objects.get(email=email) except KeyError: pass except User.DoesNotExist: returnData['errors'].append('User with email %s does not exist' % str(email)) return cors_http_response_json(returnData, 404) for s in sensors: sensor = claimSensor(s, user) #Assume error string if not a sensor if not isinstance(sensor, Sensor): if isinstance(sensor, list): returnData['errors'].extend(sensor) else: returnData['errors'].append(sensor) else: returnData['sensors'].append(sensor.toDict()) return cors_http_response_json(returnData)
def password_form(request): ''' ' This view will render the change password request form. ''' portcullisUser = check_access(request) if isinstance(portcullisUser, HttpResponse): return cors_http_response_json({'errors': portcullisUser.content}) if not isinstance(portcullisUser, AuthUser): return cors_http_response_json({'errors': 'User must be logged in to change password.'}) t = loader.get_template('passwordForm.html') c = RequestContext(request, {'user': portcullisUser}) return cors_http_response_json({'html': t.render(c)})
def shared_graph(request, token, id): ''' This function will use a key to send the jsonData for a shared graph. ''' try: # Get the key from the token key = Key.objects.get(key = token) # Get the graph from the id. graph = SavedDSGraph.objects.get(id = id) except ObjectDoesNotExist: return cors_http_response_json({'error': 'Graph %s/%s/ does not exist' % (token, str(id))}) params = { 'start': graph.start, 'end': graph.end, 'reduction': graph.reduction_type, 'granularity': graph.granularity, 'datastream_id': graph.datastream.id, 'zoom_start': graph.zoom_start, 'zoom_end': graph.zoom_end } return cors_http_response_json(get_stream_data(params, key, request.user))
def change_password(request): ''' ' This view will allow a user to change their password. ' ' POST arguments: ' jsonData - JSON data containing: ' oldPassword - string containing user's current password. ' newPassword - string containing password to change to. ''' portcullisUser = check_access(request) if isinstance(portcullisUser, HttpResponse): return cors_http_response_json({'errors': portcullisUser.content}) if not isinstance(portcullisUser, AuthUser): return cors_http_response_json({'errors': 'Please log in before changing your password.'}) jsonData = request.REQUEST.get('jsonData', None) try: jsonData = json.loads(jsonData) except Exception as e: return cors_http_response_json({'errors': 'JSON Exception: %s: %s' % (type(e), e.message)}) try: oldPassword = jsonData['oldPassword'] newPassword = jsonData['newPassword'] except KeyError as e: return cors_http_response_json({'errors': 'KeyError: %s' % e.message}) # Make sure old password is valid user = authenticate(username=portcullisUser.get_username(), password=oldPassword) if user is None or user != portcullisUser: return cors_http_response_json({'errors': 'Authentication Error: Username and password are not correct'}) elif not user.is_active: error = 'Authentication Error: User is not active. You must be active to change password.' return cors_http_response_json({'errors': error}) # Change the password portcullisUser.set_password(newPassword) portcullisUser.save() return cors_http_response_json({'success': 'Password successfully changed!'})
def create_datastreams(request): ''' ' Creates DataStreams with an array of data from json and with the owner of the specified token. ' ' The json required format is the following: TBD ' ' Returns: HttpResponse with Json containing a list with the new DataStream's ids and a dictionary of errors ''' timingMark = time.time() #TODO: for now screw permissions, but later, put them in!! errors = [] try: json_data = json.loads(request.POST.get("jsonData")) except Exception as e: #transaction.rollback() errors.append({ 'error': "Missing jsonData from request.", 'exception': str(e) }) return cors_http_response_json(errors) if 'key' in json_data: try: key = Key.objects.get(key=json_data['key']) except Key.DoesNotExist as e: #transaction.rollback() errors.append({'error': 'Key not in Database: ' + str(json_data['key']), 'exception': str(e)}) return cors_http_response_json(errors) else: #transaction.rollback() errors.append({'error': 'No Key received.', 'exception': None}) return cors_http_response_json(errors) owner = key.owner if 'datastreams' not in json_data: #transaction.rollback() errors.append({ 'error': 'No datastream data received', 'exception': None }) return cors_http_response_json(errors) if not isinstance(json_data['datastreams'], list): #transaction.rollback() errors.append({'error': 'Datastream object not a list.', 'exception': None}) return cors_http_response_json(errors) return_ids = {} for data in json_data['datastreams']: try: ds_name = data['name'] except Exception as e: error = "Exception getting DataStream name %s." % type(e) errors.append({"error": error, "exception": str(e)}) continue try: ds = create_ds(owner, data) #If not a ds then an error if not isinstance(ds, DataStream): errors.append(ds) continue except (IntegrityError, ValidationError) as e: try: ds = DataStream.objects.get(name=ds_name, owner=owner) except DataStream.DoesNotExist: error = 'Unexpected error getting datastream! Datastream does not exist, but could not create.' errors.append({'error': error, 'exception': str(e)}) continue return_ids[ds_name] = ds.pk ds.can_read.add(key) ds.can_post.add(key) #transaction.commit() elapsedTime = time.time() - timingMark return cors_http_response_json({'ids': return_ids, "errors": errors, "time": elapsedTime})
def add_readings(readings, streamId=None): """ ' Adds multiple readings to the database from a list of lists in the form of ' [[sensor_uuid, value1, time1], [sensor_uuid, value2, time2]...] with time being optional. ' ' Keyword Args: ' readings - List of lists containing sensor uuid, sensor reading, and timestamp values. ' stream - Optional. Id of Datastream to specifically look for to post sensor value to. ' If stream is found sensor uuid's must match sensor claimed by stream. ' ' Returns: HttpResponse with json encoded Dict object with the following data: ' { ' "insertions_attempted": <number of readings attemtped to be inserted> ' "insertions_succeeded": <number of successfull readings inserted> ' "insertions_failed": <number of failed reading insertions> ' "errors": <List of errors strings. If applicable> ' } """ returnData = {"insertions_attempted": 0, "insertions_succeeded": 0, "insertions_failed": 0, "errors": []} if not isinstance(readings, list): returnData["errors"].append("Did not recieve a list of sensor readings") return cors_http_response_json(returnData) ds = None if streamId is not None: try: ds = DataStream.objects.get(id=streamId) except DataStream.DoesNotExist: returnData["errors"].append("Datastream with id '%s' does not exist." % str(streamId)) return cors_http_response_json(returnData) # Grab all reading from the json for reading in readings: if streamId is None: ds = None uuid = None raw_sensor_value = None timestamp = None returnData["insertions_attempted"] += 1 try: uuid = reading[0] raw_sensor_value = reading[1] timestamp = reading[2] except: pass # If no sensor value then skip this reading if raw_sensor_value is None or raw_sensor_value == "": returnData["errors"].append("Missing data to insert! Please be sure to give data to insert.") continue # If a stream was provided make sure it's sensor matches the current uuid if ds is not None and (ds.sensor is None or ds.sensor.uuid != uuid): error = "Sensor with uuid '%s' is not claimed by Datastream with id '%s'" % (str(uuid), str(streamId)) returnData["errors"].append(error) continue # Attempt to get a stream if one wasn't provided if ds is None: try: ds = DataStream.objects.get(sensor__uuid=uuid) except DataStream.DoesNotExist: returnData["errors"].append("No Datastream that has claimed Sensor with uuid '%s'" % str(uuid)) return cors_http_response_json(returnData, 400) continue try: insert_reading(ds, ds.sensor, raw_sensor_value, timestamp) returnData["insertions_succeeded"] += 1 except SensorReadingCollision as e: returnData["errors"].append(str(e)) returnData["insertions_failed"] = returnData["insertions_attempted"] - returnData["insertions_succeeded"] return cors_http_response_json(returnData)