Added activity to main feed

This commit is contained in:
Fergal Moran
2013-02-07 19:03:09 +00:00
parent 38f20505eb
commit c6130e002e
15 changed files with 1701 additions and 192 deletions

View File

@@ -228,6 +228,8 @@ PIPELINE_CSS = {
}
INTERNAL_IPS = ('127.0.0.1', '86.44.166.21')
GOOGLE_ANALYTICS_CODE = localsettings.GOOGLE_ANALYTICS_CODE
#TASTYPIE_DATETIME_FORMATTING = 'iso-8601'
TASTYPIE_DATETIME_FORMATTING = 'rfc-2822'
SENDFILE_BACKEND = localsettings.SENDFILE_BACKEND
SENDFILE_ROOT = os.path.join(MEDIA_ROOT, 'mixes')

View File

@@ -5,9 +5,9 @@ from spa.models._Activity import _Activity
class ActivityResource(BackboneCompatibleResource):
class Meta:
queryset = _Activity.objects.all()
#queryset = _Activity.objects.filter(pk=3442).order_by('-date')
queryset = _Activity.objects.all().order_by('-date')
resource_name = 'activity'
authorization = Authorization()
authentication = Authentication()
@@ -18,13 +18,14 @@ class ActivityResource(BackboneCompatibleResource):
def dehydrate(self, bundle):
try:
if bundle.obj.user is not None:
bundle.data["message"] = "%s %s a %s on %s" %\
(bundle.obj.user.get_full_name(),
bundle.obj.get_verb_passed(),
bundle.obj.get_object_singular(),
bundle.obj.date)
return bundle
bundle.data["verb"] = bundle.obj.get_verb_passed(),
bundle.data["object"] = bundle.obj.get_object_singular(),
bundle.data["item_name"] = bundle.obj.get_object_name(),
bundle.data["item_url"] = bundle.obj.get_object_url(),
bundle.data["user_name"] = bundle.obj.user.get_full_name(),
bundle.data["user_profile"] = bundle.obj.user.get_profile().get_profile_url(),
bundle.data["user_image"] = bundle.obj.user.get_profile().get_small_profile_image()
return bundle
except AttributeError, ae:
self.logger.debug("AttributeError: Error dehydrating activity, %s" % ae.message)
@@ -32,3 +33,10 @@ class ActivityResource(BackboneCompatibleResource):
self.logger.debug("TypeError: Error dehydrating activity, %s" % te.message)
except Exception, ee:
self.logger.debug("Exception: Error dehydrating activity, %s" % ee.message)
return None
def alter_list_data_to_serialize(self, request, data):
return [i for i in data['objects'] if i is not None and i.obj.user is not None and i.obj.get_object_name is not None and i.obj.get_object_url is not None]
def dehydrate_date(self, bundle):
return self.humanize_date(bundle.obj.date)

View File

@@ -1,12 +1,15 @@
import logging
from django.conf.urls import url
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from tastypie import fields
from tastypie.http import HttpGone, HttpMultipleChoices
import datetime
import humanize
from tastypie.resources import ModelResource
from tastypie.utils import trailing_slash
class BackboneCompatibleResource(ModelResource):
logger = logging.getLogger(__name__)
pass
def humanize_date(self, date):
if (datetime.datetime.now() - date) <= datetime.timedelta(days=1):
return humanize.naturaltime(date)
else:
return humanize.naturalday(date)

View File

@@ -1,13 +1,11 @@
import datetime
import humanize
from tastypie import fields
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.models.Comment import Comment
from tastypie.resources import ModelResource
class CommentResource(ModelResource):
class CommentResource(BackboneCompatibleResource):
mix = fields.ToOneField('spa.api.v1.MixResource.MixResource', 'mix')
class Meta:
@@ -25,10 +23,7 @@ class CommentResource(ModelResource):
return super(CommentResource, self).obj_create(bundle, request, user=request.user)
def dehydrate_date_created(self, bundle):
if (datetime.datetime.now() - bundle.obj.date_created) <= datetime.timedelta(days=1):
return humanize.naturaltime(bundle.obj.date_created)
else:
return humanize.naturalday(bundle.obj.date_created)
return self.humanize_date(bundle.obj.date_created)
def dehydrate(self, bundle):
bundle.data['avatar_image'] = bundle.obj.user.get_profile().get_small_profile_image()

View File

@@ -17,7 +17,7 @@ from spa.models.Mix import Mix
class MixResource(BackboneCompatibleResource):
comments = fields.ToManyField('spa.api.v1.CommentResource.CommentResource', 'comments')
#activity = fields.ToManyField('spa.api.v1.ActivityResource.ActivityResource', 'activity', 'mix', null=True)
#downloads = fields.ToManyField('spa.api.v1.ActivityResource.ActivityResource', 'downloads')
class Meta:
queryset = Mix.objects.filter(is_active=True)

View File

@@ -9,3 +9,9 @@ class MixPlay(_Activity):
def get_object_singular(self):
return "mix"
def get_object_name(self):
return self.mix.title
def get_object_url(self):
return self.mix.get_absolute_url()

View File

@@ -26,3 +26,11 @@ class _Activity(_BaseModel):
@abc.abstractmethod
def get_object_plural(self):
return
@abc.abstractmethod
def get_object_name(self):
return
@abc.abstractmethod
def get_object_url(self):
return

View File

@@ -38,6 +38,9 @@ img.event-content {
.bordered {
border-bottom: 3px solid #CEC3B3;
}
.bordered-faint {
border-bottom: 1px solid #CEC3B3;
}
.page-header {
-moz-border-bottom-colors: none;
@@ -583,4 +586,9 @@ div.event-content td {
.mix-profile-insert {
}
.activity-list-item{
margin-bottom: 5px;
margin-left: 5px;
}

View File

@@ -34,7 +34,7 @@ window.SidebarView = Backbone.View.extend({
var content = new ActivityListView({
collection: activity
}).el;
$('.sidebar-content-activity', this.el).html(content.el);
$('#sidebar-content-activity', this.el).html(content);
}
});
return this;

View File

@@ -12,7 +12,7 @@ if (!com.podnoms) com.podnoms = {};
com.podnoms.utils = {
// Asynchronously load templates located in separate .html files
loadTemplate:function (views, callback) {
loadTemplate: function (views, callback) {
var deferreds = [];
$.each(views, function (index, view) {
if (window[view]) {
@@ -25,11 +25,11 @@ com.podnoms.utils = {
});
$.when.apply(null, deferreds).done(callback);
},
trackPageView:function (url) {
trackPageView: function (url) {
if (!(typeof(_gag) == "undefined"))
_gaq.push(['_trackPageview', "/" + url]);
},
displayValidationErrors:function (messages) {
displayValidationErrors: function (messages) {
for (var key in messages) {
if (messages.hasOwnProperty(key)) {
this.addValidationError(key, messages[key]);
@@ -37,20 +37,20 @@ com.podnoms.utils = {
}
this.showAlert('Warning!', 'Fix validation errors and try again', 'alert-warning');
},
addValidationError:function (field, message) {
addValidationError: function (field, message) {
var controlGroup = $('#' + field).parent().parent();
controlGroup.addClass('error');
$('.help-inline', controlGroup).html(message);
},
removeValidationError:function (field) {
removeValidationError: function (field) {
var controlGroup = $('#' + field).parent().parent();
controlGroup.removeClass('error');
$('.help-inline', controlGroup).html('');
},
showError:function (title, message) {
showError: function (title, message) {
this.showAlert(title, message, 'alert-error', true);
},
showAlert:function (title, text, klass, fade) {
showAlert: function (title, text, klass, fade) {
$('.alert').removeClass("alert-error alert-warning alert-success alert-info");
$('.alert').addClass(klass);
$('.alert').html('<strong>' + title + '</strong> ' + text);
@@ -63,33 +63,37 @@ com.podnoms.utils = {
this.hideAlert();
});
},
hideAlert:function () {
hideAlert: function () {
$('.alert').fadeOut('slow', function () {
});
},
pad2:function (number) {
pad2: function (number) {
return (number < 10 ? '0' : '') + number;
},
getDateAsToday:function () {
getDateAsToday: function () {
var currentTime = new Date();
var day = currentTime.getDate();
var month = currentTime.getMonth() + 1;
var year = currentTime.getFullYear();
return (com.podnoms.utils.pad2(day) + "/" + com.podnoms.utils.pad2(month) + "/" + year);
},
isEmpty:function (val) {
formatJSONDate: function (jsonDate) {
var date = new Date(parseInt(jsonDate.substr(6)));
return date;
},
isEmpty: function (val) {
return (val === undefined || val == null || val.length <= 0) ? true : false;
},
setHashbangHeader:function (xhr) {
setHashbangHeader: function (xhr) {
xhr.setRequestHeader('X-FB-Nonsense', 'Argle-Bargle');
},
generateGuid:function () {
generateGuid: function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
downloadURL:function downloadURL(url) {
downloadURL: function downloadURL(url) {
var iframe;
iframe = document.getElementById("hiddenDownloader");
if (iframe === null) {
@@ -103,7 +107,7 @@ com.podnoms.utils = {
};
jQuery.extend({
handleError:function (s, xhr, status, e) {
handleError: function (s, xhr, status, e) {
// If a local callback was specified, fire it
if (s.error) {
s.error.call(s.context || window, xhr, status, e);

1609
static/js/libs/globalize.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +0,0 @@
function DssSoundHandler() {
var _currentSound = null;
var _currentId = -1;
this.stop_sound = function () {
if (_currentSound) {
this.togglePlaying(this.getPlayingId());
_currentSound.stop();
_currentId = -1;
}
};
this.getPlayingId = function () {
return _currentId;
};
this.isPlaying = function () {
if (_currentSound != null)
return _currentSound.playState == 1;
};
this.togglePlaying = function (id) {
this.togglePlayState(id);
return this.togglePlayVisual(id);
};
this.togglePlayVisual = function (id) {
var button = $('#play-pause-button-small-' + id);
var mode = button.data("mode");
if (mode == "play" || mode == "resume") {
button.data('mode', 'pause');
button.removeClass('play-button-small-playing');
button.addClass('play-button-small-paused');
} else {
button.data('mode', 'resume');
button.removeClass('play-button-small-paused');
button.addClass('play-button-small-playing');
}
return mode;
};
this.togglePlayState = function (id) {
var button = $('#play-pause-button-small-' + id);
var mode = button.data("mode");
if (mode == 'pause')
this.pauseSound();
else if (mode == 'resume')
this.resumeSound();
};
this.playSound = (function (itemId, stream_url) {
_currentId = itemId;
var waveformTop = $('#waveform-' + _currentId).position().top;
var waveformWidth = $('#waveform-' + _currentId).width();
$('#player-seekhead').css('top', waveformTop);
if (_currentSound) _currentSound.stop();
soundManager.destroySound('current_sound');
_currentSound = soundManager.createSound({
id:'current_sound',
url:stream_url,
volume:50,
stream:true,
whileloading:function () {
var percentageFinished = (_currentSound.bytesLoaded / _currentSound.bytesTotal) * 100;
var percentageWidth = (waveformWidth / 100) * percentageFinished;
$('#progress-player-' + _currentId).css('width', percentageWidth);
},
whileplaying:function () {
/* Should move to an aggregator viewChanged callback */
if (_currentId == -1){
_currentId = itemId;
this._setupEvents(itemId, _currentSound);
}
waveformTop = $('#waveform-' + _currentId).position().top;
waveformWidth = $('#waveform-' + _currentId).width();
$('#playhead-player-' + _currentId).css('top', waveformTop);
$('#progress-player-' + _currentId).css('top', waveformTop);
$('#player-seekhead').css('top', waveformTop);
var currentPosition = _currentSound.position;
var totalLength = _currentSound.duration;
var percentageFinished = (currentPosition / totalLength) * 100;
var percentageWidth = (waveformWidth / 100) * percentageFinished;
$('#playhead-player-' + _currentId).css('width', percentageWidth);
}
});
_currentSound.loaded = false;
_currentSound.readyState = 0;
dssSoundHandler._setupEvents(_currentId, _currentSound);
_currentSound.play();
});
this.playLive = function () {
this.stop_sound();
_currentSound = soundManager.createSound({
id:'current_sound',
url:com.podnoms.settings.liveStreamRoot,
volume:50,
stream:true,
useMovieStar:true
});
_currentSound.play();
};
this.pauseSound = function () {
this.togglePlaying();
if (_currentSound) {
_currentSound.pause();
}
};
this.resumeSound = function () {
this.togglePlaying();
if (_currentSound)
_currentSound.resume();
};
this.getPosition = function () {
if (_currentSound)
return _currentSound.position;
};
this._setupEvents = function (itemId, sound) {
$('#waveform-' + itemId).mousemove(function (event) {
$('#player-seekhead').show();
$('#player-seekhead').css('left', (event.pageX) + 'px').fadeIn('fast');
});
$('#waveform-' + itemId).mousedown(function (event) {
var width = $('#waveform-image-' + itemId).width();
if (sound != null) {
var fullLength = sound.duration;
var left = $('#waveform-image-' + itemId).offset().left;
var clickPerc = ((event.pageX - left) / width) * 100;
sound.setPosition((fullLength / 100) * clickPerc);
}
});
$('#waveform-' + itemId).mouseleave(function (event) {
$('#player-seekhead').hide();
});
};
}
dssSoundHandler = new DssSoundHandler();
window.dssSoundHandler = dssSoundHandler;

View File

@@ -96,6 +96,7 @@
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.mine.js"></script>
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.infiniscroll.js"></script>
<script src="{{ STATIC_URL }}js/libs/backbone/backbone-tastypie.js"></script>
<script src="{{ STATIC_URL }}js/libs/globalize.js"></script>
<script src="{{ STATIC_URL }}js/libs/clickify.js"></script>
<script src="{{ STATIC_URL }}js/libs/jquery.colorbox.js"></script>
<script src="{{ STATIC_URL }}js/com.podnoms.utils.js"></script>

View File

@@ -1,17 +1,17 @@
{% load account_tags %}
<div class="activity-block">
<a href="">
<img class="image-avatar-small" src="<%= item.avatar_image %>" alt="">
</a>
<div class="activity-details">
<a class="activity-user" href="<%= item.user_url %>">
<%= item.user_name %>
</a>
<blockquote class="pull-right">
<p><%= item.activity %></p>
<small><%= item.date_created %></small>
</blockquote>
</div>
</div>
{% load account_tags %}
<div class="media bordered-faint activity-list-item">
<a class="pull-left" href="#">
<img class="media-object" data-src="holder.js/64x64">
<img class="media-object " src="<%= item.user_image %>" alt="">
</a>
<div class="media-body">
<div class="media">
<a class="activity-user" href="<%= item.user_profile %>">
<%= item.user_name %>
</a>
<%= item.verb %> <a href="<%= item.item_url %>"><%= item.item_name %></a>
<blockquote class="pull-right"><%= item.date %></blockquote>
</div>
</div>
</div>

View File

@@ -5,7 +5,7 @@
</ul>
<div id="mix-tabContent" class="tab-content">
<div class="tab-pane active in fade" id="activity">
<div id="sidebar-content-activity">Hello Sailor</div>
<div id="sidebar-content-activity"></div>
</div>
<div class="tab-pane fade" id="nowplaying">
{% include 'inc/side-player.html' %}