Skip to content

Commit

Permalink
Fix renaming of spiders
Browse files Browse the repository at this point in the history
Renaming spiders is very problematic because an spider name is also it's
ID

- Validate spider names (names such as "foo/bar" and ".." should not be
  allowed)
- Return the renamed spider as a "new" spider and mark the old one as
  deleted, unload it in the frontend
- Don't allow renaming spiders when they are being edited, this will
  avoid having to transition to the new spider if renamed
  • Loading branch information
dvdbng committed Feb 29, 2016
1 parent 7620754 commit 116047f
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 6 deletions.
3 changes: 3 additions & 0 deletions portiaui/app/components/buffered-input.js
Expand Up @@ -78,6 +78,9 @@ export default Ember.Component.extend({

endEditing(reason) {
const value = this.get('viewValue');
if (typeof this.attrs.validate === 'function' && !this.attrs.validate(value)) {
return Ember.run.next(this, this.setInputFocus);
}
this.setProperties({
focused: false,
value: value,
Expand Down
1 change: 1 addition & 0 deletions portiaui/app/components/list-item-editable.js
Expand Up @@ -6,6 +6,7 @@ export default Ember.Component.extend({

editing: false,
onChange: null,
validate: null,
spellcheck: true,
value: null,

Expand Down
30 changes: 28 additions & 2 deletions portiaui/app/components/project-structure-listing.js
Expand Up @@ -5,6 +5,8 @@ export default Ember.Component.extend({
browser: Ember.inject.service(),
dispatcher: Ember.inject.service(),
uiState: Ember.inject.service(),
notificationManager: Ember.inject.service(),
routing: Ember.inject.service('-routing'),

tagName: '',

Expand Down Expand Up @@ -43,8 +45,32 @@ export default Ember.Component.extend({
this.get('dispatcher').removeSpider(spider);
},

saveSpider(spider) {
spider.save();
validateSpiderName(name) {
const nm = this.get('notificationManager');
if(!/^[a-zA-Z0-9][a-zA-Z0-9_\.-]*$/.test(name)) {
nm.showWarningNotification(`Invalid spider name.
Only letters, numbers, underscores, dashes and dots are allowed.`);
return false;
}
return true;
},

loadSpider(spider) {
// Using link-to was problematic because it interpreted an enter in
// the input field as intention to follow the link (rather than
// saving the value)
this.get('routing').transitionTo('projects.project.spider', [spider], {}, true);
},

saveSpiderName(spider) {
// HACK: Renaming the spider will change it's ID, changing the ID
// of a record is not supported in Ember data, so we return a new
// record from the server and mark the original as deleted.
spider.save().then(() => {
if(spider.get('name') === '_deleted') {
spider.unloadRecord();
}
});
}
}
});
2 changes: 1 addition & 1 deletion portiaui/app/templates/components/list-item-editable.hbs
@@ -1,5 +1,5 @@
{{#if editing}}
{{buffered-input class="input-list-item" value=(mut value) focused=editing autoSelect=true spellcheck=spellcheck onChange=onChange}}
{{buffered-input class="input-list-item" value=(mut value) focused=editing autoSelect=true spellcheck=spellcheck onChange=onChange validate=validate}}
{{else}}
<span>{{value}}</span>
{{icon-button icon='edit' action=(action 'startEditing') bubbles=false}}
Expand Down
Expand Up @@ -12,7 +12,11 @@
{{#tree-list-item hide=(and currentSpider (not-eq spider currentSpider)) as |options|}}
{{#link-to 'projects.project.spider' spider}}
{{list-item-icon icon='spider'}}
{{list-item-editable value=(mut spider.name) editing=(mut spider.new) onChange=(action 'saveSpider' spider)}}
{{#if currentSpider}}
{{#list-item-text}}{{spider.name}}{{/list-item-text}}
{{else}}
{{list-item-editable value=(mut spider.name) onChange=(action 'saveSpiderName' spider) validate=(action 'validateSpiderName')}}
{{/if}}
{{#animation-container class="icon" setWidth=false setHeight=false}}
{{list-item-icon icon='remove' action=(action 'removeSpider' spider) bubbles=false}}
{{/animation-container}}
Expand Down
4 changes: 4 additions & 0 deletions slyd/slyd/gitstorage/projectspec.py
@@ -1,4 +1,5 @@
import json
import re

from os.path import join
from .repoman import Repoman
Expand All @@ -23,6 +24,9 @@ def _rfile_name(self, *resources):
def rename_spider(self, from_name, to_name):
if to_name == from_name:
return
if not re.match('^[a-zA-Z0-9][a-zA-Z0-9_\.-]*$', to_name):
raise BadRequest('Bad Request', 'Invalid spider name')

if to_name in self.list_spiders():
raise BadRequest('Bad Request', 'A spider already exists with the '
'name, "%s".' % to_name)
Expand Down
14 changes: 12 additions & 2 deletions slyd/slyd/resources/spiders.py
Expand Up @@ -38,15 +38,25 @@ def update_spider(manager, spider_id, attributes):
spider = manager.spider_json(spider_id)
spider.update(attributes)
get_schema_validator('spider').validate(spider)
if spider.get('name') and spider_id != spider['name']:
rename = spider.get('name') and spider_id != spider['name']
original_id = spider_id
if rename:
manager.rename_spider(spider_id, spider['name'].encode('utf-8'))
spider_id = spider['name']
spider['id'] = spider_id
clean_spider(spider)
manager.savejson(spider, ['spiders', spider_id.encode('utf-8')])
spider['samples'] = [{'id': name} for name in spider['template_names']]
context = ctx(manager, spider_id=spider_id)
return SpiderSchema(context=context).dump(spider).data
response = SpiderSchema(context=context).dump(spider).data
if rename:
# HACK: Ember doesn't allow changing IDs, so return a "new" spider
# and mark the original as deleted.
new_spider = SpiderSchema(context=context).dump(spider).data
response['included'] = [new_spider['data']]
response['data']['attributes']['name'] = "_deleted"
response['data']['id'] = original_id
return response


def delete_spider(manager, spider_id, attributes=None):
Expand Down

0 comments on commit 116047f

Please sign in to comment.