app.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. from functools import wraps
  2. from http import HTTPStatus
  3. import jwt
  4. from bson.objectid import ObjectId
  5. from flask import Flask, Response, json
  6. from flask import request, jsonify
  7. from mongodb_client import get_db
  8. from redis_client import get_cache
  9. global UPLOAD_MAX_SIZE
  10. UPLOAD_MAX_SIZE = 2500635
  11. CHUNK_SIZE = 100000
  12. # 416407
  13. app = Flask(__name__)
  14. def token_required(f):
  15. @wraps(f)
  16. def decorator(*args, **kwargs):
  17. token = None
  18. if 'Authorization' in request.headers:
  19. token = request.headers['Authorization'].split(' ')[1]
  20. if not token:
  21. return jsonify({'message': 'a valid token is missing'})
  22. try:
  23. data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
  24. print("logged in user is ")
  25. print(data)
  26. except Exception as e:
  27. print(e)
  28. return jsonify({'message': 'token is invalid'})
  29. return f(*args, **kwargs)
  30. return decorator
  31. @app.route('/')
  32. def index():
  33. resp = Response()
  34. resp.set_data('Welcome to CRM! Please Login')
  35. return resp
  36. @app.route('/uploadshare/<uploadId>/<shareUserId>', methods=["POST"])
  37. @token_required
  38. def uploadshare(uploadId, shareUserId):
  39. r = Response(mimetype="application/json")
  40. r.headers["Content-Type"] = "text/json; charset=utf-8"
  41. token = request.headers['Authorization'].split(' ')[1]
  42. data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
  43. upload = get_db().uploads.find_one({'_id': ObjectId(uploadId), 'status': 'done', 'ownerid': data['sub']})
  44. if upload is None:
  45. r.response = json.dumps({'error': 'upload id not found'})
  46. r.status_code = HTTPStatus.NOT_FOUND
  47. return r
  48. u = get_db().users.find_one({"name": shareUserId})
  49. if u is None:
  50. r.response = json.dumps({'error': 'user not found'})
  51. r.status_code = HTTPStatus.NOT_FOUND
  52. return r
  53. if shareUserId in upload['users']:
  54. r.response = json.dumps({'status': 'already shared'})
  55. r.status_code = HTTPStatus.OK
  56. return r
  57. get_db().uploads.update_one({'_id': ObjectId(uploadId)}, {'$push': {'users': shareUserId}})
  58. r.response = json.dumps({'status': 'share success'})
  59. r.status_code = HTTPStatus.OK
  60. return r
  61. @app.route('/upload', methods=["POST"])
  62. @token_required
  63. def upload():
  64. r = Response(mimetype="application/json")
  65. r.headers["Content-Type"] = "text/json; charset=utf-8"
  66. if 'upload_phase' in request.values and request.values['upload_phase'] == 'start':
  67. if 'size' not in request.values:
  68. r.response = json.dumps({'error': 'provide file size'})
  69. r.status_code = HTTPStatus.BAD_REQUEST
  70. return r
  71. else:
  72. if UPLOAD_MAX_SIZE < int(request.values['size']):
  73. r.response = json.dumps({'error': 'file too large'})
  74. r.status_code = HTTPStatus.BAD_REQUEST
  75. return r
  76. else:
  77. # create a session
  78. size = int(request.values['size'])
  79. new_session_id = get_cache().incr("upload:session:id", 1)
  80. token = request.headers['Authorization'].split(' ')[1]
  81. data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
  82. table = get_db()['uploads']
  83. mydict = {'status': 'start','users':[data['sub']]}
  84. x = table.insert_one(mydict)
  85. upload_id = x.inserted_id
  86. upload_redis_key = "{0}:{1}".format("upload:session", new_session_id)
  87. get_cache().hset(upload_redis_key, "state", "start")
  88. get_cache().hset(upload_redis_key, "size", size)
  89. get_cache().hset(upload_redis_key, "start_offset", 0)
  90. get_cache().hset(upload_redis_key, "upload_id", str(upload_id))
  91. start_offset = 0
  92. end_offset = CHUNK_SIZE
  93. if size <= CHUNK_SIZE:
  94. end_offset = size
  95. get_cache().hset(upload_redis_key, "end_offset", end_offset)
  96. response_body = {
  97. 'upload_session_id': new_session_id,
  98. 'upload_id': str(upload_id),
  99. 'start_offset': start_offset,
  100. 'end_offset': end_offset,
  101. }
  102. r.response = json.dumps(response_body)
  103. r.status_code = HTTPStatus.OK
  104. else:
  105. if 'upload_session_id' not in request.values or 'video_file_chunk' not in request.values:
  106. r.response = json.dumps({'error': 'provide upload session id and video file chunk'})
  107. r.status_code = HTTPStatus.BAD_REQUEST
  108. return r
  109. upload_session_id = request.values['upload_session_id']
  110. upload_redis_key = "{0}:{1}".format("upload:session", upload_session_id)
  111. uploadid = get_cache().hget(upload_redis_key, 'upload_id')
  112. start_offset = int(get_cache().hget(upload_redis_key, 'end_offset'))
  113. end_offset = int(get_cache().hget(upload_redis_key, 'end_offset'))
  114. size = int(get_cache().hget(upload_redis_key, 'size'))
  115. print(end_offset)
  116. if end_offset == size:
  117. response_body = {
  118. 'upload_session_id': upload_session_id,
  119. 'uploadid': uploadid,
  120. 'start_offset': end_offset,
  121. 'end_offset': end_offset,
  122. 'status': 'done'
  123. }
  124. # complete it
  125. r.response = json.dumps(response_body)
  126. token = request.headers['Authorization'].split(' ')[1]
  127. data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
  128. get_db()['uploads'].update_one({'_id': ObjectId(uploadid)},
  129. {'$set': {'ownerid': data['sub'], 'status': 'done'}})
  130. # get_db()['users'].update({'name': data['sub']}, {'$push': {'uploads': uploadid}})
  131. elif (start_offset + CHUNK_SIZE) >= size:
  132. end_offset = size
  133. response_body = {
  134. 'upload_session_id': upload_session_id,
  135. 'uploadid': uploadid,
  136. 'start_offset': start_offset,
  137. 'end_offset': end_offset,
  138. }
  139. r.response = json.dumps(response_body)
  140. else:
  141. end_offset = start_offset + CHUNK_SIZE
  142. # start_offset = start_offset
  143. response_body = {
  144. 'upload_session_id': upload_session_id,
  145. 'uploadid':uploadid,
  146. 'start_offset': start_offset,
  147. 'end_offset': end_offset,
  148. }
  149. r.response = json.dumps(response_body)
  150. get_cache().hset(upload_redis_key, "start_offset", start_offset)
  151. get_cache().hset(upload_redis_key, "end_offset", end_offset)
  152. video_file_chunk = request.values['video_file_chunk']
  153. uploadid = get_cache().hget(upload_redis_key, 'upload_id')
  154. print(video_file_chunk)
  155. get_db()['uploads'].update_one({'_id': ObjectId(uploadid)}, {'$push': {'chunks': video_file_chunk}})
  156. return r
  157. if __name__ == "__main__":
  158. # app.run(port=8081)
  159. app.run(host="0.0.0.0")
  160. # ,ssl_context=("/etc/ssl/certs/pythonusersapi/cert.pem","/etc/ssl/certs/pythonusersapi/key.pem"),port=8081)