app.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. from flask import Flask, abort, jsonify, url_for, render_template, g, request
  2. from flask.json import JSONEncoder
  3. from flask_sqlalchemy import SQLAlchemy
  4. from flask_httpauth import HTTPBasicAuth
  5. import decimal, re, json
  6. from passlib.apps import custom_app_context as pwd_context
  7. from itsdangerous import (TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired)
  8. app = Flask(__name__)
  9. app.config['SECRET_KEY'] = 'geunyeorang cheoeum daehoa sijag hajamaja'
  10. app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://ruvadmin:ge9BQ7fT8bVBgm1B@localhost/ruvapp'
  11. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
  12. db = SQLAlchemy(app)
  13. auth = HTTPBasicAuth()
  14. class MJSONEncoder(JSONEncoder):
  15. def default(self, obj):
  16. if isinstance(obj, decimal.Decimal):
  17. # Convert decimal instances to strings.
  18. return str(obj)
  19. return super(MJSONEncoder, self).default(obj)
  20. app.json_encoder = MJSONEncoder
  21. class User(db.Model):
  22. __tablename__ = "users"
  23. id = db.Column(db.Integer, primary_key=True)
  24. email = db.Column(db.String(120), unique=True)
  25. password_hash = db.Column(db.String(128))
  26. def hash_password(self, password):
  27. self.password_hash = pwd_context.encrypt(password)
  28. print(self.password_hash)
  29. def verify_password(self, password):
  30. return pwd_context.verify(password, self.password_hash)
  31. def generate_auth_token(self, expiration=600):
  32. s = Serializer(app.config['SECRET_KEY'], expires_in=expiration)
  33. return s.dumps({'id': self.id})
  34. @staticmethod
  35. def verify_auth_token(token):
  36. print ('48 - ' + token)
  37. s = Serializer(app.config['SECRET_KEY'])
  38. try:
  39. data = s.loads(token)
  40. except SignatureExpired:
  41. return None # valid token, but expired
  42. except BadSignature:
  43. return None # invalid token
  44. user = User.query.get(data['id'])
  45. if user is None:
  46. return
  47. return user
  48. class Roof(db.Model):
  49. __tablename__ = "roofs"
  50. id = db.Column(db.Integer, primary_key=True)
  51. length = db.Column(db.DECIMAL(10, 3))
  52. width = db.Column(db.DECIMAL(10, 3))
  53. slope = db.Column(db.Float)
  54. price = db.Column(db.DECIMAL(10, 2))
  55. address = db.Column(db.VARCHAR(255))
  56. def serialize(self):
  57. return {
  58. 'id': self.id,
  59. 'length': re.sub("[^0-9^.]", "", str(self.length)),
  60. 'width': re.sub("[^0-9^.]", "", str(self.width)),
  61. 'slope': re.sub("[^0-9^.]", "", str(self.slope)),
  62. 'price': re.sub("[^0-9^.]", "", str(self.price)),
  63. 'address': self.address.encode("utf-8"),
  64. }
  65. @auth.verify_password
  66. def verify_password(email_or_token, password):
  67. # first try to authenticate by token
  68. user = User.verify_auth_token(email_or_token)
  69. if not user:
  70. # try to authenticate with username/password
  71. user = User.query.filter_by(email=email_or_token).first()
  72. print ('86')
  73. print (user)
  74. if not user or not user.verify_password(password):
  75. return False
  76. g.user = user
  77. return True
  78. @app.route('/')
  79. def index():
  80. return render_template('index.html')
  81. @app.route('/login', methods=['POST'])
  82. def login():
  83. if request.headers['content-Type'] == 'application/x-www-form-urlencoded':
  84. email = request.form['email']
  85. password = request.form['password']
  86. if email is None or password is None:
  87. abort(400)
  88. if User.query.filter_by(email=email).first() is not None:
  89. verify = verify_password(email, password)
  90. user = User(email=email)
  91. print('108 - ' + verify)
  92. if verify:
  93. print('You already in there\n')
  94. return render_template('success.html')
  95. else:
  96. print ('Login failed')
  97. return 'Login failed'
  98. user = User(email=email)
  99. User.hash_password(user, password)
  100. db.session.add(user)
  101. db.session.commit()
  102. return render_template('success.html')
  103. elif request.headers['Content-Type'] == 'application/json':
  104. print ('122')
  105. print(request.json)
  106. email = request.json.get('email')
  107. password = request.json.get('password')
  108. if email is None or password is None:
  109. abort(400)
  110. if User.query.filter_by(email=email).first() is not None:
  111. verify = verify_password(email, password)
  112. user = User(email=email)
  113. print ('130')
  114. print (verify)
  115. if verify:
  116. print (g.user.id)
  117. token = g.user.generate_auth_token(600)
  118. return jsonify({'email': user.email, 'authToken': token.decode('ascii')}), 201, {
  119. 'Location': url_for('get_user', id=g.user.id, _external=True)}
  120. else:
  121. print ('Error: Login Unsuccessful')
  122. return 'Error: Login Unsuccessful'
  123. user = User(email=email)
  124. User.hash_password(user, password)
  125. db.session.add(user)
  126. db.session.commit()
  127. verify_password(email, password)
  128. token = g.user.generate_auth_token(600)
  129. return jsonify({'email': user.email, 'authToken': token.decode('ascii')}), 201, {'Location': url_for('get_user', id=user.id, _external=True)}
  130. @app.route('/roof/add', methods=['POST'])
  131. @auth.login_required
  132. def add_roof():
  133. print ('Requesting roof addition')
  134. if request.headers['Content-Type'] == 'application/json':
  135. print ('155')
  136. print (request.json)
  137. length = request.json.get('length')
  138. width = request.json.get('width')
  139. slope = request.json.get('slope')
  140. address = request.json.get('address')
  141. price = request.json.get('price')
  142. if length is None or width is None or slope is None or address is None or price is None:
  143. print ('Something not set')
  144. abort(400)
  145. if Roof.query.filter_by(address=address).first() is not None:
  146. roof = Roof(address=address, price=price)
  147. print ('Found a roof')
  148. if roof is not None:
  149. print ('Roof is not None')
  150. print (str(roof.serialize()))
  151. return jsonify({'Roof': roof.serialize()}), 201
  152. print ('Make new roof')
  153. roof = Roof(address=address, length=length, width=width, slope=slope, price=price)
  154. db.session.add(roof)
  155. db.session.commit()
  156. print ('Created roof==> ' + str(roof.serialize()))
  157. return jsonify({'Roof': roof.serialize()}), 201, {
  158. 'Location': url_for('get_roof', address=roof.address, _external=True)}
  159. @app.route('/users/<int:id>')
  160. @auth.login_required
  161. def get_user(id):
  162. user = User.query.get(id)
  163. if not user:
  164. abort(400)
  165. return jsonify({'email': user.email, 'password': user.password_hash})
  166. @app.route('/roofs/<int:id>')
  167. @auth.login_required
  168. def get_roof(id):
  169. roof = Roof.query.get(id)
  170. if not roof:
  171. abort(400)
  172. return jsonify({'Roof': roof.serialize()})
  173. @app.route('/token')
  174. @auth.login_required
  175. def get_auth_token():
  176. token = g.user.generate_auth_token(600)
  177. return jsonify({'token': token.decode('ascii'), 'duration': 600})
  178. @app.route('/resource')
  179. @auth.login_required
  180. def get_resource():
  181. return jsonify({'data': 'Hello, %s!' % g.user.email})
  182. @app.route('/roofs/all', methods=['GET'])
  183. @auth.login_required
  184. def get_roofs():
  185. roofs = Roof.query.all()
  186. rStr = ''
  187. mJson = ''
  188. rlist = [None] * 10
  189. i = 0
  190. for roof in roofs:
  191. # rStr += str(jsonify({i: (roof.serialize())}))
  192. mJson += '{"roof":' + str(roof.serialize()).replace("'", '"') + '},'
  193. rStr += (str([(str(i) + ":" + str((roof.serialize())))]))
  194. rObj = (["\""+str(i)+"\"", str(roof.serialize())])
  195. rlist.append(["roof", rObj])
  196. i += 1
  197. # rStr = ("[" + rStr[:-1] + "]")
  198. mJson = '{"Roofs":[' + str((mJson[:-1])) + ']}'
  199. # rjson = json.dumps(rStr.replace('\\n', '\n').replace('\"', '"'))
  200. if not roofs:
  201. abort(400)
  202. # return jsonify({'Roofs': rStr.replace("\\", "")}), 201
  203. # return jsonify({'Roofs': str(rStr).replace('\\n', '\n').replace('\"', '"')}), 201
  204. return (mJson.replace('\\"', '"')), 201
  205. def json_list(list):
  206. lst = []
  207. for pn in list:
  208. d = {}
  209. d['roof']=pn
  210. lst.append(d)
  211. return json.dumps(lst)
  212. if __name__ == '__main__':
  213. app.debug = True
  214. # app.debug = False
  215. app.run()