Skip to content

Commit

Permalink
Merge pull request #870 from girder/s3-import-no-silent-ignore
Browse files Browse the repository at this point in the history
S3 import no silent ignore
  • Loading branch information
zachmullen committed Jun 22, 2015
2 parents 820f167 + 8760d69 commit 4f16151
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 19 deletions.
7 changes: 6 additions & 1 deletion clients/web/src/models/AssetstoreModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ girder.models.AssetstoreModel = girder.Model.extend({
girder.restRequest({
path: 'assetstore/' + this.get('_id') + '/import',
type: 'POST',
data: params
data: params,
error: null
}).done(_.bind(function (resp) {
this.trigger('g:imported', resp);
}, this)).error(_.bind(function (resp) {
this.trigger('g:error', resp);
}, this));

return this;
}
});
3 changes: 3 additions & 0 deletions clients/web/src/stylesheets/body/assetstores.styl
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@
margin-bottom 22px
padding-top 8px
border-top 1px solid #eee

.g-submit-s3-import
margin-top 7px
4 changes: 4 additions & 0 deletions clients/web/src/views/body/S3ImportView.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ girder.views.S3ImportView = girder.View.extend({
var destId = this.$('#g-s3-import-dest-id').val().trim(),
destType = this.$('#g-s3-import-dest-type').val();

this.$('.g-validation-failed-message').empty();

this.assetstore.off('g:imported').on('g:imported', function () {
girder.router.navigate(destType + '/' + destId, {trigger: true});
}, this).on('g:error', function (resp) {
this.$('.g-validation-failed-message').text(resp.responseJSON.message);
}, this).import({
importPath: this.$('#g-s3-import-path').val().trim(),
destinationId: destId,
Expand Down
40 changes: 24 additions & 16 deletions clients/web/test/spec/adminSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ describe('Test the assetstore page', function () {
};

var _testS3Import = function (params) {
var privateFolder = null;

runs(function () {
var container = _getAssetstoreContainer(params.name);
var el = $('a.g-s3-import-button', container);
Expand All @@ -267,8 +269,22 @@ describe('Test the assetstore page', function () {
}, 'import page to load');

runs(function () {
$('#g-s3-import-dest-id').val(girder.currentUser.id);
$('#g-s3-import-dest-type').val('user');
var coll = new girder.collections.FolderCollection();
coll.on('g:changed', function () {
privateFolder = coll.models[0];
}).fetch({
parentType: 'user',
parentId: girder.currentUser.id
});
});

waitsFor(function () {
return privateFolder !== null;
}, 'admin user folders to be fetched');

runs(function () {
$('#g-s3-import-dest-id').val(privateFolder.id);
$('#g-s3-import-dest-type').val('folder');

$('.g-submit-s3-import').click();
});
Expand Down Expand Up @@ -297,24 +313,16 @@ describe('Test the assetstore page', function () {
return $('.g-file-list-link').length === 1;
}, 'item page to render');

// Delete the file so we can delete the assetstore
// Delete the containing folder so we can delete the assetstore
runs(function () {
$('.g-delete-file').click();
privateFolder.on('g:deleted', function () {
privateFolder = null;
}).destroy();
});

girderTest.waitForDialog();
waitsFor(function () {
return $('#g-confirm-button').length === 1;
}, 'delete file confirmation dialog to appear');

runs(function () {
$('#g-confirm-button').click();
});
girderTest.waitForLoad();

waitsFor(function () {
return $('.g-file-list-link').length === 0;
});
return privateFolder === null;
}, 'private folder to be deleted');

runs(function () {
window.location = '#assetstores';
Expand Down
3 changes: 2 additions & 1 deletion girder/api/v1/assetstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ def importData(self, assetstore, params):

user = self.getCurrentUser()
parent = self.model(parentType).load(
params.pop('destinationId'), user=user, level=AccessType.ADMIN)
params.pop('destinationId'), user=user, level=AccessType.ADMIN,
exc=True)

progress = self.boolParam('progress', params, default=False)
with ProgressContext(
Expand Down
8 changes: 7 additions & 1 deletion girder/utility/s3_assetstore_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,16 @@ def importData(self, parent, parentType, params, progress, user,
self.importData(parent=folder, parentType='folder', params={
'importPath': obj.name
}, progress=progress, user=user, bucket=bucket)
elif isinstance(obj, boto.s3.key.Key) and parentType == 'folder':
elif isinstance(obj, boto.s3.key.Key):
name = obj.name.rsplit('/', 1)[-1]
if not name:
continue

if parentType != 'folder':
raise ValidationException(
'Keys cannot be imported directly underneath a %s.' %
parentType)

item = self.model('item').createItem(
name=name, creator=user, folder=parent, reuseExisting=True)
file = self.model('file').createFile(
Expand Down
11 changes: 11 additions & 0 deletions tests/cases/assetstore_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,17 @@ def s3_pipe_mock(url, request):
extracted = zip.read('Public/My File.txt')
self.assertEqual(extracted, b'dummy file contents')

# Attempt to import item directly into user; should fail
resp = self.request(
'/assetstore/%s/import' % assetstore['_id'], method='POST', params={
'importPath': '/foo/bar',
'destinationType': 'user',
'destinationId': self.admin['_id']
}, user=self.admin)
self.assertStatus(resp, 400)
self.assertEqual(resp.json['message'],
'Keys cannot be imported directly underneath a user.')

# Import existing data from S3
resp = self.request('/folder', method='POST', params={
'parentType': 'folder',
Expand Down

0 comments on commit 4f16151

Please sign in to comment.