def models(): #Posts the model to sketchfab. if request.method == 'POST': try: logging.debug(msg='sketchfab req: {}'.format(request.form)) SKETCHFAB_DOMAIN = 'sketchfab.com' SKETCHFAB_API_URL = 'https://api.{}/v3'.format(SKETCHFAB_DOMAIN) MODEL_ENDPOINT = SKETCHFAB_API_URL + '/models' logging.debug(msg='sketchfab req: {}'.format(request.form)) # token = get_value(request, 'config', 'token') config = json.loads(request.form.get('config')) auth = config.get('auth') token = auth.get('token') headers = {'Authorization': 'Token {}'.format(token)} # name = get_value(request, 'data', 'Creator Name') data = json.loads(request.form.get('data')) metadata = data.get('metadata') name = metadata.get('Object Title') logging.debug(msg='sketchfab name: {}'.format(name)) data = {'name': name} logging.debug('sketchfab values: {}, {}'.format(token, name)) # data = {'name': post_data.get('name'), # 'description': post_data.get('description'), # 'tags': post_data.get('tags'), # 'categories': post_data.get('categories'), # 'license': post_data.get('license')} file = request.files['file'] file.save('model.zip') f = open('model.zip', 'rb') files = {'modelFile': f} try: r = requests.post(MODEL_ENDPOINT, data=data, files=files, headers=headers) f.close() except requests.exceptions.RequestException as e: return jsonify({'requestException': e}) else: response = r.json() print(response) if os.path.exists('model.zip'): os.remove('model.zip') return jsonify(response) except requests.exceptions.RequestException as e: return jsonify({'requestException': str(e)}) #Deletes the model from sketchfab. if request.method == 'DELETE': try: uid = get_value(request, 'data', 'uid') SKETCHFAB_DOMAIN = 'sketchfab.com' SKETCHFAB_API_URL = 'https://api.{}/v3'.format(SKETCHFAB_DOMAIN) token = get_value(request, 'config', 'token') headers = {'Authorization': 'Token {}'.format(token)} model_endpoint = SKETCHFAB_API_URL + '/models/{}'.format(uid) r = requests.delete(model_endpoint, headers=headers) if r.status_code != 204: return jsonify({ "msg": "Model does not exist.", "content": str(r.content) }) else: return jsonify({ "msg": "Model successfully deleted.", "content": r.status_code }) except requests.exceptions.RequestException as e: return jsonify({'requestException': str(e)}) #Returns the details of the model. if request.method == 'GET': try: uid = get_value(request, 'data', 'uid') SKETCHFAB_DOMAIN = 'sketchfab.com' SKETCHFAB_API_URL = 'https://api.{}/v3'.format(SKETCHFAB_DOMAIN) token = get_value(request, 'config', 'token') headers = {'Authorization': 'Token {}'.format(token)} model__endpoint = SKETCHFAB_API_URL + '/models/{}'.format(uid) r = requests.get(model__endpoint, headers=headers) except requests.exceptions.RequestException as e: return jsonify({'requestException': e}) else: response = r.json() print(response) return jsonify(response)
def objects(): if request.method == 'POST': client = create_client(request) database = client['3deposit'] data = json.loads(request.form.get('data')) deposit_id = data.get('deposit_id') if not deposit_id: return jsonify({"err": "Please enter a valid deposit_id."}) collection = database[COLLECTION_NAME] mongo_id = collection.insert_one(data).inserted_id if mongo_id: return jsonify({"mongo_id": str(mongo_id)}) if request.method == 'PATCH': try: client = create_client(request) database = client[DATABASE_NAME] config = json.loads(request.form.get('config')) deposit_id = config.get('deposit_id') collection = database[COLLECTION_NAME] update_query = { 'deposit_id': deposit_id } values = json.loads(request.form.get('data')) update_values = {} for key in values.keys(): update_values.update({f'deposit_metadata.{key}': values[key]}) result = collection.update_one(update_query, {'$set': update_values}) if result.modified_count == 0: return jsonify({"err": f'PATCH attempted, no change to document for {deposit_id}'}) else: return jsonify({"log": f'Updated deposit ID {deposit_id} with values {str(update_values)}'}) except Exception as err: return jsonify({"err": str(err)}) if request.method == 'GET': try: client = create_client(request) database = client[DATABASE_NAME] config = json.loads(request.form.get('config')) deposit_id = config.get('deposit_id') collection = database[COLLECTION_NAME] if deposit_id: document = collection.find_one(filter={"deposit_id": deposit_id}, projection={'_id': False}) return jsonify(document) if config.get('filters'): if len(config.get('filters')) > 0: filters = config.get('filters') where_clause = {} for f in filters: key = f['key'] op = f['op'] value = f['value'] op_dict = { 'Equals': '=', 'Excludes': '$ne', 'Between': 'between', 'Greater Than': '$gt', 'Less Than': '$lt', 'Contains': '~~*' } key = f'deposit_metadata.{key}' op_dict_char = op_dict[op] if len(value) == 1: value = value[0] if op_dict_char == op_dict['Between']: where_clause.update({key: {'$gte': value[0], '$lte': value[1]}}) elif op_dict_char == op_dict['Contains']: where_clause.update({key: {'$regex': f'.*{value}.*', '$options': 'i'}}) elif op_dict_char in [op_dict['Excludes'], op_dict['Greater Than'], op_dict['Less Than']]: where_clause.update({key: {op_dict_char: value}}) elif op_dict_char == op_dict['Equals']: where_clause.update({key: value}) else: temp = [] if op_dict_char == op_dict['Between']: for index, v in enumerate(value): temp.append({key: {'$gte': v[index][0], '$lte': v[index][1]}}) where_clause.update({"$or": temp}) elif op_dict_char == op_dict['Contains']: for v in value: temp.append({key: {'$regex': f'.*{v}.*', '$options': 'i'}}) where_clause.update({"$or": temp}) elif op_dict_char in [op_dict['Excludes'], op_dict['Greater Than'], op_dict['Less Than']]: for v in value: temp.append({op_dict_char: v}) where_clause.update({"$or": temp}) elif op_dict_char == op_dict['Equals']: for v in value: temp.append({key: v}) where_clause.update({"$or": temp}) docs = collection.find(where_clause, projection={'_id': False}) doc_list = [] for doc in docs: doc_list.append(doc) return jsonify(doc_list) else: docs = collection.find(projection={'_id': False}) doc_list = [] for doc in docs: doc_list.append(doc) return jsonify(doc_list) except Exception as err: return jsonify({"err": str(err)}) if request.method == 'DELETE': client = create_client(request) database = client['3deposit'] deposit_id = get_value(request=request, scope='data', field='deposit_id') collection_name = get_value(request=request, scope='config', field='collection_name') collection = database[collection_name] del_obj = collection.delete_one({"deposit_id": deposit_id}) if del_obj: return jsonify({"del_obj": deposit_id}) else: return jsonify({"err": "Document not deleted."})
def index(): try: # get keys from request object access_key = get_value(request, 'config', 'access_key') secret_key = get_value(request, 'config', 'secret_key') # get AWS S3 bucket name being used for static hosting bucket_name = get_value(request, 'config', 'bucket_name') logging.debug(bucket_name) # Connect to S3 c = boto.connect_s3(access_key, secret_key) b = c.get_bucket(bucket_name) if request.method == 'POST': try: # get deposit it and use as temporary directory name deposit_id = get_value(request, 'data', 'deposit_id') logging.debug(deposit_id) # get deposit file and save to temporary location deposit_file = request.files['file'] deposit_file.save('tmp.zip') deposit_file.close() # unzip into directory and remove tmp file with zipfile.ZipFile('tmp.zip','r') as zip_ref: zip_ref.extractall(deposit_id) file_paths = [] def get_file_paths(tmp_dir): for dir_, _, files in os.walk(tmp_dir): for file_name in files: rel_dir = os.path.relpath(dir_, tmp_dir) rel_file = os.path.join(tmp_dir, rel_dir, file_name) file_paths.append(rel_file) return file_paths fps = get_file_paths(deposit_id) # Get file info for f in fps: source_path = f source_size = os.stat(source_path).st_size print(source_path) # Create a multipart upload request content_type = str(mimetypes.guess_type(source_path)[0]) mp = b.initiate_multipart_upload(source_path, policy='public-read', headers={'Content-Type': content_type}) # Use a chunk size of 50 MiB (feel free to change this) chunk_size = 52428800 chunk_count = int(math.ceil(source_size / float(chunk_size))) # Send the file parts, using FileChunkIO to create a file-like object # that points to a certain byte range within the original file. # We set bytes to never exceed the original file size. for i in range(chunk_count): offset = chunk_size * i bytes = min(chunk_size, source_size - offset) with FileChunkIO(source_path, 'r', offset=offset, bytes=bytes) as fp: mp.upload_part_from_file(fp, part_num=i + 1) # Finish the upload mp.complete_upload() # walk until index.html or first html is found for f in fps: source_path = f if source_path.endswith('index.html'): index_path = source_path break elif source_path.endswith('.html'): index_path = source_path break # return deposit id as resource id and build object url from bucket name # https://<bucket_name>.s3.amazonaws.com/<deposit_id> return jsonify({ 'resource_id': deposit_id, 'location': f'https://{bucket_name}.s3.amazonaws.com/{index_path}' }) except Exception as err: return jsonify({'err': str(err)}) finally: if os.path.exists(deposit_id): shutil.rmtree(deposit_id) if os.path.exists('tmp.zip'): os.remove('tmp.zip') elif request.method == 'GET': resource_id = get_value(request, 'data', 'resource_id') if resource_id: obj_list = [] attr_list = ['metadata', 'content_type', 'etag', 'last_modified', 'md5', 'storage_class', 'size'] length = 0 for obj in b.list(prefix=resource_id): obj_metadata = {} obj_metadata.update({'s3_key_name': obj.name}) for attr in attr_list: obj_metadata.update({attr: getattr(obj, attr)}) obj_list.append(obj_metadata) length += 1 return jsonify({'metadata': obj_list, 'files': length}) else: return jsonify({'metadata': 'No resource_id provided.', 'files': 0}) elif request.method == 'DELETE': resource_id = get_value(request, 'data', 'resource_id') if resource_id: for key in b.list(prefix=resource_id): key.delete() return jsonify({'msg': 'Deleted object '+str(resource_id)+' successfully.'}) else: return jsonify({'msg': 'No resource_id provided.'}) except Exception as err: return jsonify({'err': str(err)})