Beispiel #1
0
def upload_transaction_csv():
    """
    batch upload the transaction by a csv file
    """

    if request.method == "POST":
        # parse the csv file
        f = request.files['csv']
        df = pd.read_csv(f)
        # connect the database
        session = get_database_client()
        # update the db
        for i in range(df.shape[0]):
            # Check if category is nan
            if df.category[i] != df.category[i]:
                category = ""
            else:
                category = df.category[i]
            try:
                session.execute(
                    """
                    INSERT INTO fisci.transactions 
                    (transaction_id, user_id, shop_name, category, labeled, amount, date)
                    VALUES (now(), %s, %s, %s, %s, %s, %s)
                    """,
                    (df.user_id[i], df.shop_name[i], category,
                     bool(df.labeled[i]), float(df.amount[i]), df.date[i]))
            except Exception as err:
                error_response(500, "Error parsing csv. " + str(err))
        return {"message": "success"}
    else:
        return {"message": "Nothing happened. Please POST the csv file"}
Beispiel #2
0
def add_transaction():
    """User send transaction details to be uploaded to the database
    Data is received in json format"""

    # parse the request
    data = request.get_json() or {}
    # check required fields
    required_fields = ["user_id", "shop_name", "category", "amount", "date"]
    for f in required_fields:
        if f not in data:
            return bad_request("Required field " + f + " is missing")
    # add labeled field
    data["labeled"] = len(
        data["category"]) == 0  # user provided the category or not
    # connect to db
    session = get_database_client()
    # update db
    try:
        session.execute(
            """
        INSERT INTO fisci.transactions (transaction_id, user_id, shop_name, category, labeled, amount, date)
        VALUES (now(), %s, %s, %s, %s, %s, %s);
        """, (data["user_id"], data["shop_name"], data["category"],
              data["labeled"], float(data["amount"]), data["date"]))
    except Exception as err:
        return error_response(500,
                              "Error in updating the database. " + str(err))

    return {"message": "success"}
Beispiel #3
0
def get_new_firmware():
    ver = request.args.get("ver", default=None)
    if ver is None or not ver.isdigit():
        return bad_request(
            "Required parameter 'ver' is missing or not an int.")

    dev_type = request.args.get("dev_type", default=None)
    if dev_type is None:
        return bad_request("Required parameter 'dev_type' is missing.")
    dev_type = dev_type.lower()

    dev_id = request.args.get("dev_id", default=None)
    if dev_id is None:
        return bad_request("Required parameter 'dev_id' is missing.")

    app.logger.debug("ver: " + ver + ", dev: " + dev_type + " dev_id: " +
                     dev_id)

    latest_firmware = find_latest_firmware(ver, dev_type)
    if latest_firmware is None:
        app.logger.debug("Device already up to date")
        return error_response(304, "Device already up to date")

    app.logger.debug("Found firmware version: " + latest_firmware)
    return send_from_directory(
        directory=os.path.join(ROOT_DIR, "firmwares"),
        filename=latest_firmware,
        as_attachment=True,
        mimetype="application/octet-stream",
        attachment_filename=latest_firmware,
    )
Beispiel #4
0
def texts_get(text_no):
    """Get a text.
    
    Note: The body will only be included in the response if the content type is text.
    
    .. rubric:: Request
    
    ::
    
      GET /texts/19680717 HTTP/1.0
    
    .. rubric:: Responses
    
    Text exists::
    
      HTTP/1.0 200 OK
      
      {
        "body": "r\u00e4ksm\u00f6rg\u00e5s",
        "recipient_list": [
          {
            "conf_name": "Oskars Testperson",
            "type": "to",
            "loc_no": 29,
            "conf_no": 14506
          }
        ], 
        "author": {
          "pers_no": 14506,
          "pers_name": "Oskars Testperson"
        }, 
        "creation_time": "2012-05-08 18:36:17",
        "comment_in_list": [],
        "content_type": "text/x-kom-basic",
        "text_no": 19680717,
        "comment_to_list": [],
        "subject": "jaha"
      }
    
    Text does not exist::
    
      HTTP/1.0 404 NOT FOUND
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET -H "Content-Type: application/json" \\
           http://localhost:5001/texts/19680717
    
    """
    try:
        return jsonify(to_dict(g.ksession.get_text(text_no), True, g.ksession))
    except kom.NoSuchText as ex:
        return error_response(404, kom_error=ex)
Beispiel #5
0
def texts_get(text_no):
    """Get a text.
    
    Note: The body will only be included in the response if the content type is text.
    
    .. rubric:: Request
    
    ::
    
      GET /texts/19680717 HTTP/1.0
    
    .. rubric:: Responses
    
    Text exists::
    
      HTTP/1.0 200 OK
      
      {
        "body": "r\u00e4ksm\u00f6rg\u00e5s",
        "recipient_list": [
          {
            "conf_name": "Oskars Testperson",
            "type": "to",
            "loc_no": 29,
            "conf_no": 14506
          }
        ], 
        "author": {
          "pers_no": 14506,
          "pers_name": "Oskars Testperson"
        }, 
        "creation_time": "2012-05-08 18:36:17",
        "comment_in_list": [],
        "content_type": "text/x-kom-basic",
        "text_no": 19680717,
        "comment_to_list": [],
        "subject": "jaha"
      }
    
    Text does not exist::
    
      HTTP/1.0 404 NOT FOUND
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET -H "Content-Type: application/json" \\
           http://localhost:5001/texts/19680717
    
    """
    try:
        return jsonify(to_dict(g.ksession.get_text(text_no), True, g.ksession))
    except kom.NoSuchText as ex:
        return error_response(404, kom_error=ex)
Beispiel #6
0
def texts_get_body(text_no):
    """Get the body of text, with the content type of the body set in the HTTP header.
    Useful for creating img-tags in HTML and specifying this URL as source.
    
    If the content type is text, the text will be recoded to UTF-8. For other types,
    the content type will be left untouched.
    
    .. rubric:: Request
    
    ::
    
      GET /texts/19680717/body HTTP/1.0
    
    .. rubric:: Responses
    
    Text exists::
    
      HTTP/1.0 200 OK
      Content-Type: text/x-kom-basic; charset=utf-8
      
      räksmörgås
    
    Text does not exist::
    
      HTTP/1.0 404 NOT FOUND
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET -H "Content-Type: application/json" \\
           http://localhost:5001/texts/19680717/body
    
    """
    try:
        text = g.ksession.get_text(text_no)
        mime_type, encoding = parse_content_type(text.content_type)
        
        data = StringIO.StringIO()
        if mime_type[0] == 'text':
            data.write(text.body.encode('utf-8'))
        else:
            data.write(text.body)
        data.flush()
        data.seek(0)
        response = send_file(data,
                             mimetype=text.content_type,
                             as_attachment=False)
            
        return response
    except kom.NoSuchText as ex:
        return error_response(404, kom_error=ex)
Beispiel #7
0
def texts_get_body(text_no):
    """Get the body of text, with the content type of the body set in the HTTP header.
    Useful for creating img-tags in HTML and specifying this URL as source.
    
    If the content type is text, the text will be recoded to UTF-8. For other types,
    the content type will be left untouched.
    
    .. rubric:: Request
    
    ::
    
      GET /texts/19680717/body HTTP/1.0
    
    .. rubric:: Responses
    
    Text exists::
    
      HTTP/1.0 200 OK
      Content-Type: text/x-kom-basic; charset=utf-8
      
      räksmörgås
    
    Text does not exist::
    
      HTTP/1.0 404 NOT FOUND
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET -H "Content-Type: application/json" \\
           http://localhost:5001/texts/19680717/body
    
    """
    try:
        text = g.ksession.get_text(text_no)
        mime_type, encoding = parse_content_type(text.content_type)

        data = StringIO.StringIO()
        if mime_type[0] == 'text':
            data.write(text.body.encode('utf-8'))
        else:
            data.write(text.body)
        data.flush()
        data.seek(0)
        response = send_file(data,
                             mimetype=text.content_type,
                             as_attachment=False)

        return response
    except kom.NoSuchText as ex:
        return error_response(404, kom_error=ex)
Beispiel #8
0
def remove_transaction(transaction_id):
    """Remove transaction based on transaction_id"""

    try:
        session = get_database_client()
        session.execute(
            "DELETE FROM fisci.transactions WHERE transaction_id=%s;",
            (transaction_id, ))

    except Exception as err:
        return error_response(500,
                              "Error in deleting the transaction. " + str(err))

    return {"message": "success"}
Beispiel #9
0
def stats_by_time(user_id):
    """
    Fetch all transactions and sum by time
    """

    # connect the database
    session = get_database_client()
    # fetch user data
    df = fetch_by_user(user_id, session)
    if type(df) != pd.DataFrame:
        return error_response(500, "Error fetching transactions. " + df)
    # sum over time
    result = df.groupby("date").sum()["amount"]
    result_list = [{
        "date": key,
        "spending": val
    } for key, val in dict(result).items()]
    return {"data": result_list}
Beispiel #10
0
def stats_by_category(user_id):
    """
    Fetch all the transactions categorized
    """

    # connect the database
    session = get_database_client()
    # fetch user-related transactions
    df = fetch_by_user(user_id, session)
    if type(df) != pd.DataFrame:
        return error_response(500, "Error fetching transactions. " + df)
    # sum by category
    result = df.groupby("category").sum()["amount"]
    result_list = [{
        "category": key,
        "spending": val
    } for key, val in dict(result).items()]
    return {"data": result_list}
Beispiel #11
0
def conferences_get(conf_no):
    """Get information about a specific conference.
    
    =======  =======  =================================================================
    Key      Type     Values
    =======  =======  =================================================================
    micro    boolean  :true: (Default) Return micro conference information (`UConference <http://www.lysator.liu.se/lyskom/protocol/11.1/protocol-a.html#Conferences>`_) which causes less load on the server.
                      :false: Return full conference information.
    =======  =======  =================================================================
    
    .. rubric:: Request
    
    ::
    
      GET /conferences/14506 HTTP/1.1
    
    .. rubric:: Responses
    
    With micro=true::
    
      HTTP/1.0 200 OK
      
      {
        "highest_local_no": 1996, 
        "nice": 77, 
        "type": {
          "forbid_secret": 0, 
          "allow_anonymous": 1, 
          "rd_prot": 1, 
          "secret": 0, 
          "letterbox": 1, 
          "original": 0, 
          "reserved3": 0, 
          "reserved2": 0
        }, 
        "name": "Oskars Testperson", 
        "conf_no": 14506
      }
    
    With micro=false::
    
      HTTP/1.0 200 OK
      
      {
        "super_conf": {
          "conf_name": "", 
          "conf_no": 0
        }, 
        "creator": {
          "pers_no": 14506, 
          "pers_name": "Oskars Testperson"
        }, 
        "no_of_texts": 1977, 
        "no_of_members": 1, 
        "creation_time": "2012-04-28 19:49:11", 
        "permitted_submitters": {
          "conf_name": "", 
          "conf_no": 0
        }, 
        "conf_no": 14506, 
        "last_written": "2012-07-31 00:00:11", 
        "keep_commented": 77, 
        "name": "Oskars Testperson", 
        "type": {
          "forbid_secret": 0, 
          "allow_anonymous": 1, 
          "rd_prot": 1, 
          "secret": 0, 
          "letterbox": 1, 
          "original": 0, 
          "reserved3": 0, 
          "reserved2": 0
        }, 
        "first_local_no": 20, 
        "expire": 0, 
        "msg_of_day": 0, 
        "supervisor": {
          "conf_name": "Oskars Testperson", 
          "conf_no": 14506
        }, 
        "presentation": 0, 
        "nice": 77
      }
    
    Conference does not exist::
    
      HTTP/1.0 404 NOT FOUND
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET http://localhost:5001/conferences/14506?micro=true
    
    """
    try:
        micro = get_bool_arg_with_default(request.args, 'micro', True)
        return jsonify(
            to_dict(g.ksession.get_conference(conf_no, micro), True,
                    g.ksession))
    except kom.UndefinedConference as ex:
        return error_response(404, kom_error=ex)
Beispiel #12
0
def persons_list():
    """Lookup person names.
    
    An existing session is not required, but if one exist (i.e. valid
    cookie) it will be used. Otherwise a new session will be created
    temporarily for this request.
    
    Query parameters:
    
    =======  =======  =================================================================
    Key      Type     Values
    =======  =======  =================================================================
    name     string   Name to look up according to `KOM conventions <http://www.lysator.liu.se/lyskom/protocol/11.1/protocol-a.html#Name%20Expansion>`_.
    =======  =======  =================================================================
    
    .. rubric:: Request
    
    ::
    
      GET /persons/?name=Osk%20t HTTP/1.0
    
    .. rubric:: Response
    
    ::
    
      HTTP/1.0 200 OK
      
      {
        "persons": [
          {
            "pers_no": 13212, 
            "pers_name": "Oskars tredje person"
          }, 
          {
            "pers_no": 14506, 
            "pers_name": "Oskars Testperson"
          }
        ]
      }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET -H "Content-Type: application/json" \\
           http://localhost:5001/persons/?name=Osk%20t
    
    """

    name = request.args["name"]
    if g.ksession:
        # Use exising session if we have one
        ksession = g.ksession
    else:
        # .. otherwise create a new temporary session
        ksession = KomSession(_kom_server)
        ksession.connect()

    try:
        lookup = ksession.lookup_name(name, True, False)
        persons = [dict(pers_no=t[0], pers_name=t[1]) for t in lookup]
        return jsonify(dict(persons=persons))
    except kom.Error as ex:
        return error_response(400, kom_error=ex)
    finally:
        # if we created a new session, close it
        if not g.ksession:
            ksession.disconnect()
Beispiel #13
0
def sessions_create():
    """Create a new session (i.e. login).
    
    Note: If the login is successful, the matched full name will be
    returned in the response.
    
    If no client is specified in the request, "httpkom" will be used.
    
    .. rubric:: Request
    
    ::
    
      POST /sessions/ HTTP/1.1
      
      {
        "person": { "pers_no": 14506 },
        "password": "******",
        "client": { "name": "jskom", "version": "0.2" }
      }
    
    .. rubric:: Responses
    
    Successful login::
    
      HTTP/1.0 200 OK
      Set-Cookie: session_id=033556ee-3e52-423f-9c9a-d85aed7688a1; expires=Sat, 19-May-2012 12:44:51 GMT; Max-Age=604800; Path=/
      
      { "id": "033556ee-3e52-423f-9c9a-d85aed7688a1",
        "person": { "pers_no": 14506, "pers_name": "Oskars testperson" },
        "client": { "name": "jskom", "version": "0.2" } }
    
    Failed login::
    
      HTTP/1.1 401 Unauthorized
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X POST -H "Content-Type: application/json" \\
           -d '{ "pers_no": 14506, "password": "******" }' \\
            http://localhost:5001/sessions/
    
    """
    old_ksession = _get_komsession(_get_session_id())
    if old_ksession:
        # already loggedin, logout first, then try to login with the
        # supplied credentials.
        _logout(old_ksession)

    try:
        person = request.json['person']
    except KeyError as ex:
        return error_response(400, error_msg='Missing "person".')

    try:
        pers_no = person['pers_no']
    except KeyError as ex:
        return error_response(400, error_msg='Missing "pers_no" in "person".')

    try:
        password = request.json['password']
    except KeyError as ex:
        return error_response(400, error_msg='Missing "password".')

    try:
        if 'client' in request.json and request.json['client'] is not None:
            ksession = _login(pers_no, password,
                              request.json['client']['name'],
                              request.json['client']['version'])
        else:
            ksession = _login(pers_no, password)

        response = jsonify(to_dict(ksession, True, ksession))
        response.set_cookie('session_id',
                            domain=app.config['HTTPKOM_COOKIE_DOMAIN'],
                            value=ksession.id,
                            max_age=7 * 24 * 60 * 60)
        return response
    except (kom.InvalidPassword, kom.UndefinedPerson, kom.LoginDisallowed,
            kom.ConferenceZero) as ex:
        return error_response(401, kom_error=ex)
Beispiel #14
0
def persons_list():
    """Lookup person names.
    
    An existing session is not required, but if one exist (i.e. valid
    cookie) it will be used. Otherwise a new session will be created
    temporarily for this request.
    
    Query parameters:
    
    =======  =======  =================================================================
    Key      Type     Values
    =======  =======  =================================================================
    name     string   Name to look up according to `KOM conventions <http://www.lysator.liu.se/lyskom/protocol/11.1/protocol-a.html#Name%20Expansion>`_.
    =======  =======  =================================================================
    
    .. rubric:: Request
    
    ::
    
      GET /persons/?name=Osk%20t HTTP/1.0
    
    .. rubric:: Response
    
    ::
    
      HTTP/1.0 200 OK
      
      {
        "persons": [
          {
            "pers_no": 13212, 
            "pers_name": "Oskars tredje person"
          }, 
          {
            "pers_no": 14506, 
            "pers_name": "Oskars Testperson"
          }
        ]
      }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET -H "Content-Type: application/json" \\
           http://localhost:5001/persons/?name=Osk%20t
    
    """

    name = request.args['name']
    if g.ksession:
        # Use exising session if we have one
        ksession = g.ksession
    else:
        # .. otherwise create a new temporary session
        ksession = KomSession(_kom_server)
        ksession.connect()

    try:
        lookup = ksession.lookup_name(name, True, False)
        persons = [dict(pers_no=t[0], pers_name=t[1]) for t in lookup]
        return jsonify(dict(persons=persons))
    except kom.Error as ex:
        return error_response(400, kom_error=ex)
    finally:
        # if we created a new session, close it
        if not g.ksession:
            ksession.disconnect()
Beispiel #15
0
def sessions_create():
    """Create a new session (i.e. login).
    
    Note: If the login is successful, the matched full name will be
    returned in the response.
    
    If no client is specified in the request, "httpkom" will be used.
    
    .. rubric:: Request
    
    ::
    
      POST /sessions/ HTTP/1.1
      
      {
        "person": { "pers_no": 14506 },
        "password": "******",
        "client": { "name": "jskom", "version": "0.2" }
      }
    
    .. rubric:: Responses
    
    Successful login::
    
      HTTP/1.0 200 OK
      Set-Cookie: session_id=033556ee-3e52-423f-9c9a-d85aed7688a1; expires=Sat, 19-May-2012 12:44:51 GMT; Max-Age=604800; Path=/
      
      { "id": "033556ee-3e52-423f-9c9a-d85aed7688a1",
        "person": { "pers_no": 14506, "pers_name": "Oskars testperson" },
        "client": { "name": "jskom", "version": "0.2" } }
    
    Failed login::
    
      HTTP/1.1 401 Unauthorized
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X POST -H "Content-Type: application/json" \\
           -d '{ "pers_no": 14506, "password": "******" }' \\
            http://localhost:5001/sessions/
    
    """
    old_ksession = _get_komsession(_get_session_id())
    if old_ksession:
        # already loggedin, logout first, then try to login with the
        # supplied credentials.
        _logout(old_ksession)
    
    try:
        person = request.json['person']
    except KeyError as ex:
        return error_response(400, error_msg='Missing "person".')
    
    try:
        pers_no = person['pers_no']
    except KeyError as ex:
        return error_response(400, error_msg='Missing "pers_no" in "person".')

    try:
        password = request.json['password']
    except KeyError as ex:
        return error_response(400, error_msg='Missing "password".')
    
    try:
        if 'client' in request.json and request.json['client'] is not None:
            ksession = _login(pers_no, password,
                              request.json['client']['name'], request.json['client']['version'])
        else:
            ksession = _login(pers_no, password)
        
        response = jsonify(to_dict(ksession, True, ksession))
        response.set_cookie('session_id', domain=app.config['HTTPKOM_COOKIE_DOMAIN'],
                            value=ksession.id, max_age=7*24*60*60)
        return response
    except (kom.InvalidPassword, kom.UndefinedPerson, kom.LoginDisallowed,
            kom.ConferenceZero) as ex:
        return error_response(401, kom_error=ex)
Beispiel #16
0
def conferences_get(conf_no):
    """Get information about a specific conference.
    
    =======  =======  =================================================================
    Key      Type     Values
    =======  =======  =================================================================
    micro    boolean  :true: (Default) Return micro conference information (`UConference <http://www.lysator.liu.se/lyskom/protocol/11.1/protocol-a.html#Conferences>`_) which causes less load on the server.
                      :false: Return full conference information.
    =======  =======  =================================================================
    
    .. rubric:: Request
    
    ::
    
      GET /conferences/14506 HTTP/1.1
    
    .. rubric:: Responses
    
    With micro=true::
    
      HTTP/1.0 200 OK
      
      {
        "highest_local_no": 1996, 
        "nice": 77, 
        "type": {
          "forbid_secret": 0, 
          "allow_anonymous": 1, 
          "rd_prot": 1, 
          "secret": 0, 
          "letterbox": 1, 
          "original": 0, 
          "reserved3": 0, 
          "reserved2": 0
        }, 
        "name": "Oskars Testperson", 
        "conf_no": 14506
      }
    
    With micro=false::
    
      HTTP/1.0 200 OK
      
      {
        "super_conf": {
          "conf_name": "", 
          "conf_no": 0
        }, 
        "creator": {
          "pers_no": 14506, 
          "pers_name": "Oskars Testperson"
        }, 
        "no_of_texts": 1977, 
        "no_of_members": 1, 
        "creation_time": "2012-04-28 19:49:11", 
        "permitted_submitters": {
          "conf_name": "", 
          "conf_no": 0
        }, 
        "conf_no": 14506, 
        "last_written": "2012-07-31 00:00:11", 
        "keep_commented": 77, 
        "name": "Oskars Testperson", 
        "type": {
          "forbid_secret": 0, 
          "allow_anonymous": 1, 
          "rd_prot": 1, 
          "secret": 0, 
          "letterbox": 1, 
          "original": 0, 
          "reserved3": 0, 
          "reserved2": 0
        }, 
        "first_local_no": 20, 
        "expire": 0, 
        "msg_of_day": 0, 
        "supervisor": {
          "conf_name": "Oskars Testperson", 
          "conf_no": 14506
        }, 
        "presentation": 0, 
        "nice": 77
      }
    
    Conference does not exist::
    
      HTTP/1.0 404 NOT FOUND
      
      { TODO: error stuff }
    
    .. rubric:: Example
    
    ::
    
      curl -b cookies.txt -c cookies.txt -v \\
           -X GET http://localhost:5001/conferences/14506?micro=true
    
    """
    try:
        micro = get_bool_arg_with_default(request.args, 'micro', True)
        return jsonify(to_dict(g.ksession.get_conference(conf_no, micro),
                               True, g.ksession))
    except kom.UndefinedConference as ex:
        return error_response(404, kom_error=ex)