Slugified mix urls

This commit is contained in:
Fergal Moran
2013-04-23 09:46:04 +01:00
parent a2281ee3dd
commit 34299cb2de
10 changed files with 120 additions and 62 deletions

View File

@@ -28,6 +28,11 @@ class MixResource(BackboneCompatibleResource):
}
authorization = Authorization()
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
def _parseGenreList(self, genres):
#for magic..
ret = []
@@ -113,7 +118,7 @@ class MixResource(BackboneCompatibleResource):
bundle.data['user_name'] = bundle.obj.user.get_nice_name()
bundle.data['user_profile_url'] = bundle.obj.user.get_absolute_url()
bundle.data['user_profile_image'] = bundle.obj.user.get_small_profile_image()
bundle.data['item_url'] = 'mix/%s' % bundle.obj.id
bundle.data['item_url'] = 'mix/%s' % bundle.obj.slug
bundle.data['play_count'] = bundle.obj.plays.count()
bundle.data['download_count'] = bundle.obj.downloads.count()

View File

@@ -1,3 +1,4 @@
from django.conf.urls import url
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from tastypie.constants import ALL, ALL_WITH_RELATIONS
@@ -18,38 +19,48 @@ class UserResource(BackboneCompatibleResource):
'id': ALL,
}
def full_dehydrate(self, bundle, for_list=False):
return super(UserResource, self).full_dehydrate(bundle, for_list)
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
def authorized_read_list(self, object_list, bundle):
return object_list.filter(user_id=bundle.request.user.id)
def authorized_read_detail(self, object_list, bundle):
return object_list.only('description')
def dehydrate(self, bundle):
bundle.data['display_name'] = bundle.obj.display_name
#set the "me" user only properties
if bundle.obj.id == bundle.request.user.id:
bundle.data['email'] = bundle.obj.email
if bundle.obj.activity_sharing is not None:
bundle.data['activity_share_likes'] = \
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_LIKES) != 0
bundle.data['activity_share_favourites'] = \
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_FAVOURITES) != 0
bundle.data['activity_share_comments'] = \
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_COMMENTS) != 0
else:
bundle.data['activity_share_likes'] = 0
bundle.data['activity_share_favourites'] = 0
bundle.data['activity_share_comments'] = 0
if bundle.obj.activity_sharing_networks is not None:
bundle.data['activity_share_networks_facebook'] = \
(bundle.obj.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK) != 0
bundle.data['activity_share_networks_twitter'] = \
(bundle.obj.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER) != 0
else:
bundle.data['activity_share_networks_facebook'] = 0
bundle.data['activity_share_networks_facebook'] = 0
else:
del bundle.data['activity_sharing']
del bundle.data['activity_sharing_networks']
bundle.data['first_name'] = bundle.obj.first_name
bundle.data['last_name'] = bundle.obj.last_name
bundle.data['email'] = bundle.obj.email
if bundle.obj.activity_sharing is not None:
bundle.data['activity_share_likes'] = \
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_LIKES) != 0
bundle.data['activity_share_favourites'] = \
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_FAVOURITES) != 0
bundle.data['activity_share_comments'] = \
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_COMMENTS) != 0
else:
bundle.data['activity_share_likes'] = 0
bundle.data['activity_share_favourites'] = 0
bundle.data['activity_share_comments'] = 0
if bundle.obj.activity_sharing_networks is not None:
bundle.data['activity_share_networks_facebook'] = \
(bundle.obj.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK) != 0
bundle.data['activity_share_networks_twitter'] = \
(bundle.obj.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER) != 0
else:
bundle.data['activity_share_networks_facebook'] = 0
bundle.data['activity_share_networks_facebook'] = 0
return bundle

View File

@@ -1,26 +1,30 @@
import os
from django.core.management.base import NoArgsCommand, CommandError
from core.utils.audio import Mp3FileNotFoundException
from core.utils.audio.mp3 import mp3_length
from dss import settings
from spa.models import Mix
class Command(NoArgsCommand):
help = "Updates audio files with their durations"
def handle(self, *args, **options):
try:
candidates = Mix.objects.filter(duration__isnull=True)
for mix in candidates:
try:
print "Finding duration for: %s" % mix.title
length = mp3_length(mix.get_absolute_path())
print "\tLength: %d" % length
mix.duration = length
mix.save()
except Mp3FileNotFoundException, me:
mix.delete()
print me.message
except Exception, ex:
from django.core.management.base import NoArgsCommand, CommandError
from django.template.defaultfilters import slugify
from core.utils.audio import Mp3FileNotFoundException
from core.utils.audio.mp3 import mp3_length
from spa.models import Mix
class Command(NoArgsCommand):
help = "Updates audio files with their durations"
def handle(self, *args, **options):
try:
candidates = Mix.objects.all()
for mix in candidates:
try:
if mix.duration is None:
print "Finding duration for: %s" % mix.title
length = mp3_length(mix.get_absolute_path())
print "\tLength: %d" % length
mix.duration = length
if mix.slug == 'Invalid':
print "Slugifying mix: %s" % mix.title
mix.slug = slugify(mix.title)
print "\tNew title: %s" % mix.slug
mix.save()
except Mp3FileNotFoundException, me:
mix.delete()
print me.message
except Exception, ex:
raise CommandError(ex.message)

View File

@@ -2,6 +2,7 @@ import os
import rfc822
from datetime import datetime
import urlparse
from django.template.defaultfilters import slugify
from sorl.thumbnail import get_thumbnail
from django.contrib.sites.models import Site
@@ -45,6 +46,7 @@ class Mix(_BaseModel):
uid = models.CharField(max_length=38, blank=True, unique=True)
download_allowed = models.BooleanField(default=False)
duration = models.IntegerField(null=True, blank=True)
slug = models.SlugField()
genres = models.ManyToManyField(Genre)
@@ -52,6 +54,10 @@ class Mix(_BaseModel):
return self.title
def save(self, force_insert=False, force_update=False, using=None):
if not self.id:
self.slug = slugify(self.title)
#TODO
#turn away now - horrid hack to strip media root url
#from image - will sort when I've figured backbone out better
if self.mix_image.name.startswith(settings.MEDIA_URL):
@@ -71,7 +77,7 @@ class Mix(_BaseModel):
return '%s/mixes/%s%s%s' % (settings.MEDIA_ROOT, prefix, self.uid, extension)
def get_absolute_url(self):
return '/mix/%i' % self.id
return '/mix/%s' % self.slug
def get_full_url(self):
return 'http://%s%s' % (Site.objects.get_current().domain, self.get_absolute_url())

View File

@@ -37,7 +37,7 @@ class UserProfile(_BaseModel):
display_name = models.CharField(blank=True, max_length=35)
description = models.CharField(blank=True, max_length=2048)
slug = models.CharField(max_length=35, blank=True, null=True, default=None)
slug = models.SlugField(max_length=50, blank=True, null=True, default=None)
activity_sharing = models.IntegerField(default=0)
activity_sharing_networks = models.IntegerField(default=0)

View File

@@ -54,9 +54,23 @@ var AppRouter = Backbone.Router.extend({
},
user: function (user) {
this._renderMixList('latest', { "user": user });
var model = new User({
id: user
});
this.sidebarView = new SidebarViewUser({
model: model
});
$('#sidebar').html(this.sidebarView.el);
},
mixList: function (type) {
this._renderMixList(type);
this.sidebarView = new SidebarView();
$('#sidebar').html(this.sidebarView.el);
startChat(
$('#chat-messages-body', this.sidebarView.el),
$('#input', this.sidebarView.el),
$('#status', this.sidebarView.el),
$('#header-profile-edit').text());
},
_renderMixList: function (type, data) {
var mixList = new MixCollection();
@@ -77,13 +91,6 @@ var AppRouter = Backbone.Router.extend({
}
}
});
this.sidebarView = new SidebarView();
$('#sidebar').html(this.sidebarView.el);
startChat(
$('#chat-messages-body', this.sidebarView.el),
$('#input', this.sidebarView.el),
$('#status', this.sidebarView.el),
$('#header-profile-edit').text());
},
mixDetails: function (id) {
var mix = new Mix({
@@ -227,7 +234,7 @@ var AppRouter = Backbone.Router.extend({
}
});
com.podnoms.utils.loadTemplate(['HeaderView', 'SidebarView', 'UserView', 'MixListView', 'MixListItemView', 'MixView', 'MixCreateView', 'CommentListView', 'CommentListItemView', 'ActivityListView', 'ActivityListItemView', 'ReleaseListView', 'ReleaseListItemView', 'ReleaseItemView', 'ReleaseView', 'ReleaseCreateView', 'ReleaseAudioListView', 'ReleaseAudioItemView', 'EventCreateView', 'EventListView', 'EventListItemView', 'EventView', 'EventItemView'], function () {
com.podnoms.utils.loadTemplate(['HeaderView', 'SidebarView', 'SidebarViewUser', 'UserView', 'MixListView', 'MixListItemView', 'MixView', 'MixCreateView', 'CommentListView', 'CommentListItemView', 'ActivityListView', 'ActivityListItemView', 'ReleaseListView', 'ReleaseListItemView', 'ReleaseItemView', 'ReleaseView', 'ReleaseCreateView', 'ReleaseAudioListView', 'ReleaseAudioItemView', 'EventCreateView', 'EventListView', 'EventListItemView', 'EventView', 'EventItemView'], function () {
window.app = new AppRouter();
// Trigger the initial route and enable HTML5 History API support, set the
// root folder to '/' by default. Change in app.js.

View File

@@ -213,7 +213,7 @@ window.MixView = Backbone.View.extend({
*/
var comments = new CommentCollection();
comments.url = com.podnoms.settings.urlRoot + this.model.get("item_url") + "/comments/";
comments.url = this.model.get("resource_uri") + "comments/";
comments.mix_id = this.model.id;
comments.mix = this.model.get("resource_uri");
comments.fetch({success: function (data) {

View File

@@ -0,0 +1,20 @@
/** @license
----------------------------------------------
Copyright (c) 2012, Fergal Moran. All rights reserved.
Code provided under the BSD License:
*/
window.SidebarViewUser = Backbone.View.extend({
events: {
},
initialize: function () {
this.render();
},
render: function () {
$(this.el).html(this.template({"item":this.model.toJSON()}));
return this;
}
});

View File

@@ -90,6 +90,7 @@
<script src="{{ STATIC_URL }}js/app/models/event.js"></script>
<script src="{{ STATIC_URL }}js/app/views/header.js"></script>
<script src="{{ STATIC_URL }}js/app/views/sidebar.js"></script>
<script src="{{ STATIC_URL }}js/app/views/sidebaruser.js"></script>
<script src="{{ STATIC_URL }}js/app/views/mix.js"></script>
<script src="{{ STATIC_URL }}js/app/views/user.js"></script>
<script src="{{ STATIC_URL }}js/app/views/comment.js"></script>

View File

@@ -0,0 +1,4 @@
<div>
<h1>Hello Sailor</h1>
<%= item.display_name %>
</div>