diff --git a/spa/api/v1/MixResource.py b/spa/api/v1/MixResource.py index 1c73413..570b354 100644 --- a/spa/api/v1/MixResource.py +++ b/spa/api/v1/MixResource.py @@ -1,5 +1,6 @@ from django.conf.urls import url from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Count from django.template.loader import render_to_string from tastypie import fields from tastypie.authorization import Authorization @@ -102,15 +103,28 @@ class MixResource(BackboneCompatibleResource): self._unpackGenreList(ret, bundle.data['genre-list']) return ret - def obj_get_list(self, bundle, **kwargs): - if 'user' in bundle.request.GET and bundle.request.GET['user']: - user = bundle.request.GET['user'] - return Mix.get_for_username(user) - elif 'type' in bundle.request.GET and bundle.request.GET['type']: - type = bundle.request.GET['type'] - return Mix.get_listing(type, bundle.request.user) + def apply_sorting(self, obj_list, options=None): + orderby = options.get('order_by', '') + if orderby == 'latest': + obj_list = obj_list.order_by('-id') + elif orderby == 'toprated': + obj_list = obj_list.annotate(karma=Count('likes')).order_by('-karma') + elif orderby == 'mostplayed': + obj_list = obj_list.annotate(karma=Count('plays')).order_by('-karma') + elif orderby == 'mostactive': + obj_list = obj_list.annotate(karma=Count('comments')).order_by('-karma') + elif orderby == 'recommended': + obj_list = obj_list.annotate(karma=Count('likes')) .order_by('-karma') - return Mix.get_listing('latest', bundle.request.user) + return obj_list + + def apply_filters(self, request, applicable_filters): + semi_filtered = super(MixResource, self).apply_filters(request, applicable_filters) + type = request.GET.get('type', None) + if type == 'favourites': + semi_filtered = semi_filtered.filter(favourites__mix__in=semi_filtered) + + return semi_filtered def hydrate_favourited(self, bundle): return bundle @@ -128,6 +142,7 @@ class MixResource(BackboneCompatibleResource): bundle.data['play_count'] = bundle.obj.plays.count() bundle.data['download_count'] = bundle.obj.downloads.count() bundle.data['like_count'] = bundle.obj.likes.count() + bundle.data['favourite_count'] = bundle.obj.favourites.count() bundle.data['tooltip'] = render_to_string('inc/player_tooltip.html', {'item': bundle.obj}) bundle.data['comment_count'] = bundle.obj.comments.count() diff --git a/spa/api/v1/UserResource.py b/spa/api/v1/UserResource.py index 79a9e24..2ceaa9a 100644 --- a/spa/api/v1/UserResource.py +++ b/spa/api/v1/UserResource.py @@ -6,6 +6,7 @@ from tastypie.authorization import DjangoAuthorization from django.conf.urls import url from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource +from spa.api.v1.MixResource import MixResource from spa.models import UserProfile, Mix @@ -77,6 +78,8 @@ class UserProfileResource(BackboneCompatibleResource): UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER) bundle.data['mix_count'] = Mix.objects.filter(user=bundle.obj).count() + bundle.data['like_count'] = bundle.obj.likes.count() + bundle.data['favourite_count'] = bundle.obj.favourites.count() bundle.data['follower_count'] = bundle.obj.followers.count() bundle.data['following_count'] = bundle.obj.following.count() bundle.data['following'] = bundle.obj.is_follower(bundle.request.user) @@ -95,12 +98,23 @@ class UserResource(BackboneCompatibleResource): def prepend_urls(self): return [ - url(r"^(?P%s)/(?P\d+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), - name="api_dispatch_detail"), + url(r"^(?P%s)/(?P[\w\d_.-]+)/favourites/$" % self._meta.resource_name, + self.wrap_view('get_user_favourites'), name="api_get_user_favourites"), + url(r"^(?P%s)/(?P\d+)/$" % self._meta.resource_name, + self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), url(r"^(?P%s)/(?P[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), ] + def get_user_favourites(self, request, **kwargs): + try: + basic_bundle = self.build_bundle(request=request) + user = self.cached_obj_get(bundle=basic_bundle, **self.remove_api_resource_names(kwargs)) + mixes = MixResource() + return mixes.get_object_list(request).filter() + except Exception, ex: + self.logger.error("Error getting user favourites: %s" % ex.message) + def dehydrate(self, bundle): if bundle.obj.id != bundle.request.user.id: del bundle.data['email'] diff --git a/spa/migrations/0018_auto__chg_field_mixlike_user.py b/spa/migrations/0018_auto__chg_field_mixlike_user.py new file mode 100644 index 0000000..08ca31a --- /dev/null +++ b/spa/migrations/0018_auto__chg_field_mixlike_user.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Changing field 'MixLike.user' + db.alter_column(u'spa_mixlike', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.UserProfile'])) + + def backwards(self, orm): + + # Changing field 'MixLike.user' + db.alter_column(u'spa_mixlike', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])) + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'spa._activity': { + 'Meta': {'object_name': '_Activity'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity'", 'null': 'True', 'to': u"orm['auth.User']"}) + }, + 'spa._lookup': { + 'Meta': {'object_name': '_Lookup'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'spa.chatmessage': { + 'Meta': {'object_name': 'ChatMessage'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) + }, + 'spa.comment': { + 'Meta': {'object_name': 'Comment'}, + 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['spa.Mix']"}), + 'time_index': ('django.db.models.fields.IntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + 'spa.event': { + 'Meta': {'object_name': 'Event'}, + 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'event_description': ('tinymce.models.HTMLField', [], {}), + 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), + 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), + 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'spa.genre': { + 'Meta': {'object_name': 'Genre'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) + }, + 'spa.label': { + 'Meta': {'object_name': 'Label'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'spa.mix': { + 'Meta': {'object_name': 'Mix'}, + 'description': ('django.db.models.fields.TextField', [], {}), + 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}), + 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), + 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), + 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'spa.mixdownload': { + 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, + u'_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) + }, + 'spa.mixfavourite': { + 'Meta': {'object_name': 'MixFavourite'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': u"orm['auth.User']"}) + }, + 'spa.mixlike': { + 'Meta': {'object_name': 'MixLike'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.UserProfile']"}) + }, + 'spa.mixplay': { + 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, + u'_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) + }, + 'spa.purchaselink': { + 'Meta': {'object_name': 'PurchaseLink'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'spa.recurrence': { + 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, + u'_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'spa.release': { + 'Meta': {'object_name': 'Release'}, + 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'release_description': ('django.db.models.fields.TextField', [], {}), + 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), + 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) + }, + 'spa.releaseaudio': { + 'Meta': {'object_name': 'ReleaseAudio'}, + 'description': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) + }, + 'spa.tracklist': { + 'Meta': {'object_name': 'Tracklist'}, + 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index': ('django.db.models.fields.SmallIntegerField', [], {}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), + 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'spa.userprofile': { + 'Meta': {'object_name': 'UserProfile'}, + 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), + 'followers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'followers_rel_+'", 'null': 'True', 'to': "orm['spa.UserProfile']"}), + 'following': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'following_rel_+'", 'null': 'True', 'to': "orm['spa.UserProfile']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'default': 'None', 'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + 'spa.venue': { + 'Meta': {'object_name': 'Venue'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) + } + } + + complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0019_auto__chg_field_mixfavourite_user.py b/spa/migrations/0019_auto__chg_field_mixfavourite_user.py new file mode 100644 index 0000000..f98de29 --- /dev/null +++ b/spa/migrations/0019_auto__chg_field_mixfavourite_user.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Changing field 'MixFavourite.user' + db.alter_column(u'spa_mixfavourite', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.UserProfile'])) + + def backwards(self, orm): + + # Changing field 'MixFavourite.user' + db.alter_column(u'spa_mixfavourite', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])) + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'spa._activity': { + 'Meta': {'object_name': '_Activity'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity'", 'null': 'True', 'to': u"orm['auth.User']"}) + }, + 'spa._lookup': { + 'Meta': {'object_name': '_Lookup'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'spa.chatmessage': { + 'Meta': {'object_name': 'ChatMessage'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) + }, + 'spa.comment': { + 'Meta': {'object_name': 'Comment'}, + 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['spa.Mix']"}), + 'time_index': ('django.db.models.fields.IntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + 'spa.event': { + 'Meta': {'object_name': 'Event'}, + 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'event_description': ('tinymce.models.HTMLField', [], {}), + 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), + 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), + 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'spa.genre': { + 'Meta': {'object_name': 'Genre'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) + }, + 'spa.label': { + 'Meta': {'object_name': 'Label'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'spa.mix': { + 'Meta': {'object_name': 'Mix'}, + 'description': ('django.db.models.fields.TextField', [], {}), + 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}), + 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), + 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), + 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'spa.mixdownload': { + 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, + u'_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) + }, + 'spa.mixfavourite': { + 'Meta': {'object_name': 'MixFavourite'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.UserProfile']"}) + }, + 'spa.mixlike': { + 'Meta': {'object_name': 'MixLike'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.UserProfile']"}) + }, + 'spa.mixplay': { + 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, + u'_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) + }, + 'spa.purchaselink': { + 'Meta': {'object_name': 'PurchaseLink'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'spa.recurrence': { + 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, + u'_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'spa.release': { + 'Meta': {'object_name': 'Release'}, + 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 5, 26, 0, 0)'}), + 'release_description': ('django.db.models.fields.TextField', [], {}), + 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), + 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) + }, + 'spa.releaseaudio': { + 'Meta': {'object_name': 'ReleaseAudio'}, + 'description': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) + }, + 'spa.tracklist': { + 'Meta': {'object_name': 'Tracklist'}, + 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index': ('django.db.models.fields.SmallIntegerField', [], {}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), + 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'spa.userprofile': { + 'Meta': {'object_name': 'UserProfile'}, + 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), + 'followers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'followers_rel_+'", 'null': 'True', 'to': "orm['spa.UserProfile']"}), + 'following': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'following_rel_+'", 'null': 'True', 'to': "orm['spa.UserProfile']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'default': 'None', 'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + 'spa.venue': { + 'Meta': {'object_name': 'Venue'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) + } + } + + complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/models/_basemodel.py b/spa/models/_basemodel.py index eaebb8f..a905296 100644 --- a/spa/models/_basemodel.py +++ b/spa/models/_basemodel.py @@ -1,16 +1,12 @@ import logging import os - from django.db import models from django.utils import simplejson - from core.utils import url from dss import localsettings, settings -from immutablefield.models import ImmutableModel - -class _BaseModel(ImmutableModel): +class _BaseModel(models.Model): logger = logging.getLogger(__name__) class Meta: diff --git a/spa/models/mix.py b/spa/models/mix.py index c690fb9..09507d7 100644 --- a/spa/models/mix.py +++ b/spa/models/mix.py @@ -2,12 +2,10 @@ import os import rfc822 from datetime import datetime import urlparse - from sorl.thumbnail import get_thumbnail from django.contrib.sites.models import Site from django.db import models from django.db.models import Count - from core.utils import url from core.utils.audio.mp3 import mp3_length from core.utils.url import unique_slugify @@ -20,7 +18,7 @@ from spa.models.userprofile import UserProfile from spa.models._basemodel import _BaseModel from spa.models.mixfavourite import MixFavourite from core.utils.file import generate_save_file_name -from immutablefield.models import ImmutableModel + def mix_file_name(instance, filename): return generate_save_file_name(instance.uid, 'mixes', filename) @@ -31,6 +29,10 @@ def mix_image_name(instance, filename): return ret +class MixManager(models.Manager): + pass + + class Mix(_BaseModel): class Meta: app_label = 'spa' @@ -59,7 +61,7 @@ class Mix(_BaseModel): def __unicode__(self): return self.title - def save(self, force_insert=False, force_update=False, using=None): + def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if not self.id: self.slug = unique_slugify(self, self.title) @@ -68,7 +70,7 @@ class Mix(_BaseModel): self.waveform_generated = True self.duration = mp3_length(self.get_absolute_path()) - super(Mix, self).save(force_insert, force_update, using) + super(Mix, self).save(force_insert, force_update, using, update_fields) def get_absolute_path(self, prefix=""): fileName, extension = os.path.splitext(self.local_file.name) @@ -126,23 +128,28 @@ class Mix(_BaseModel): rfc822.mktime_tz(rfc822.parsedate_tz(self.upload_date.strftime("%a, %d %b %Y %H:%M:%S")))) @classmethod - def get_for_username(cls, user): - queryset = Mix.objects \ + def get_for_username(cls, user, queryset=None): + if queryset is None: + queryset = Mix.objects + + return queryset \ .filter(user__slug__exact=user) \ .filter(waveform_generated=True) \ .order_by('-id') - return queryset @classmethod - def get_listing(cls, listing_type, user=None): - queryset = None - candidates = Mix.objects \ + def get_listing(cls, listing_type, user=None, queryset=None): + candidates = queryset or Mix.objects \ .filter(waveform_generated=True) \ .filter(is_featured=True) \ .exclude(duration__isnull=True) if listing_type == 'latest': queryset = candidates.order_by('-id') + elif listing_type == 'likes': + queryset = candidates.annotate(karma=Count('likes')).order_by('-karma') + elif listing_type == 'favourites': + queryset = candidates.annotate(karma=Count('likes')).order_by('-karma') elif listing_type == 'toprated': queryset = candidates.annotate(karma=Count('likes')).order_by('-karma') elif listing_type == 'mostactive': @@ -200,7 +207,7 @@ class Mix(_BaseModel): if user.is_authenticated(): if value: if self.favourites.filter(user=user).count() == 0: - self.favourites.add(MixFavourite(mix=self, user=user)) + self.favourites.add(MixFavourite(mix=self, user=user.get_profile())) else: self.favourites.filter(user=user).delete() except Exception, ex: @@ -213,7 +220,7 @@ class Mix(_BaseModel): if user.is_authenticated(): if value: if self.likes.filter(user=user).count() == 0: - self.likes.add(MixLike(mix=self, user=user)) + self.likes.add(MixLike(mix=self, user=user.get_profile())) else: self.likes.filter(user=user).delete() except Exception, ex: diff --git a/spa/models/mixfavourite.py b/spa/models/mixfavourite.py index fd56d1a..3b6cb05 100644 --- a/spa/models/mixfavourite.py +++ b/spa/models/mixfavourite.py @@ -1,10 +1,10 @@ -from django.contrib.auth.models import User +from spa.models.userprofile import UserProfile from spa.models._basemodel import _BaseModel from django.db import models class MixFavourite(_BaseModel): mix = models.ForeignKey('spa.Mix', related_name='favourites') - user = models.ForeignKey(User, related_name='favourites') + user = models.ForeignKey(UserProfile, related_name='favourites') date = models.DateTimeField(auto_now=True) diff --git a/spa/models/mixlike.py b/spa/models/mixlike.py index 2edfd83..2888c32 100644 --- a/spa/models/mixlike.py +++ b/spa/models/mixlike.py @@ -1,9 +1,9 @@ -from django.contrib.auth.models import User from django.db import models +from spa.models.userprofile import UserProfile from spa.models._basemodel import _BaseModel class MixLike(_BaseModel): mix = models.ForeignKey('spa.Mix', related_name='likes') - user = models.ForeignKey(User, related_name='likes') + user = models.ForeignKey(UserProfile, related_name='likes') date = models.DateTimeField(auto_now=True) diff --git a/static/css/deepsouthsounds.css b/static/css/deepsouthsounds.css index 889f62d..5879cd4 100644 --- a/static/css/deepsouthsounds.css +++ b/static/css/deepsouthsounds.css @@ -8,9 +8,6 @@ Code provided under the BSD License: */ -* { - font-family: 'Open Sans', sans-serif; -} body { font-size: 14px; diff --git a/static/js/app/appv2.js b/static/js/app/appv2.js index 964c18c..e62d1dc 100644 --- a/static/js/app/appv2.js +++ b/static/js/app/appv2.js @@ -1,8 +1,8 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { - define(['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'views/header', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, DssRouter, PanningRegion, HeaderView, SidebarView, MixCollection) { var App, sidebarView; + Marionette.Region.prototype.open = function(view) { this.$el.hide(); this.$el.html(view.el); @@ -35,6 +35,7 @@ }); App.vent.on("routing:started", function() { var enablePushState, pushState; + console.log("App(vent): routing:started"); enablePushState = true; pushState = !!(enablePushState && window.history && window.history.pushState); @@ -60,6 +61,7 @@ console.log("App: gobbling links"); $(document).on("click", "a[href]:not([data-bypass])", function(evt) { var href, root; + href = { prop: $(this).prop("href"), attr: $(this).attr("href") diff --git a/static/js/app/lib/controller.coffee b/static/js/app/lib/controller.coffee index 5dbc313..830a4d3 100644 --- a/static/js/app/lib/controller.coffee +++ b/static/js/app/lib/controller.coffee @@ -8,12 +8,14 @@ define ['app', 'marionette', @showMixList() true - showMixList: (type, options) -> - console.log "Controller: showMixList" - type = type or "latest" + _showMixList: (options) -> + console.log "Controller: _showMixList" app = require('app') + app.contentRegion.show(new MixListView(options)) + true - app.contentRegion.show(new MixListView($.extend({type: type}, options)), 'drop'); + showMixList: (type) -> + @_showMixList({order_by: type || 'latest'}) true showMix: (slug)-> @@ -54,10 +56,25 @@ define ['app', 'marionette', app = require('app') app.contentRegion.show(new UserListView()) - showUserDetail: (slug) -> console.log("Controller: showUserDetail") - @showMixList('latest', {user: slug}) + @_showMixList({order_by: 'latest', user: slug}) + + showUserFavourites: (slug) -> + console.log("Controller: showUserFavourites") + @_showMixList({order_by: 'latest', type: 'favourites', user: slug}) + + showUserLikes: (slug) -> + console.log("Controller: showUserLikes") + @_showMixList({order_by: 'latest', type: 'likes', user: slug}) + + showUserFollowing: (slug) -> + console.log("Controller: showUserFollowing") + @_showMixList({order_by: 'latest', type: 'following', user: slug}) + + showUserFollowers: (slug) -> + console.log("Controller: showUserFollowers") + @_showMixList({order_by: 'latest', type: 'followers', user: slug}) editUser: () -> console.log("Controller: editUser") diff --git a/static/js/app/lib/controller.js b/static/js/app/lib/controller.js index ff9e990..b6fa7b9 100644 --- a/static/js/app/lib/controller.js +++ b/static/js/app/lib/controller.js @@ -1,16 +1,17 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __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; }; define(['app', 'marionette', 'models/mix/mixItem', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView', 'models/user/userItem', 'views/user/userListView', 'views/user/userEditView'], function(App, Marionette, MixItem, MixListView, MixDetailView, MixEditView, UserItem, UserListView, UserEditView) { - var DssController; - DssController = (function(_super) { + var DssController, _ref; + DssController = (function(_super) { __extends(DssController, _super); function DssController() { - return DssController.__super__.constructor.apply(this, arguments); + _ref = DssController.__super__.constructor.apply(this, arguments); + return _ref; } DssController.prototype.home = function() { @@ -19,19 +20,25 @@ return true; }; - DssController.prototype.showMixList = function(type, options) { + DssController.prototype._showMixList = function(options) { var app; - console.log("Controller: showMixList"); - type = type || "latest"; + + console.log("Controller: _showMixList"); app = require('app'); - app.contentRegion.show(new MixListView($.extend({ - type: type - }, options)), 'drop'); + app.contentRegion.show(new MixListView(options)); + return true; + }; + + DssController.prototype.showMixList = function(type) { + this._showMixList({ + order_by: type || 'latest' + }); return true; }; DssController.prototype.showMix = function(slug) { var app, mix; + console.log("Controller: showMix"); app = require('app'); mix = new MixItem({ @@ -50,6 +57,7 @@ DssController.prototype.uploadMix = function() { var app, mix; + console.log("Controller: mixUpload"); app = require('app'); mix = new MixItem({ @@ -66,6 +74,7 @@ DssController.prototype.editMix = function(slug) { var app, mix; + console.log("Controller: mixEdit"); app = require('app'); mix = new MixItem({ @@ -83,6 +92,7 @@ DssController.prototype.showUserList = function(type) { var app; + console.log("Controller: showUserList"); app = require('app'); return app.contentRegion.show(new UserListView()); @@ -90,13 +100,51 @@ DssController.prototype.showUserDetail = function(slug) { console.log("Controller: showUserDetail"); - return this.showMixList('latest', { + return this._showMixList({ + order_by: 'latest', + user: slug + }); + }; + + DssController.prototype.showUserFavourites = function(slug) { + console.log("Controller: showUserFavourites"); + return this._showMixList({ + order_by: 'latest', + type: 'favourites', + user: slug + }); + }; + + DssController.prototype.showUserLikes = function(slug) { + console.log("Controller: showUserLikes"); + return this._showMixList({ + order_by: 'latest', + type: 'likes', + user: slug + }); + }; + + DssController.prototype.showUserFollowing = function(slug) { + console.log("Controller: showUserFollowing"); + return this._showMixList({ + order_by: 'latest', + type: 'following', + user: slug + }); + }; + + DssController.prototype.showUserFollowers = function(slug) { + console.log("Controller: showUserFollowers"); + return this._showMixList({ + order_by: 'latest', + type: 'followers', user: slug }); }; DssController.prototype.editUser = function() { var app, user; + console.log("Controller: editUser"); app = require('app'); user = new UserItem({ diff --git a/static/js/app/lib/editableView.js b/static/js/app/lib/editableView.js index 851f828..06bfc94 100644 --- a/static/js/app/lib/editableView.js +++ b/static/js/app/lib/editableView.js @@ -1,16 +1,17 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __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; }; define(["marionette"], function(Marionette) { - var EditableView; - EditableView = (function(_super) { + var EditableView, _ref; + EditableView = (function(_super) { __extends(EditableView, _super); function EditableView() { - return EditableView.__super__.constructor.apply(this, arguments); + _ref = EditableView.__super__.constructor.apply(this, arguments); + return _ref; } EditableView.prototype.events = { @@ -26,6 +27,7 @@ EditableView.prototype.changeSelect = function(evt) { var changed, obj, objInst, value; + changed = evt.currentTarget; if (id) { value = $(evt.currentTarget).val(); @@ -37,6 +39,7 @@ EditableView.prototype.changed = function(evt) { var changed, obj, objInst, value; + return; changed = evt.currentTarget; if (changed.id) { @@ -56,6 +59,7 @@ EditableView.prototype._bakeForm = function(el, lookups) { var labels, mapped, model; + model = this.model; labels = void 0; mapped = void 0; @@ -108,6 +112,7 @@ EditableView.prototype._saveChanges = function() { var args, error, _results; + args = arguments; if (!this.model.isValid()) { if (this.model.errors) { diff --git a/static/js/app/lib/router.coffee b/static/js/app/lib/router.coffee index ebd6ef8..9170ae8 100644 --- a/static/js/app/lib/router.coffee +++ b/static/js/app/lib/router.coffee @@ -13,6 +13,10 @@ define ['marionette', 'app.lib/controller'], "mix/edit/:slug": "editMix", "users": "showUserList" + "user/:slug/favourites": "showUserFavourites" + "user/:slug/likes": "showUserLikes" + "user/:slug/followers": "showUserFollowers" + "user/:slug/following": "showUserFollowing" "user/:slug": "showUserDetail" "me": "editUser" diff --git a/static/js/app/lib/router.js b/static/js/app/lib/router.js index 5ca2cc8..3134049 100644 --- a/static/js/app/lib/router.js +++ b/static/js/app/lib/router.js @@ -1,16 +1,17 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __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; }; define(['marionette', 'app.lib/controller'], function(Marionette, Controller) { - var DssRouter; - return DssRouter = (function(_super) { + var DssRouter, _ref; + return DssRouter = (function(_super) { __extends(DssRouter, _super); function DssRouter() { - return DssRouter.__super__.constructor.apply(this, arguments); + _ref = DssRouter.__super__.constructor.apply(this, arguments); + return _ref; } DssRouter.prototype.controller = new Controller; @@ -24,6 +25,10 @@ "mix/:slug": "showMix", "mix/edit/:slug": "editMix", "users": "showUserList", + "user/:slug/favourites": "showUserFavourites", + "user/:slug/likes": "showUserLikes", + "user/:slug/followers": "showUserFollowers", + "user/:slug/following": "showUserFollowing", "user/:slug": "showUserDetail", "me": "editUser" }; diff --git a/static/js/app/views/user/userListView.coffee b/static/js/app/views/user/userListView.coffee index ea24817..f18d9a9 100644 --- a/static/js/app/views/user/userListView.coffee +++ b/static/js/app/views/user/userListView.coffee @@ -4,7 +4,7 @@ define ['marionette', 'models/user/userCollection', 'views/user/userItemView', ' template: _.template(Template) tagName: "table" - className: "table table-striped" + className: "table table-hover" itemView: UserItemView initialize: -> @@ -14,8 +14,13 @@ define ['marionette', 'models/user/userCollection', 'views/user/userItemView', ' data: @options success: => console.log("UserListView: Collection fetched") + $(@el).tablesorter() return ) return + onRender: -> + console.log("UserListView: onRender") + true + UserListView \ No newline at end of file diff --git a/static/js/app/views/user/userListView.js b/static/js/app/views/user/userListView.js index 1f27650..8ac0fdb 100644 --- a/static/js/app/views/user/userListView.js +++ b/static/js/app/views/user/userListView.js @@ -17,7 +17,7 @@ UserListView.prototype.tagName = "table"; - UserListView.prototype.className = "table table-striped"; + UserListView.prototype.className = "table table-hover"; UserListView.prototype.itemView = UserItemView; @@ -29,10 +29,16 @@ data: this.options, success: function() { console.log("UserListView: Collection fetched"); + $(_this.el).tablesorter(); } }); }; + UserListView.prototype.onRender = function() { + console.log("UserListView: onRender"); + return true; + }; + return UserListView; })(Marionette.CompositeView); diff --git a/templates/base.html b/templates/base.html index 3fc08f8..9759281 100644 --- a/templates/base.html +++ b/templates/base.html @@ -4,7 +4,6 @@ Deep South Sounds {% include 'inc/meta.html' %} - {% load compress %} {% compress css %} @@ -54,6 +53,7 @@ + @@ -74,7 +74,6 @@ - diff --git a/templates/views/UserListItemView.html b/templates/views/UserListItemView.html index f24898f..ec0b6c9 100644 --- a/templates/views/UserListItemView.html +++ b/templates/views/UserListItemView.html @@ -2,6 +2,12 @@ <%= profile.mix_count%> + + <%= profile.like_count%> + + + <%= profile.favourite_count%> + <%= profile.follower_count %> diff --git a/templates/views/UserListView.html b/templates/views/UserListView.html index 90864d7..b5d22c7 100644 --- a/templates/views/UserListView.html +++ b/templates/views/UserListView.html @@ -1,7 +1,9 @@ - + Name Uploads + Likes + Favourites Followers Following Last seen