Exemple #1
0
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})
Exemple #2
0
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))
Exemple #3
0
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
Exemple #4
0
    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)
Exemple #5
0
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)})
Exemple #6
0
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))
Exemple #7
0
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!'})
Exemple #8
0
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)