def test_get(client, test_local_account, test_local_assets): account = test_local_account # Find a file and image asset to get file_asset = Asset.one(Q.name == 'file') image_asset = Asset.one(Q.name == 'image') # Get the details for a file response = client.get(url_for('api.get'), data=dict(api_key=account.api_key, uid=file_asset.uid)) assert response.json['status'] == 'success' # Check that the asset information returned is correct payload = response.json['payload'] assert payload.get('created') is not None assert payload['ext'] == 'zip' assert payload['meta']['filename'] == 'file.zip' assert payload.get('modified') is not None assert payload['name'] == 'file' assert payload['type'] == 'file' assert payload.get('uid') is not None assert payload['store_key'] == 'file.' + payload['uid'] + '.zip' # Get the details for an image response = client.get(url_for('api.get'), data=dict(api_key=account.api_key, uid=image_asset.uid)) assert response.json['status'] == 'success' # Check that the asset information returned is correct payload = response.json['payload'] assert payload.get('created') is not None assert payload['ext'] == 'jpg' assert payload['meta']['filename'] == 'image.jpg' assert payload['meta']['image'] == {'size': [720, 960], 'mode': 'RGB'} assert payload.get('modified') is not None assert payload['name'] == 'image' assert payload['type'] == 'image' assert payload.get('uid') is not None assert payload['store_key'] == 'image.' + payload['uid'] + '.jpg' assert len(payload['variations']) == 1 variation = payload['variations'][0] assert variation['name'] == 'test' assert variation['ext'] == 'webp' key = 'image.{uid}.test.{version}.webp'.format( uid=payload['uid'], version=variation['version']) assert variation['store_key'] == key assert variation.get('version') is not None assert variation['meta']['image'] == {'size': [75, 100], 'mode': 'RGBA'}
def set_expires(): """Set the expiry date for an asset""" # Validate the parameters form = SetExpiresForm(request.values) if not form.validate(): return fail('Invalid request', issues=form.errors) form_data = form.data # Get the asset asset = Asset.one(And(Q.account == g.account, Q.uid == form_data['uid'])) # Update the assets `expires` value if 'expires' in form_data: # Set `expires` asset.expires = form_data['expires'] asset.update('expires', 'modified') else: # Unset `expires` Asset.get_collection().update({'_id': asset._id}, {'$unset': { 'expires': '' }}) asset.update('modified') return success()
def test_generate_variations(client, test_backends, test_images): # Define a set of variations for the image variations = { 'test1': [['fit', [200, 200]], ['crop', [0, 0.5, 0.5, 0]], ['rotate', 90], ['output', { 'format': 'jpg', 'quality': 50 }]], 'test2': [['fit', [100, 100]], ['rotate', 90], ['crop', [0, 0.5, 0.5, 0]], ['rotate', 180], ['output', { 'format': 'webp', 'quality': 50 }]] } # Test each backend for account in test_backends: asset = Asset.one(And(Q.account == account, Q.name == 'image')) response = client.post(url_for('api.generate_variations'), data=dict(api_key=account.api_key, uid=asset.uid, variations=json.dumps(variations), on_delivery='wait')) assert response.json['status'] == 'success' # Check the response is correct payload = response.json['payload'] assert len(payload.keys()) == 2 # Test variation 1 assert 'test1' in payload assert payload['test1']['ext'] == 'jpg' assert payload['test1']['name'] == 'test1' key = 'image.{uid}.test1.{version}.jpg'.format( uid=asset.uid, version=payload['test1']['version']) assert payload['test1']['store_key'] == key assert payload['test1']['meta']['image'] == { 'mode': 'RGB', 'size': [200, 150] } # Test variation 2 assert 'test2' in payload assert payload['test2']['ext'] == 'webp' assert payload['test2']['name'] == 'test2' key = 'image.{uid}.test2.{version}.webp'.format( uid=asset.uid, version=payload['test2']['version']) assert payload['test2']['store_key'] == key assert payload['test2']['meta']['image'] == { 'mode': 'RGBA', 'size': [100, 75] }
def get(): """Get the details for an asset""" # Validate the parameters form = GetForm(request.values) if not form.validate(): return fail('Invalid request', issues=form.errors) form_data = form.data # Get the asset asset = Asset.one(And(Q.account == g.account, Q.uid == form_data['uid'])) return success(asset.to_json_type())
def test_download(client, test_local_account, test_local_assets): account = test_local_account # Find an asset to download file_asset = Asset.one(Q.name == 'file') # Download the file response = client.get(url_for('api.download'), data=dict(api_key=account.api_key, uid=file_asset.uid)) assert response.content_type == 'application/zip' content_disposition = 'attachment; filename=' + file_asset.store_key assert response.headers['Content-Disposition'] == content_disposition assert len(response.data) == file_asset.meta['length']
def generate_variations(): """Generate one or more variations for of an image asset""" # Validate the parameters form = GenerateVariationsForm(request.values) if not form.validate(): return fail('Invalid request', issues=form.errors) form_data = form.data # Find the asset asset = Asset.one(And(Q.account == g.account, Q.uid == form_data['uid'])) # Check the asset is an image if asset.type != 'image': return fail('Variations can only be generated for images') # Parse the variation data variations = json.loads(form_data['variations']) # Has the user specified how they want the results delivered? on_delivery = form_data['on_delivery'] or 'wait' if on_delivery == 'wait': # Caller is waiting for a response so generate the variations now # Retrieve the original file backend = g.account.get_backend_instance() f = backend.retrieve(asset.store_key) im = Image.open(f) # Generate the variations new_variations = {} for name, ops in variations.items(): new_variations[name] = asset.add_variation(f, im, name, ops) new_variations[name] = new_variations[name].to_json_type() # Update the assets modified timestamp asset.update('modified') return success(new_variations) else: # Caller doesn't want to wait for a response so generate the variations # in the background. current_app.celery.send_task('generate_variations', [ g.account._id, asset.uid, variations, form_data['webhook'].strip() ]) return success()
def generate_variations(account_id, asset_uid, variations, webhook=''): """Generate a set of variations for an image asset""" # Find the account account = Account.by_id(account_id) if not account: return # Find the asset asset = Asset.one(And(Q.account == account, Q.uid == asset_uid)) if not asset: return # Check the asset hasn't expired if asset.expired: return # Retrieve the original file backend = account.get_backend_instance() f = backend.retrieve(asset.store_key) im = Image.open(f) # Generate the variations new_variations = {} for name, ops in variations.items(): variation = asset.add_variation(im, name, ops) new_variations[name] = variation.to_json_type() # Update the assets modified timestamp asset.update('modified') # If a webhook has been provide call it with details of the new # variations. if webhook: requests.get( webhook, data={ 'account': account.name, 'asset': asset.uid, 'variations': json.dumps(variations) } )
def test_set_expires(client, test_local_account): account = test_local_account # Load a file to upload with open('tests/data/assets/uploads/file.zip', 'rb') as f: file_stream = io.BytesIO(f.read()) # Create an asset response = client.post(url_for('api.upload'), data=dict(api_key=account.api_key, asset=(file_stream, 'file.zip'), name='files/test')) # Get the asset we uploaded asset = Asset.one( And(Q.account == account, Q.uid == response.json['payload']['uid'])) # Set an expiry date 1 hour from now expires = datetime.now(timezone.utc) + timedelta(seconds=3600) expires = time.mktime(expires.timetuple()) response = client.post(url_for('api.set_expires'), data=dict(api_key=account.api_key, uid=asset.uid, expires=str(expires))) assert response.json['status'] == 'success' # Reload the asset and check the expires has been correctly set asset.reload() assert asset.expires == expires # Unset the expiry date response = client.post(url_for('api.set_expires'), data=dict(api_key=account.api_key, uid=asset.uid)) assert response.json['status'] == 'success' # Reload the asset and check the expires has been correctly set asset.reload() assert asset.expires == None
def download(): """Download an asset""" # Validate the parameters form = DownloadForm(request.values) if not form.validate(): return fail('Invalid request', issues=form.errors) form_data = form.data # Get the asset asset = Asset.one(And(Q.account == g.account, Q.uid == form_data['uid'])) # Retrieve the original file backend = g.account.get_backend_instance() f = backend.retrieve(asset.store_key) # Build the file response to return response = make_response(f.read()) response.headers['Content-Type'] = asset.content_type response.headers['Content-Disposition'] = \ 'attachment; filename={0}'.format(asset.store_key) return response
def validate_uid(form, field): """Validate that the asset exists""" asset = Asset.one(And(Q.account == g.account, Q.uid == field.data)) if not asset or asset.expired: raise ValidationError('Asset not found.')