mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-29 08:48:18 -05:00
Add REST create method that errors if a multi already exists.
This commit is contained in:
@@ -93,23 +93,21 @@ class MultiApiController(RedditController, OAuth2ResourceController):
|
||||
"""Fetch a multi's data and subreddit list by name."""
|
||||
return self._format_multi(multi)
|
||||
|
||||
@require_oauth2_scope("subscribe")
|
||||
@api_doc(api_section.multis, extends=GET_multi)
|
||||
@validate(
|
||||
VUser(),
|
||||
VModhash(),
|
||||
info=VMultiPath("multipath"),
|
||||
data=VJSON("model"),
|
||||
)
|
||||
def PUT_multi(self, info, data):
|
||||
"""Create or update a multi."""
|
||||
if info['username'].lower() != c.user.name.lower():
|
||||
def _write_multi_data(self, path_info, data, fail_if_exists=False):
|
||||
if path_info['username'].lower() != c.user.name.lower():
|
||||
raise RedditError('BAD_MULTI_NAME', code=400, fields="multipath")
|
||||
|
||||
try:
|
||||
multi = LabeledMulti._byID(info['path'])
|
||||
multi = LabeledMulti._byID(path_info['path'])
|
||||
except tdb_cassandra.NotFound:
|
||||
multi = LabeledMulti.create(info['path'], c.user)
|
||||
multi = None
|
||||
|
||||
if multi:
|
||||
if fail_if_exists:
|
||||
raise RedditError('MULTI_EXISTS', code=409, fields="multipath")
|
||||
else:
|
||||
multi = LabeledMulti.create(path_info['path'], c.user)
|
||||
|
||||
|
||||
if 'visibility' in data:
|
||||
if data['visibility'] not in ('private', 'public'):
|
||||
@@ -143,6 +141,32 @@ class MultiApiController(RedditController, OAuth2ResourceController):
|
||||
raise RedditError('MULTI_TOO_MANY_SUBREDDITS', code=409)
|
||||
|
||||
multi._commit()
|
||||
return multi
|
||||
|
||||
@require_oauth2_scope("subscribe")
|
||||
@api_doc(api_section.multis, extends=GET_multi)
|
||||
@validate(
|
||||
VUser(),
|
||||
VModhash(),
|
||||
path_info=VMultiPath("multipath"),
|
||||
data=VJSON("model"),
|
||||
)
|
||||
def POST_multi(self, path_info, data):
|
||||
"""Create a multi. Responds with 409 Conflict if it already exists."""
|
||||
multi = self._write_multi_data(path_info, data, fail_if_exists=True)
|
||||
return self._format_multi(multi)
|
||||
|
||||
@require_oauth2_scope("subscribe")
|
||||
@api_doc(api_section.multis, extends=GET_multi)
|
||||
@validate(
|
||||
VUser(),
|
||||
VModhash(),
|
||||
path_info=VMultiPath("multipath"),
|
||||
data=VJSON("model"),
|
||||
)
|
||||
def PUT_multi(self, path_info, data):
|
||||
"""Create or update a multi."""
|
||||
multi = self._write_multi_data(path_info, data)
|
||||
return self._format_multi(multi)
|
||||
|
||||
@require_oauth2_scope("subscribe")
|
||||
|
||||
@@ -124,6 +124,7 @@ error_list = dict((
|
||||
('BAD_MULTI_PATH', _('invalid multi path')),
|
||||
('BAD_MULTI_NAME', _('%(reason)s')),
|
||||
('MULTI_NOT_FOUND', _('that multireddit doesn\'t exist')),
|
||||
('MULTI_EXISTS', _('that multireddit already exists')),
|
||||
('MULTI_CANNOT_EDIT', _('you can\'t change that multireddit')),
|
||||
('MULTI_TOO_MANY_SUBREDDITS', _('no more space for subreddits in that multireddit')),
|
||||
('MULTI_SPECIAL_SUBREDDIT', _("can't add special subreddit %(path)s")),
|
||||
|
||||
@@ -216,7 +216,6 @@ Note: there are a couple of places outside of your subreddit where someone can c
|
||||
create_multi = _('create a new multi'),
|
||||
awesomeness_goes_here = _('awesomeness goes here'),
|
||||
add_multi_sr = _('add a subreddit to your multi.'),
|
||||
multi_already_exists = _('that multi already exists'),
|
||||
)
|
||||
|
||||
class StringHandler(object):
|
||||
|
||||
@@ -56,7 +56,8 @@ r.multi.MultiReddit = Backbone.Model.extend({
|
||||
return r.utils.joinURLs('/api/multi', this.id)
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize: function(attributes, options) {
|
||||
this.uncreated = options && !!options.isNew
|
||||
this.subreddits = new r.multi.MultiRedditList(this.get('subreddits'))
|
||||
this.subreddits.url = this.url() + '/r/'
|
||||
this.on('change:subreddits', function(model, value) {
|
||||
@@ -77,6 +78,21 @@ r.multi.MultiReddit = Backbone.Model.extend({
|
||||
return data
|
||||
},
|
||||
|
||||
isNew: function() {
|
||||
return this.uncreated
|
||||
},
|
||||
|
||||
sync: function(method, model, options) {
|
||||
var res = Backbone.sync.apply(this, arguments)
|
||||
if (method == 'create') {
|
||||
res.done(_.bind(function() {
|
||||
// upon successful creation, unset new flag
|
||||
this.uncreated = false
|
||||
}, this))
|
||||
}
|
||||
return res
|
||||
},
|
||||
|
||||
addSubreddit: function(name, options) {
|
||||
this.subreddits.create({name: name}, options)
|
||||
},
|
||||
@@ -101,14 +117,6 @@ r.multi.MyMultiCollection = Backbone.Collection.extend({
|
||||
return model.get('path').toLowerCase()
|
||||
},
|
||||
|
||||
create: function(attributes, options) {
|
||||
if ('name' in attributes) {
|
||||
attributes['path'] = this.pathByName(attributes['name'])
|
||||
delete attributes['name']
|
||||
}
|
||||
Backbone.Collection.prototype.create.call(this, attributes, options)
|
||||
},
|
||||
|
||||
parse: function(data) {
|
||||
return _.map(data, function(multiData) {
|
||||
return r.multi.multis.reify(multiData)
|
||||
@@ -117,10 +125,6 @@ r.multi.MyMultiCollection = Backbone.Collection.extend({
|
||||
|
||||
pathByName: function(name) {
|
||||
return '/user/' + r.config.logged + '/m/' + name
|
||||
},
|
||||
|
||||
touchByName: function(name) {
|
||||
return r.multi.multis.touch(this.pathByName(name))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -306,7 +310,9 @@ r.multi.MultiDetails = Backbone.View.extend({
|
||||
el: $copyForm,
|
||||
navOnCreate: true,
|
||||
createMulti: _.bind(function(name) {
|
||||
var newMulti = r.multi.mine.touchByName(name)
|
||||
var newMulti = new r.multi.MultiReddit({
|
||||
path: r.multi.mine.pathByName(name)
|
||||
}, {isNew: true})
|
||||
this.model.copyTo(newMulti)
|
||||
return newMulti
|
||||
}, this)
|
||||
@@ -431,30 +437,25 @@ r.multi.MultiCreateForm = Backbone.View.extend({
|
||||
if (this.options.createMulti) {
|
||||
newMulti = this.options.createMulti(name)
|
||||
} else {
|
||||
newMulti = r.multi.mine.touchByName(name)
|
||||
var newMulti = new r.multi.MultiReddit({
|
||||
path: r.multi.mine.pathByName(name)
|
||||
}, {isNew: true})
|
||||
}
|
||||
|
||||
// check if the multi already exists
|
||||
newMulti.fetch({beforeSend: this.showWorkingDeferred})
|
||||
.done(_.bind(function() {
|
||||
this.showError(r.strings('multi_already_exists'))
|
||||
}, this))
|
||||
.fail(_.bind(function() {
|
||||
r.multi.mine.create(newMulti, {
|
||||
wait: true,
|
||||
beforeSend: this.showWorkingDeferred,
|
||||
success: _.bind(function(multi) {
|
||||
this.trigger('create', multi)
|
||||
if (this.options.navOnCreate) {
|
||||
window.location = multi.get('path') + '#created'
|
||||
}
|
||||
}, this),
|
||||
error: _.bind(function(multi, xhr) {
|
||||
var resp = JSON.parse(xhr.responseText)
|
||||
this.showError(resp.explanation)
|
||||
}, this)
|
||||
})
|
||||
}, this))
|
||||
r.multi.mine.create(newMulti, {
|
||||
wait: true,
|
||||
beforeSend: this.showWorkingDeferred,
|
||||
success: _.bind(function(multi) {
|
||||
this.trigger('create', multi)
|
||||
if (this.options.navOnCreate) {
|
||||
window.location = multi.get('path') + '#created'
|
||||
}
|
||||
}, this),
|
||||
error: _.bind(function(multi, xhr) {
|
||||
var resp = JSON.parse(xhr.responseText)
|
||||
this.showError(resp.explanation)
|
||||
}, this)
|
||||
})
|
||||
},
|
||||
|
||||
showError: function(error) {
|
||||
|
||||
Reference in New Issue
Block a user