Fixed broken login

This commit is contained in:
Fergal Moran
2013-07-03 19:58:31 +01:00
parent 830558af62
commit e20990b8c2
12 changed files with 131 additions and 28 deletions

View File

@@ -154,3 +154,12 @@ class UserResource(BackboneCompatibleResource):
del bundle.data['email'] del bundle.data['email']
del bundle.data['username'] del bundle.data['username']
return bundle return bundle
def obj_update(self, bundle, skip_errors=False, **kwargs):
#Handle the patched items from backbone
if bundle.data['following']:
bundle.obj.get_profile().add_follower(bundle.request.user.get_profile())
else:
bundle.obj.get_profile().remove_follower(bundle.request.user.get_profile())
return super(UserResource, self).obj_update(bundle, skip_errors, **kwargs)

View File

@@ -114,6 +114,9 @@ class UserProfile(_BaseModel):
self.logger.warning("Port: %s" % settings.EMAIL_PORT) self.logger.warning("Port: %s" % settings.EMAIL_PORT)
self.logger.warning("Backend: %s" % settings.EMAIL_BACKEND) self.logger.warning("Backend: %s" % settings.EMAIL_BACKEND)
def remove_follower(self, user):
self.followers.remove(user)
def is_follower(self, user): def is_follower(self, user):
try: try:
return user.get_profile() in self.followers.all() return user.get_profile() in self.followers.all()
@@ -180,5 +183,22 @@ class UserProfile(_BaseModel):
def get_default_avatar_image(cls): def get_default_avatar_image(cls):
return urlparse.urljoin(settings.STATIC_URL, "img/default-avatar-32.png") return urlparse.urljoin(settings.STATIC_URL, "img/default-avatar-32.png")
"""
handle custom patch methods from tastypie
feels smelly, maybe introduce a tier between
the API and the models to handle these patches
"""
def update_following(self, user, value):
try:
if user is None:
return
if user.is_authenticated():
if value:
if self.favourites.filter(user=user).count() == 0:
ActivityFavourite(user=user.get_profile(), mix=self).save()
else:
self.favourites.filter(user=user).delete()
except Exception, ex:
self.logger.error("Exception updating favourite: %s" % ex.message)

View File

@@ -48,12 +48,12 @@ def send_activity_to_realtime(sender, instance, created, **kwargs):
post_save.connect(send_activity_to_realtime, sender=ActivityPlay, dispatch_uid="activity-realtime-play") post_save.connect(send_activity_to_realtime, sender=ActivityPlay, dispatch_uid="activity-realtime-play")
def create_user_profile(sender, instance, created, **kwargs): def create_profile(sender, **kw):
if not created: user = kw["instance"]
UserProfile.objects.create(user=instance) if kw["created"]:
up = UserProfile(user=user)
up.save()
post_save.connect(create_user_profile, sender=User, dispatch_uid="users-profilecreation") post_save.connect(create_profile, sender=User)
if "notification" in settings.INSTALLED_APPS: if "notification" in settings.INSTALLED_APPS:
from notification import models as notification from notification import models as notification

View File

@@ -1,8 +1,9 @@
define ['backbone', 'marionette', 'vent', define ['backbone', 'marionette', 'vent', 'utils'
'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/widgets/headerView', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController',
'views/sidebar/sidebarView', 'views/widgets/headerView', 'views/sidebar/sidebarView', 'models/mix/mixCollection'],
'models/mix/mixCollection'], (Backbone, Marionette, vent, utils,
(Backbone, Marionette, vent, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) -> DssRouter, PanningRegion, RealtimeController, AudioController,
HeaderView, SidebarView, MixCollection) ->
App = new Marionette.Application(); App = new Marionette.Application();
App.audioController = new AudioController(); App.audioController = new AudioController();
App.realtimeController = new RealtimeController(); App.realtimeController = new RealtimeController();
@@ -61,6 +62,15 @@ define ['backbone', 'marionette', 'vent',
social.sharePageToTwitter(model); social.sharePageToTwitter(model);
true true
@listenTo vent, "user:follow", (model)->
console.log "App(vent): user:follow"
model.save 'following', !model.get('following'), patch: true
true
@listenTo vent, "app:login", ->
utils.modal "/dlg/LoginView"
true
App.headerRegion.show(new HeaderView()); App.headerRegion.show(new HeaderView());
sidebarView = new SidebarView(); sidebarView = new SidebarView();
App.sidebarRegion.show(sidebarView) App.sidebarRegion.show(sidebarView)

View File

@@ -1,15 +1,14 @@
// Generated by CoffeeScript 1.6.2 // Generated by CoffeeScript 1.3.3
(function() { (function() {
define(['backbone', 'marionette', 'vent', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/widgets/headerView', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, vent, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) {
var App, sidebarView;
define(['backbone', 'marionette', 'vent', 'utils', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/widgets/headerView', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, vent, utils, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) {
var App, sidebarView;
App = new Marionette.Application(); App = new Marionette.Application();
App.audioController = new AudioController(); App.audioController = new AudioController();
App.realtimeController = new RealtimeController(); App.realtimeController = new RealtimeController();
App.realtimeController.startSocketIO(); App.realtimeController.startSocketIO();
App.vent.on("routing:started", function() { App.vent.on("routing:started", function() {
var enablePushState, pushState; var enablePushState, pushState;
console.log("App(vent): routing:started"); console.log("App(vent): routing:started");
enablePushState = true; enablePushState = true;
pushState = !!(enablePushState && window.history && window.history.pushState); pushState = !!(enablePushState && window.history && window.history.pushState);
@@ -35,7 +34,6 @@
App.addInitializer(function() { App.addInitializer(function() {
$(document).on("click", "a[href]:not([data-bypass])", function(evt) { $(document).on("click", "a[href]:not([data-bypass])", function(evt) {
var href, root; var href, root;
href = { href = {
prop: $(this).prop("href"), prop: $(this).prop("href"),
attr: $(this).attr("href") attr: $(this).attr("href")
@@ -64,7 +62,7 @@
}); });
return true; return true;
}); });
return this.listenTo(vent, "mix:share", function(mode, model) { this.listenTo(vent, "mix:share", function(mode, model) {
console.log("App(vent): mix:share"); console.log("App(vent): mix:share");
if (mode === "facebook") { if (mode === "facebook") {
social.sharePageToFacebook(model); social.sharePageToFacebook(model);
@@ -73,6 +71,17 @@
} }
return true; return true;
}); });
this.listenTo(vent, "user:follow", function(model) {
console.log("App(vent): user:follow");
model.save('following', !model.get('following'), {
patch: true
});
return true;
});
return this.listenTo(vent, "app:login", function() {
utils.modal("/dlg/LoginView");
return true;
});
}); });
App.headerRegion.show(new HeaderView()); App.headerRegion.show(new HeaderView());
sidebarView = new SidebarView(); sidebarView = new SidebarView();

View File

@@ -1,9 +1,26 @@
define ['app', 'moment', 'marionette', 'text!/tpl/UserListItemView'], define ['app', 'moment', 'marionette', 'vent', 'text!/tpl/UserListItemView'],
(App, moment, Marionette, Template)-> (App, moment, Marionette, vent, Template)->
class UserItemView extends Marionette.ItemView class UserItemView extends Marionette.ItemView
template: _.template(Template) template: _.template(Template)
tagName: "tr" tagName: "tr"
events:
"click #follow-button": "followUser"
"click #follow-button-login": "promptLogin"
templateHelpers: templateHelpers:
humanise: (date)-> humanise: (date)->
moment(date).fromNow() moment(date).fromNow()
intialize: =>
@listenTo(@model, 'change:profile.following', @render)
followUser: ->
console.log("UserItemView: followUser")
vent.trigger("user:follow", @model)
promptLogin:->
vent.trigger("app:login", @model)
UserItemView

View File

@@ -1,32 +1,52 @@
// Generated by CoffeeScript 1.6.2 // Generated by CoffeeScript 1.3.3
(function() { (function() {
var __hasProp = {}.hasOwnProperty, var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'moment', 'marionette', 'text!/tpl/UserListItemView'], function(App, moment, Marionette, Template) { define(['app', 'moment', 'marionette', 'vent', 'text!/tpl/UserListItemView'], function(App, moment, Marionette, vent, Template) {
var UserItemView, _ref; var UserItemView;
UserItemView = (function(_super) {
return UserItemView = (function(_super) {
__extends(UserItemView, _super); __extends(UserItemView, _super);
function UserItemView() { function UserItemView() {
_ref = UserItemView.__super__.constructor.apply(this, arguments); this.intialize = __bind(this.intialize, this);
return _ref; return UserItemView.__super__.constructor.apply(this, arguments);
} }
UserItemView.prototype.template = _.template(Template); UserItemView.prototype.template = _.template(Template);
UserItemView.prototype.tagName = "tr"; UserItemView.prototype.tagName = "tr";
UserItemView.prototype.events = {
"click #follow-button": "followUser",
"click #follow-button-login": "promptLogin"
};
UserItemView.prototype.templateHelpers = { UserItemView.prototype.templateHelpers = {
humanise: function(date) { humanise: function(date) {
return moment(date).fromNow(); return moment(date).fromNow();
} }
}; };
UserItemView.prototype.intialize = function() {
return this.listenTo(this.model, 'change:profile.following', this.render);
};
UserItemView.prototype.followUser = function() {
console.log("UserItemView: followUser");
return vent.trigger("user:follow", this.model);
};
UserItemView.prototype.promptLogin = function() {
return vent.trigger("app:login", this.model);
};
return UserItemView; return UserItemView;
})(Marionette.ItemView); })(Marionette.ItemView);
return UserItemView;
}); });
}).call(this); }).call(this);

View File

@@ -31,7 +31,7 @@ define ["underscore", "marionette", "vent", "utils", "views/widgets/searchView",
@searchRegion.show(new SearchView()) @searchRegion.show(new SearchView())
login: -> login: ->
utils.modal "/dlg/LoginView" vent.trigger('app:login')
logout: -> logout: ->
utils.showAlert "Success", "You are now logged out" utils.showAlert "Success", "You are now logged out"

View File

@@ -52,7 +52,7 @@ Code provided under the BSD License:
}; };
HeaderView.prototype.login = function() { HeaderView.prototype.login = function() {
return utils.modal("/dlg/LoginView"); return vent.trigger('app:login');
}; };
HeaderView.prototype.logout = function() { HeaderView.prototype.logout = function() {

View File

@@ -0,0 +1 @@
<h1>User has not uploaded any mixes</h1>

View File

@@ -16,3 +16,19 @@
<td><%= profile.following_count %></td> <td><%= profile.following_count %></td>
<td><%= humanise(date_joined) %></td> <td><%= humanise(date_joined) %></td>
<td><%= humanise(last_login) %></td> <td><%= humanise(last_login) %></td>
<td>
{% if user.is_authenticated %}
<button href="#"
id="follow-button"
class="follow-button btn btn-mini <% if (profile.following) { %> disabled <% } %>">
<i id="follow-icon" class="icon-eye-close"></i>Follow
</button>
{% else %}
<button href="#"
id="follow-button-login"
class="follow-button btn btn-mini <% if (profile.following) { %> disabled <% } %>">
<i id="follow-icon" class="icon-eye-close"></i>Follow
</button>
{% endif %}
</td>

View File

@@ -23,6 +23,7 @@
<th>Following</th> <th>Following</th>
<th>Join date</th> <th>Join date</th>
<th>Last seen</th> <th>Last seen</th>
<th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>