Exemple #1
0
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)})