diff --git a/spa/ajax.py b/spa/ajax.py index 9400c37..6f049bd 100755 --- a/spa/ajax.py +++ b/spa/ajax.py @@ -41,6 +41,7 @@ class AjaxHandler(object): url(r'^facebook_post_likes_allowed/$', 'spa.ajax.facebook_post_likes_allowed', name='ajax_facebook_post_likes_allowed'), url(r'^upload_image/(?P\d+)/$', 'spa.ajax.upload_image', name='ajax_upload_image'), + url(r'^upload_release_image/(?P\d+)/$', 'spa.ajax.upload_release_image', name='ajax_upload_release_image'), url(r'^upload_avatar_image/$', 'spa.ajax.upload_avatar_image', name='ajax_upload_avatar_image'), url(r'^upload_mix_file_handler/$', 'spa.ajax.upload_mix_file_handler', name='ajax_upload_mix_file_handler'), url(r'^lookup/$', 'spa.ajax.lookup', name='ajax_lookup'), @@ -168,6 +169,18 @@ def facebook_post_likes_allowed(request): return HttpResponse(_get_json(False), mimetype="application/json") +@csrf_exempt +def upload_release_image(request, release_id): + try: + if 'release_image' in request.FILES and release_id is not None: + release = Release.objects.get(pk=release_id) + if release is not None: + release.release_image = request.FILES['release_image'] + release.save() + return HttpResponse(_get_json("Success")) + except Exception, ex: + logger.exception("Error uploading avatar") + return HttpResponse(_get_json("Failed")) @csrf_exempt def upload_image(request, mix_id): diff --git a/spa/api/v1/ReleaseResource.py b/spa/api/v1/ReleaseResource.py index a6999d8..2365fdc 100755 --- a/spa/api/v1/ReleaseResource.py +++ b/spa/api/v1/ReleaseResource.py @@ -32,7 +32,7 @@ class ReleaseResource(BackboneCompatibleResource): return bundle def dehydrate(self, bundle): - bundle.data['label'] = bundle.obj.release_label.name + bundle.data['release_label'] = bundle.obj.release_label.name bundle.data['item_url'] = 'release/%s' % bundle.obj.id bundle.data['mode'] = 'release' return bundle diff --git a/static/js/app/app.js b/static/js/app/app.js index c0568cc..369e3a2 100755 --- a/static/js/app/app.js +++ b/static/js/app/app.js @@ -83,6 +83,7 @@ var AppRouter = Backbone.Router.extend({ release.fetch({success:function () { var content = new ReleaseView({model:release}).el; $('#content').html(content); + /* var audio = new ReleaseAudioCollection(); audio.url = window.appSettings.urlRoot + release.attributes.item_url + "/release_audio/"; audio.audio_id = id; @@ -91,6 +92,7 @@ var AppRouter = Backbone.Router.extend({ var content = new ReleaseAudioListView({collection:audio}); $('#release-description').html(content.el); }}); + */ }}); }, releaseAdd: function(){ diff --git a/static/js/app/models/comment.js b/static/js/app/models/comment.js index 3784090..0806cf6 100755 --- a/static/js/app/models/comment.js +++ b/static/js/app/models/comment.js @@ -1,4 +1,4 @@ -var Comment = TastypieModel.extend({ +var Comment = DSSModel.extend({ urlRoot:window.appSettings.urlRoot + "comments/" }); diff --git a/static/js/app/models/event.js b/static/js/app/models/event.js index c5f50d5..9e3ba71 100755 --- a/static/js/app/models/event.js +++ b/static/js/app/models/event.js @@ -1,4 +1,4 @@ -var Event = TastypieModel.extend({ +var Event = DSSModel.extend({ urlRoot:window.appSettings.urlRoot + "event/" }); var EventCollection = TastypieCollection.extend({ diff --git a/static/js/app/models/mix.js b/static/js/app/models/mix.js index f008cc2..d29b667 100755 --- a/static/js/app/models/mix.js +++ b/static/js/app/models/mix.js @@ -1,4 +1,4 @@ -window.Mix = TastypieModel.extend({ +window.Mix = DSSModel.extend({ urlRoot:window.appSettings.urlRoot + "mix/", schema:{ title:'Text', diff --git a/static/js/app/models/release.js b/static/js/app/models/release.js index c48e785..825f2df 100755 --- a/static/js/app/models/release.js +++ b/static/js/app/models/release.js @@ -1,5 +1,24 @@ -var Release = TastypieModel.extend({ - urlRoot:window.appSettings.urlRoot + "release/" +var Release = DSSModel.extend({ + urlRoot:window.appSettings.urlRoot + "release/", + isValid:function () { + this.errors = {}; + if (isEmpty(this.get('release_label'))) { + return this.addError('release_label', 'Please choose a label'); + } + if (isEmpty(this.get('release_title'))) { + return this.addError('release_title', 'Please choose a title'); + } + if (isEmpty(this.get('release_artist'))) { + return this.addError('release_artist', 'Please choose an artist'); + } + if (isEmpty(this.get('release_date'))) { + return this.addError('release_date', 'Please choose a valid date'); + } + if (isEmpty(this.get('release_description'))) { + return this.addError('release_description', 'Please enter a description of some sort'); + } + return ""; + } }); var ReleaseCollection = TastypieCollection.extend({ url:window.appSettings.urlRoot + "release/", diff --git a/static/js/app/models/release_audio.js b/static/js/app/models/release_audio.js index 4080ff7..93550da 100755 --- a/static/js/app/models/release_audio.js +++ b/static/js/app/models/release_audio.js @@ -1,4 +1,4 @@ -var ReleaseAudio = TastypieModel.extend({ +var ReleaseAudio = DSSModel.extend({ urlRoot:window.appSettings.urlRoot + "release_audio/" }); diff --git a/static/js/app/models/user.js b/static/js/app/models/user.js index 63e57df..592c04f 100755 --- a/static/js/app/models/user.js +++ b/static/js/app/models/user.js @@ -1,3 +1,3 @@ -var User = TastypieModel.extend({ +var User = DSSModel.extend({ urlRoot:window.appSettings.urlRoot + "user/" }); diff --git a/static/js/app/utils.js b/static/js/app/utils.js index e2065ed..6bec5fa 100755 --- a/static/js/app/utils.js +++ b/static/js/app/utils.js @@ -79,24 +79,9 @@ window.utils = { }; setHashbangHeader = function (xhr) { xhr.setRequestHeader('X-FB-Nonsense', 'Argle-Bargle'); -} +}; -window.TastypieModel = Backbone.Model.extend({ - base_url:function () { - var temp_url = Backbone.Model.prototype.url.call(this); - return (temp_url.charAt(temp_url.length - 1) == '/' ? temp_url : temp_url + '/'); - }, - url:function () { - return this.base_url(); - } -}); -window.TastypieCollection = Backbone.Collection.extend({ - parse:function (response) { - this.recent_meta = response.meta || {}; - return response.objects || response; - } -}); jQuery.extend({ handleError:function (s, xhr, status, e) { // If a local callback was specified, fire it @@ -113,11 +98,11 @@ jQuery.extend({ (function () { var proxied = window.alert; /* - window.alert = function () { - $('#alert-proxy-message').text(arguments[0]); - $('#alert-proxy').modal(); - }; - */ + window.alert = function () { + $('#alert-proxy-message').text(arguments[0]); + $('#alert-proxy').modal(); + }; + */ })(); function generateGuid() { @@ -129,10 +114,14 @@ function generateGuid() { function pad2(number) { return (number < 10 ? '0' : '') + number } -function getDateAsToday(){ +function getDateAsToday() { var currentTime = new Date(); var day = currentTime.getDate(); var month = currentTime.getMonth() + 1; var year = currentTime.getFullYear(); return (pad2(day) + "/" + pad2(month) + "/" + year); +} + +function isEmpty(val){ + return (val === undefined || val == null || val.length <= 0) ? true : false; } \ No newline at end of file diff --git a/static/js/app/views/release.js b/static/js/app/views/release.js index 8fdd31a..d9538d8 100755 --- a/static/js/app/views/release.js +++ b/static/js/app/views/release.js @@ -72,7 +72,6 @@ var ReleaseCreateView = Backbone.View.extend({ $(this.el).html(this.template({"item":this.model.toJSON()})); var el = this.el; var model = this.model; - console.clear(); var labels, mapped; $('.typeahead', this.el).typeahead({ source:function (query, process) { @@ -89,7 +88,7 @@ var ReleaseCreateView = Backbone.View.extend({ process(labels); }, 'json'); }, - updater: function(item){ + updater:function (item) { $('#release_label_id', el).val(mapped[item].pk); model.set('release_label_id', mapped[item].pk); return item; @@ -97,11 +96,11 @@ var ReleaseCreateView = Backbone.View.extend({ }); $('.datepicker', this.el).datepicker( { - 'format' : 'dd/mm/yyyy' + 'format':'dd/mm/yyyy' } ); $('textarea.tinymce', this.el).tinymce({ - script_url: "/static/js/libs/tiny_mce/tiny_mce.js", + script_url:"/static/js/libs/tiny_mce/tiny_mce.js", mode:"textareas", theme:"advanced", theme_advanced_toolbar_location:"top", @@ -126,18 +125,47 @@ var ReleaseCreateView = Backbone.View.extend({ var model = this.model; var el = this.el; var parent = this; + this.model.set('release_description', $('#release-description', this.el).html()); - this.model.set('release_date', $('#release-date', this.el).val()); - this.model.save( - null, { - success:function () { - window.utils.showAlert("Success", "Release succesfully added", "alert-info", true); - app.navigate('#/release/' + model.get('id')); - }, - error:function () { - alert("Error saving release"); + this.model.set('release_date', $('#release_date', this.el).val()); + this.model.set('embed_code', $('#embed_code', this.el).val()); + if (this.model.isValid() != "") { + if (this.model.errors){ + for (var error in this.model.errors){ + $('#group-' + error, this.el).addClass('error'); + $('#error-' + error, this.el).text(this.model.errors[error]); } - }); + } + } else { + this.model.save( + null, { + success:function () { + $.ajaxFileUpload({ + url:'ajax/upload_release_image/' + model.get('id') + '/', + secureuri:false, + fileElementId:'release_image', + success:function (data, status) { + if (typeof(data.error) != 'undefined') { + if (data.error != '') { + alert(data.error); + } else { + alert(data.msg); + } + } else { + window.utils.showAlert("Success", "Release successfully added", "alert-info", true); + app.navigate('#/release/' + model.get('id')); + } + }, + error:function (data, status, e) { + alert(e); + } + }); + }, + error:function () { + alert("Error saving release"); + } + }); + } return false; }, changed:function (evt) { diff --git a/static/js/libs/backbone/backbone.mine.js b/static/js/libs/backbone/backbone.mine.js new file mode 100755 index 0000000..c9e0d4f --- /dev/null +++ b/static/js/libs/backbone/backbone.mine.js @@ -0,0 +1,57 @@ +Backbone.Validate = function(model, changedAttributes) { + + return (function() { + this.errors = {}; + this.attributes = _.clone(model.attributes); + _.extend(this.attributes, changedAttributes); + _.each(model.validates, function(value, rule) { + this.validators[rule](value); + }); + + this.validators = { + required: function(fields) { + _.each(fields, function(field) { + if(_.isEmpty(this.attributes[field]) === true) { + this.addError(field, I18n.t('errors.form.required')); + } + }); + } + }; + + this.addError = function(field, message) { + if (_.isUndefined(this.errors[field])) { + this.errors[field] = []; + } + this.errors[field].push(message); + }; + + return this.errors; + })(); +}; + +window.TastypieModel = Backbone.Model.extend({ + base_url:function () { + var temp_url = Backbone.Model.prototype.url.call(this); + return (temp_url.charAt(temp_url.length - 1) == '/' ? temp_url : temp_url + '/'); + }, + url:function () { + return this.base_url(); + } +}); + +window.TastypieCollection = Backbone.Collection.extend({ + parse:function (response) { + this.recent_meta = response.meta || {}; + return response.objects || response; + } +}); + +window.DSSModel = window.TastypieModel.extend({ + addError: function(field, message) { + if (_.isUndefined(this.errors[field])) { + this.errors[field] = []; + } + this.errors[field].push(message); + return field; + } +}); \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 9505cf4..7988424 100755 --- a/templates/base.html +++ b/templates/base.html @@ -85,6 +85,7 @@ + diff --git a/templates/views/ReleaseCreateView.html b/templates/views/ReleaseCreateView.html index d4993ac..d0a56ab 100755 --- a/templates/views/ReleaseCreateView.html +++ b/templates/views/ReleaseCreateView.html @@ -3,36 +3,79 @@ {% csrf_token %} Release details
- -
- -
- - +
+
+ +
+ + + +
+
+
+ +
+ + +
-
- -
- +
+
+ +
+ + +
+
+
+ +
+ + +
-
- -
- -
-
-
- -
- -
-
-
+
+
+