123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- from functools import wraps
- from http import HTTPStatus
- import jwt
- from bson.objectid import ObjectId
- from flask import Flask, Response, json
- from flask import request, jsonify
- from mongodb_client import get_db
- from redis_client import get_cache
- global UPLOAD_MAX_SIZE
- UPLOAD_MAX_SIZE = 2500635
- CHUNK_SIZE = 100000
- # 416407
- app = Flask(__name__)
- def token_required(f):
- @wraps(f)
- def decorator(*args, **kwargs):
- token = None
- if 'Authorization' in request.headers:
- token = request.headers['Authorization'].split(' ')[1]
- if not token:
- return jsonify({'message': 'a valid token is missing'})
- try:
- data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
- print("logged in user is ")
- print(data)
- except Exception as e:
- print(e)
- return jsonify({'message': 'token is invalid'})
- return f(*args, **kwargs)
- return decorator
- @app.route('/')
- def index():
- resp = Response()
- resp.set_data('Welcome to CRM! Please Login')
- return resp
- @app.route('/uploadshare/<uploadId>/<shareUserId>', methods=["POST"])
- @token_required
- def uploadshare(uploadId, shareUserId):
- r = Response(mimetype="application/json")
- r.headers["Content-Type"] = "text/json; charset=utf-8"
- token = request.headers['Authorization'].split(' ')[1]
- data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
- upload = get_db().uploads.find_one({'_id': ObjectId(uploadId), 'status': 'done', 'ownerid': data['sub']})
- if upload is None:
- r.response = json.dumps({'error': 'upload id not found'})
- r.status_code = HTTPStatus.NOT_FOUND
- return r
- u = get_db().users.find_one({"name": shareUserId})
- if u is None:
- r.response = json.dumps({'error': 'user not found'})
- r.status_code = HTTPStatus.NOT_FOUND
- return r
- if shareUserId in upload['users']:
- r.response = json.dumps({'status': 'already shared'})
- r.status_code = HTTPStatus.OK
- return r
- get_db().uploads.update_one({'_id': ObjectId(uploadId)}, {'$push': {'users': shareUserId}})
- r.response = json.dumps({'status': 'share success'})
- r.status_code = HTTPStatus.OK
- return r
- @app.route('/upload', methods=["POST"])
- @token_required
- def upload():
- r = Response(mimetype="application/json")
- r.headers["Content-Type"] = "text/json; charset=utf-8"
- if 'upload_phase' in request.values and request.values['upload_phase'] == 'start':
- if 'size' not in request.values:
- r.response = json.dumps({'error': 'provide file size'})
- r.status_code = HTTPStatus.BAD_REQUEST
- return r
- else:
- if UPLOAD_MAX_SIZE < int(request.values['size']):
- r.response = json.dumps({'error': 'file too large'})
- r.status_code = HTTPStatus.BAD_REQUEST
- return r
- else:
- # create a session
- size = int(request.values['size'])
- new_session_id = get_cache().incr("upload:session:id", 1)
- token = request.headers['Authorization'].split(' ')[1]
- data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
- table = get_db()['uploads']
- mydict = {'status': 'start','users':[data['sub']]}
- x = table.insert_one(mydict)
- upload_id = x.inserted_id
- upload_redis_key = "{0}:{1}".format("upload:session", new_session_id)
- get_cache().hset(upload_redis_key, "state", "start")
- get_cache().hset(upload_redis_key, "size", size)
- get_cache().hset(upload_redis_key, "start_offset", 0)
- get_cache().hset(upload_redis_key, "upload_id", str(upload_id))
- start_offset = 0
- end_offset = CHUNK_SIZE
- if size <= CHUNK_SIZE:
- end_offset = size
- get_cache().hset(upload_redis_key, "end_offset", end_offset)
- response_body = {
- 'upload_session_id': new_session_id,
- 'upload_id': str(upload_id),
- 'start_offset': start_offset,
- 'end_offset': end_offset,
- }
- r.response = json.dumps(response_body)
- r.status_code = HTTPStatus.OK
- else:
- if 'upload_session_id' not in request.values or 'video_file_chunk' not in request.values:
- r.response = json.dumps({'error': 'provide upload session id and video file chunk'})
- r.status_code = HTTPStatus.BAD_REQUEST
- return r
- upload_session_id = request.values['upload_session_id']
- upload_redis_key = "{0}:{1}".format("upload:session", upload_session_id)
- uploadid = get_cache().hget(upload_redis_key, 'upload_id')
- start_offset = int(get_cache().hget(upload_redis_key, 'end_offset'))
- end_offset = int(get_cache().hget(upload_redis_key, 'end_offset'))
- size = int(get_cache().hget(upload_redis_key, 'size'))
- print(end_offset)
- if end_offset == size:
- response_body = {
- 'upload_session_id': upload_session_id,
- 'uploadid': uploadid,
- 'start_offset': end_offset,
- 'end_offset': end_offset,
- 'status': 'done'
- }
- # complete it
- r.response = json.dumps(response_body)
- token = request.headers['Authorization'].split(' ')[1]
- data = jwt.decode(token.encode('UTF-8'), 'SECRET', algorithm='HS256')
- get_db()['uploads'].update_one({'_id': ObjectId(uploadid)},
- {'$set': {'ownerid': data['sub'], 'status': 'done'}})
- # get_db()['users'].update({'name': data['sub']}, {'$push': {'uploads': uploadid}})
- elif (start_offset + CHUNK_SIZE) >= size:
- end_offset = size
- response_body = {
- 'upload_session_id': upload_session_id,
- 'uploadid': uploadid,
- 'start_offset': start_offset,
- 'end_offset': end_offset,
- }
- r.response = json.dumps(response_body)
- else:
- end_offset = start_offset + CHUNK_SIZE
- # start_offset = start_offset
- response_body = {
- 'upload_session_id': upload_session_id,
- 'uploadid':uploadid,
- 'start_offset': start_offset,
- 'end_offset': end_offset,
- }
- r.response = json.dumps(response_body)
- get_cache().hset(upload_redis_key, "start_offset", start_offset)
- get_cache().hset(upload_redis_key, "end_offset", end_offset)
- video_file_chunk = request.values['video_file_chunk']
- uploadid = get_cache().hget(upload_redis_key, 'upload_id')
- print(video_file_chunk)
- get_db()['uploads'].update_one({'_id': ObjectId(uploadid)}, {'$push': {'chunks': video_file_chunk}})
- return r
- if __name__ == "__main__":
- # app.run(port=8081)
- app.run(host="0.0.0.0")
- # ,ssl_context=("/etc/ssl/certs/pythonusersapi/cert.pem","/etc/ssl/certs/pythonusersapi/key.pem"),port=8081)
|