Browse Source

initial commit files

Inyoung 8 years ago
commit
50a0bceffd
4 changed files with 302 additions and 0 deletions
  1. 3 0
      .gitignore
  2. 37 0
      README.txt
  3. 258 0
      app.py
  4. 4 0
      curls.txt

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+.idea
+.git
+v_grogcerycalc

+ 37 - 0
README.txt

@@ -0,0 +1,37 @@
+
+
+API Paths available:
+
+/
+    (HTML login form)
+
+
+
+/login
+    (accepts application/json)
+
+
+
+/roof/add
+    (accepts application/json)
+
+
+
+/users/<int:id>
+    (takes GET parameter and searches for User by ID)
+
+
+
+/roofs/<string:address>
+    (takes GET parameter and searches for Roof by Address)
+
+
+
+/token
+    (returns an ASCII token which remains viable for 600 seconds)
+
+
+
+/resource
+    (Returns current user's email address)
+INYOUNGISADEVELOPER

+ 258 - 0
app.py

@@ -0,0 +1,258 @@
+from flask import Flask, abort, jsonify, url_for, render_template, g, request
+from flask.json import JSONEncoder
+from flask_sqlalchemy import SQLAlchemy
+from flask_httpauth import HTTPBasicAuth
+import decimal, re, json
+from passlib.apps import custom_app_context as pwd_context
+from itsdangerous import (TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired)
+
+app = Flask(__name__)
+app.config['SECRET_KEY'] = 'geunyeorang cheoeum daehoa sijag hajamaja'
+app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://ruvadmin:ge9BQ7fT8bVBgm1B@localhost/ruvapp'
+app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
+db = SQLAlchemy(app)
+auth = HTTPBasicAuth()
+
+
+class MJSONEncoder(JSONEncoder):
+
+    def default(self, obj):
+        if isinstance(obj, decimal.Decimal):
+            # Convert decimal instances to strings.
+            return str(obj)
+        return super(MJSONEncoder, self).default(obj)
+
+
+app.json_encoder = MJSONEncoder
+
+
+class User(db.Model):
+    __tablename__ = "users"
+    id = db.Column(db.Integer, primary_key=True)
+    email = db.Column(db.String(120), unique=True)
+    password_hash = db.Column(db.String(128))
+
+    def hash_password(self, password):
+        self.password_hash = pwd_context.encrypt(password)
+        print(self.password_hash)
+
+    def verify_password(self, password):
+        return pwd_context.verify(password, self.password_hash)
+
+    def generate_auth_token(self, expiration=600):
+        s = Serializer(app.config['SECRET_KEY'], expires_in=expiration)
+        return s.dumps({'id': self.id})
+
+    @staticmethod
+    def verify_auth_token(token):
+        print ('48 - ' + token)
+        s = Serializer(app.config['SECRET_KEY'])
+        try:
+            data = s.loads(token)
+        except SignatureExpired:
+            return None  # valid token, but expired
+        except BadSignature:
+            return None  # invalid token
+        user = User.query.get(data['id'])
+        if user is None:
+            return
+        return user
+
+
+class Roof(db.Model):
+    __tablename__ = "roofs"
+    id = db.Column(db.Integer, primary_key=True)
+    length = db.Column(db.DECIMAL(10, 3))
+    width = db.Column(db.DECIMAL(10, 3))
+    slope = db.Column(db.Float)
+    price = db.Column(db.DECIMAL(10, 2))
+    address = db.Column(db.VARCHAR(255))
+
+    def serialize(self):
+        return {
+            'id': self.id,
+            'length': re.sub("[^0-9^.]", "", str(self.length)),
+            'width': re.sub("[^0-9^.]", "", str(self.width)),
+            'slope': re.sub("[^0-9^.]", "", str(self.slope)),
+            'price': re.sub("[^0-9^.]", "", str(self.price)),
+            'address': self.address.encode("utf-8"),
+        }
+
+
+@auth.verify_password
+def verify_password(email_or_token, password):
+    # first try to authenticate by token
+    user = User.verify_auth_token(email_or_token)
+    if not user:
+        # try to authenticate with username/password
+        user = User.query.filter_by(email=email_or_token).first()
+        print ('86')
+        print (user)
+        if not user or not user.verify_password(password):
+            return False
+    g.user = user
+    return True
+
+
+@app.route('/')
+def index():
+    return render_template('index.html')
+
+
+@app.route('/login', methods=['POST'])
+def login():
+    if request.headers['content-Type'] == 'application/x-www-form-urlencoded':
+        email = request.form['email']
+        password = request.form['password']
+        if email is None or password is None:
+            abort(400)
+        if User.query.filter_by(email=email).first() is not None:
+            verify = verify_password(email, password)
+            user = User(email=email)
+            print('108 - ' + verify)
+            if verify:
+                print('You already in there\n')
+                return render_template('success.html')
+            else:
+                print ('Login failed')
+                return 'Login failed'
+
+        user = User(email=email)
+        User.hash_password(user, password)
+        db.session.add(user)
+        db.session.commit()
+        return render_template('success.html')
+    elif request.headers['Content-Type'] == 'application/json':
+        print ('122')
+        print(request.json)
+        email = request.json.get('email')
+        password = request.json.get('password')
+        if email is None or password is None:
+            abort(400)
+        if User.query.filter_by(email=email).first() is not None:
+            verify = verify_password(email, password)
+            user = User(email=email)
+            print ('130')
+            print (verify)
+            if verify:
+                print (g.user.id)
+                token = g.user.generate_auth_token(600)
+                return jsonify({'email': user.email, 'authToken': token.decode('ascii')}), 201, {
+                    'Location': url_for('get_user', id=g.user.id, _external=True)}
+            else:
+                print ('Error: Login Unsuccessful')
+                return 'Error: Login Unsuccessful'
+
+        user = User(email=email)
+        User.hash_password(user, password)
+        db.session.add(user)
+        db.session.commit()
+        verify_password(email, password)
+        token = g.user.generate_auth_token(600)
+        return jsonify({'email': user.email, 'authToken': token.decode('ascii')}), 201, {'Location': url_for('get_user', id=user.id, _external=True)}
+
+
+@app.route('/roof/add', methods=['POST'])
+@auth.login_required
+def add_roof():
+    print ('Requesting roof addition')
+    if request.headers['Content-Type'] == 'application/json':
+        print ('155')
+        print (request.json)
+        length = request.json.get('length')
+        width = request.json.get('width')
+        slope = request.json.get('slope')
+        address = request.json.get('address')
+        price = request.json.get('price')
+
+        if length is None or width is None or slope is None or address is None or price is None:
+            print ('Something not set')
+            abort(400)
+        if Roof.query.filter_by(address=address).first() is not None:
+            roof = Roof(address=address, price=price)
+            print ('Found a roof')
+            if roof is not None:
+                print ('Roof is not None')
+                print (str(roof.serialize()))
+                return jsonify({'Roof': roof.serialize()}), 201
+        print ('Make new roof')
+        roof = Roof(address=address, length=length, width=width, slope=slope, price=price)
+        db.session.add(roof)
+        db.session.commit()
+        print ('Created roof==> ' + str(roof.serialize()))
+        return jsonify({'Roof': roof.serialize()}), 201, {
+            'Location': url_for('get_roof', address=roof.address, _external=True)}
+
+
+@app.route('/users/<int:id>')
+@auth.login_required
+def get_user(id):
+    user = User.query.get(id)
+    if not user:
+        abort(400)
+    return jsonify({'email': user.email, 'password': user.password_hash})
+
+
+@app.route('/roofs/<int:id>')
+@auth.login_required
+def get_roof(id):
+    roof = Roof.query.get(id)
+    if not roof:
+        abort(400)
+    return jsonify({'Roof': roof.serialize()})
+
+
+@app.route('/token')
+@auth.login_required
+def get_auth_token():
+    token = g.user.generate_auth_token(600)
+    return jsonify({'token': token.decode('ascii'), 'duration': 600})
+
+
+@app.route('/resource')
+@auth.login_required
+def get_resource():
+    return jsonify({'data': 'Hello, %s!' % g.user.email})
+
+
+@app.route('/roofs/all', methods=['GET'])
+@auth.login_required
+def get_roofs():
+
+    roofs = Roof.query.all()
+    rStr = ''
+    mJson = ''
+    rlist = [None] * 10
+    i = 0
+    for roof in roofs:
+
+        # rStr += str(jsonify({i: (roof.serialize())}))
+        mJson += '{"roof":' + str(roof.serialize()).replace("'", '"') + '},'
+        rStr += (str([(str(i) + ":" + str((roof.serialize())))]))
+        rObj = (["\""+str(i)+"\"", str(roof.serialize())])
+        rlist.append(["roof", rObj])
+        i += 1
+    # rStr = ("[" + rStr[:-1] + "]")
+    mJson = '{"Roofs":[' + str((mJson[:-1])) + ']}'
+    # rjson = json.dumps(rStr.replace('\\n', '\n').replace('\"', '"'))
+
+    if not roofs:
+        abort(400)
+    # return jsonify({'Roofs': rStr.replace("\\", "")}), 201
+    # return jsonify({'Roofs': str(rStr).replace('\\n', '\n').replace('\"', '"')}), 201
+    return (mJson.replace('\\"', '"')), 201
+
+
+def json_list(list):
+    lst = []
+    for pn in list:
+        d = {}
+        d['roof']=pn
+        lst.append(d)
+    return json.dumps(lst)
+
+
+if __name__ == '__main__':
+    app.debug = True
+    # app.debug = False
+    app.run()

+ 4 - 0
curls.txt

@@ -0,0 +1,4 @@
+curl -v -i -X POST -H "Content-Type: application/json"  -u eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MDQ4NjIyMCwiaWF0IjoxNDgwNDg1NjIwfQ.eyJpZCI6N30.X_4i61NCuo387xOInT1i7mgQQ-5gOT6gnu90T3HNIh4:jigga -d'{"address":"87 Nizro Nebula","width":"50", "length":"100", "slope":"66.666", "price":"999.99"}' http://127.0.0.1:5000/roof/add 
+
+
+