Temp fix for file downloads

This commit is contained in:
Fergal Moran
2014-08-30 19:40:30 +01:00
parent ab4ae43279
commit 18afd9fcf0
20 changed files with 202 additions and 133 deletions

View File

@@ -22,6 +22,7 @@ git+git://github.com/etianen/django-require.git#django-require
git+git://github.com/spookylukey/django-paypal.git#django-paypal
git+git://github.com/llazzaro/django-scheduler.git#django-scheduler
git+git://github.com/cyberdelia/django-pipeline.git#django-pipeline
git+git://github.com/disqus/django-bitfield.git#django-bitfield
django-templated-email
django-grappelli
humanize

View File

@@ -2,12 +2,12 @@ import humanize
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from tastypie.constants import ALL, ALL_WITH_RELATIONS
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models import UserProfile
from spa.models.activity import Activity
class ActivityResource(BackboneCompatibleResource):
class ActivityResource(BaseResource):
class Meta:
queryset = Activity.objects.select_subclasses().order_by('-id')
resource_name = 'activity'

View File

@@ -1,15 +0,0 @@
import logging
import datetime
import humanize
from tastypie.resources import ModelResource
class BackboneCompatibleResource(ModelResource):
logger = logging.getLogger(__name__)
pass
def humanize_date(self, date):
if (timezone.now() - date) <= datetime.timedelta(days=1):
return humanize.naturaltime(date)
else:
return humanize.naturalday(date)

View File

@@ -0,0 +1,14 @@
import logging
from tastypie.resources import ModelResource
class BaseResource(ModelResource):
logger = logging.getLogger(__name__)
pass
def _remove_kwargs(self, *args, **kwargs):
for arg in args:
if arg in kwargs:
del kwargs['activity_sharing_networks_facebook']
return kwargs

View File

@@ -1,7 +1,7 @@
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models.chatmessage import ChatMessage
class ChatResource(BackboneCompatibleResource):
class ChatResource(BaseResource):
class Meta:
queryset = ChatMessage.objects.all().order_by('-timestamp')
resource_name = 'chat'

View File

@@ -3,13 +3,13 @@ from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpBadRequest, HttpMethodNotAllowed, HttpUnauthorized, HttpApplicationError, HttpNotImplemented
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models import Mix, UserProfile
from spa.models.activity import ActivityComment
from spa.models.comment import Comment
class CommentResource(BackboneCompatibleResource):
class CommentResource(BaseResource):
mix = fields.ToOneField('spa.api.v1.MixResource.MixResource', 'mix')
likes = fields.ToManyField('spa.api.v1.UserResource.UserResource',
'likes', related_name='favourites',

View File

@@ -1,7 +1,7 @@
from django.core.exceptions import ObjectDoesNotExist
import humanize
from tastypie.authorization import Authorization
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models.recurrence import Recurrence
"""
from spa.views.venue import Venue

View File

@@ -1,11 +1,11 @@
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models import Genre
class GenreResource(BackboneCompatibleResource):
class GenreResource(BaseResource):
class Meta:
queryset = Genre.objects.all().order_by('description')
resource_name = 'genres'

View File

@@ -13,7 +13,7 @@ from tastypie.http import HttpGone, HttpUnauthorized
from tastypie.utils import trailing_slash
from dss import settings
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.api.v1.CommentResource import CommentResource
from spa.api.v1.ActivityResource import ActivityResource
from spa.models.mix import Mix
@@ -21,7 +21,7 @@ from spa.models.show import Show
from spa.models.userprofile import UserProfile
class MixResource(BackboneCompatibleResource):
class MixResource(BaseResource):
comments = fields.ToManyField('spa.api.v1.CommentResource.CommentResource',
'comments', null=True, full=True)
favourites = fields.ToManyField('spa.api.v1.UserResource.UserResource',

View File

@@ -1,11 +1,11 @@
from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models.notification import Notification
from spa.models.userprofile import UserProfile
class NotificationResource(BackboneCompatibleResource):
class NotificationResource(BaseResource):
class Meta:
queryset = Notification.objects.order_by('-id')
resource_name = 'notification'

View File

@@ -6,11 +6,11 @@ from tastypie import fields
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpUnauthorized
from tastypie.utils import trailing_slash
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models import Playlist, Mix, UserProfile
class PlaylistResource(BackboneCompatibleResource):
class PlaylistResource(BaseResource):
user = fields.ToOneField('spa.api.v1.UserResource.UserResource', 'user')
mixes = fields.ManyToManyField('spa.api.v1.MixResource.MixResource', 'mixes', full=True, null=True)

View File

@@ -1,8 +1,8 @@
from tastypie import fields
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models.release import ReleaseAudio
class ReleaseAudioResource(BackboneCompatibleResource):
class ReleaseAudioResource(BaseResource):
release = fields.ToOneField('spa.api.v1.ReleaseResource.ReleaseResource', 'release')
class Meta:

View File

@@ -2,11 +2,11 @@ import datetime
from tastypie import fields
from tastypie.authorization import Authorization
from tastypie.constants import ALL_WITH_RELATIONS
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models import Label
from spa.models.release import Release
from django.core.exceptions import ObjectDoesNotExist
class ReleaseResource(BackboneCompatibleResource):
class ReleaseResource(BaseResource):
release_audio = fields.ToManyField('spa.api.v1.ReleaseAudioResource.ReleaseAudioResource', 'release_audio', 'release', null=True, blank=True)
class Meta:
queryset = Release.objects.all()

View File

@@ -3,7 +3,7 @@ from tastypie.authorization import Authorization
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpBadRequest
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.models import Show
from spa.models.show import ShowOverlapException
@@ -11,7 +11,7 @@ from spa.models.show import ShowOverlapException
DATE_FORMAT = '%d/%m/%Y %H:%M:%S'
class ShowResource(BackboneCompatibleResource):
class ShowResource(BaseResource):
mix = fields.ToOneField('spa.api.v1.MixResource.MixResource',
'mix', null=False, full=False)

View File

@@ -10,14 +10,14 @@ from tastypie.utils import trailing_slash
from tastypie_msgpack import Serializer
from dss import settings
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.BaseResource import BaseResource
from spa.api.v1.PlaylistResource import PlaylistResource
from spa.models.userprofile import UserProfile
from spa.models.mix import Mix
from core.tasks import update_geo_info_task
class UserResource(BackboneCompatibleResource):
class UserResource(BaseResource):
following = fields.ToManyField(to='self', attribute='following', related_name='following', null=True)
followers = fields.ToManyField(to='self', attribute='followers', related_name='followers', null=True)
@@ -44,7 +44,6 @@ class UserResource(BackboneCompatibleResource):
authorization = Authorization()
authentication = Authentication()
@staticmethod
def _hydrate_bitmap_opt(source, comparator):
return True if (source & comparator) != 0 else False
@@ -75,26 +74,11 @@ class UserResource(BackboneCompatibleResource):
return super(UserResource, self).obj_create(bundle, **kwargs)
def obj_update(self, bundle, skip_errors=False, **kwargs):
"""
This feels extremely hacky - but for some reason, deleting from the bundle
in hydrate is not preventing the fields from being serialized at the ORM
"""
if 'activity_sharing_networks_facebook' in kwargs: del kwargs['activity_sharing_networks_facebook']
if 'activity_sharing_networks_twitter' in kwargs: del kwargs['activity_sharing_networks_twitter']
if 'activity_sharing_likes' in kwargs: del kwargs['activity_sharing_likes']
if 'activity_sharing_favourites' in kwargs: del kwargs['activity_sharing_favourites']
if 'activity_sharing_comments' in kwargs: del kwargs['activity_sharing_comments']
ret = super(UserResource, self).obj_update(bundle, skip_errors, **kwargs)
try:
update_geo_info_task.delay(ip_address=bundle.request.META['REMOTE_ADDR'],
profile_id=bundle.request.user.get_profile().id)
except:
pass
return ret
update_geo_info_task.delay(
ip_address=bundle.request.META['REMOTE_ADDR'],
profile_id=bundle.request.user.get_profile().id
)
return super(UserResource, self).obj_update(bundle, skip_errors, **kwargs)
def _create_playlist(self, request):
pass
@@ -120,6 +104,13 @@ class UserResource(BackboneCompatibleResource):
del bundle.data['activity_sharing_networks']
bundle.data['display_name'] = bundle.obj.get_nice_name()
bundle.data['avatar_image'] = bundle.obj.get_avatar_image()
bundle.data['email_notification_plays'] = bundle.obj.email_notifications.plays.is_set
bundle.data['email_notification_likes'] = bundle.obj.email_notifications.likes.is_set
bundle.data['email_notification_favourites'] = bundle.obj.email_notifications.favourites.is_set
bundle.data['email_notification_follows'] = bundle.obj.email_notifications.follows.is_set
bundle.data['email_notification_comments'] = bundle.obj.email_notifications.comments.is_set
if bundle.obj.user.id == bundle.request.user.id:
bundle.data['email'] = bundle.obj.email
bundle.data['first_name'] = bundle.obj.first_name
@@ -130,6 +121,8 @@ class UserResource(BackboneCompatibleResource):
self._hydrate_bitmap_opt(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_FAVOURITES)
bundle.data['activity_sharing_comments'] = \
self._hydrate_bitmap_opt(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_COMMENTS)
bundle.data['activity_sharing_plays'] = \
self._hydrate_bitmap_opt(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_PLAYS)
bundle.data['activity_sharing_networks_facebook'] = \
self._hydrate_bitmap_opt(bundle.obj.activity_sharing_networks,
@@ -153,10 +146,12 @@ class UserResource(BackboneCompatibleResource):
def hydrate(self, bundle):
if 'activity_sharing_likes' in bundle.data:
plays = UserProfile.ACTIVITY_SHARE_PLAYS if bundle.data['activity_sharing_plays'] else 0
likes = UserProfile.ACTIVITY_SHARE_LIKES if bundle.data['activity_sharing_likes'] else 0
favourites = UserProfile.ACTIVITY_SHARE_FAVOURITES if bundle.data['activity_sharing_favourites'] else 0
comments = UserProfile.ACTIVITY_SHARE_COMMENTS if bundle.data['activity_sharing_comments'] else 0
bundle.data['activity_sharing'] = (likes | favourites | comments)
del bundle.data['activity_sharing_plays']
del bundle.data['activity_sharing_likes']
del bundle.data['activity_sharing_favourites']
del bundle.data['activity_sharing_comments']

View File

@@ -5,8 +5,10 @@ import urlparse
from django.conf.urls import url
import json
from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseNotFound
from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseNotFound, HttpResponseRedirect
from django.core.servers.basehttp import FileWrapper
from django.shortcuts import redirect
from django.utils.encoding import smart_str
from nginx_signing.signing import UriSigner
from sendfile import sendfile
@@ -37,9 +39,9 @@ def download(request, mix_id):
mix = Mix.objects.get(pk=mix_id)
if mix is not None:
if mix.download_allowed:
if mix.archive_path in [None, '']:
audio_file = mix.get_absolute_path()
filename, extension = os.path.splitext(audio_file)
if os.path.exists(audio_file):
return sendfile(
request,
@@ -49,6 +51,12 @@ def download(request, mix_id):
mix.title, extension
)
)
else:
response = HttpResponseRedirect(mix.archive_path)
response['Content-Disposition'] = 'attachment; filename=' + \
smart_str('Deep South Sounds - %s%s' % (mix.title, mix.filetype))
return response
else:
return HttpResponse('Downloads not allowed for this mix', status=401)

View File

@@ -1,5 +1,6 @@
import logging
import urlparse
from bitfield.models import BitField
from django.contrib.auth.models import User
from django.core.exceptions import SuspiciousOperation
@@ -37,6 +38,7 @@ class UserProfile(BaseModel):
ACTIVITY_SHARE_LIKES = 1
ACTIVITY_SHARE_FAVOURITES = 2
ACTIVITY_SHARE_COMMENTS = 4
ACTIVITY_SHARE_PLAYS = 8
ACTIVITY_SHARE_NETWORK_FACEBOOK = 1
ACTIVITY_SHARE_NETWORK_TWITTER = 2
@@ -51,6 +53,14 @@ class UserProfile(BaseModel):
activity_sharing = models.IntegerField(default=0)
activity_sharing_networks = models.IntegerField(default=0)
email_notifications = BitField(flags=(
('plays', 'Plays'),
('likes', 'Likes'),
('favourites', 'Favourites'),
('follows', 'Follows'),
('comments', 'Comments'),
), default=0)
following = models.ManyToManyField('self', null=True, blank=True, symmetrical=False, related_name='followers')
#location properties

View File

@@ -50,17 +50,13 @@
error: (data, status, e) ->
utils.showError e
@uploadImage
el: $('#avatar_image')
success: ->
utils.showMessage "Successfully updated yourself"
Backbone.history.navigate "/",
trigger: true
else
toastr.info "Successfully updated yourself"
alert("What to do")
"""
Backbone.history.navigate "/",
trigger: true
"""
true
error: ->
toastr.error "There was an error updating your info. Please try again later."

View File

@@ -1,11 +1,9 @@
@social = do ->
postFacebookLike: (mixId) ->
#first off, find if the current user has allowed facebook likes
$.getJSON "social/like/" + mixId + "/", (data) ->
utils.showAlert "Posted your like to facebook, you can stop this in your settings page.", "Cheers feen"
generateEmbedCode: (model) ->
console.log("Generating embed code");
utils.modal "/dlg/embed/" + model.get('slug')

View File

@@ -64,58 +64,120 @@
</div>
<div class="col-md-7">
<div class="row">
<p>
<h5>What can we share about you?</h5>
</p>
<div class="col-md-5 pull-left">
<h5>Share this activity</h5>
<table class="table dss-option-table table-condensed table-bordered">
<tbody>
<tr class="info">
<td>Likes</td>
<td>Favourites</td>
<td>Comments</td>
</tr>
<tr>
<td>
<input type="checkbox" name="activity_sharing_likes"
id="activity_sharing_likes" <%= renderCheckbox(activity_sharing_likes)
%>>
</td>
<td>
<input type="checkbox" name="activity_sharing_favourites"
id="activity_sharing_favourites"
<%= renderCheckbox(activity_sharing_favourites) %>>
</td>
<td>
<input type="checkbox" name="activity_sharing_comments"
id="activity_sharing_comments"
<%= renderCheckbox(activity_sharing_comments) %>>
</td>
</tr>
</tbody>
</table>
<div class="widget-box transparent">
<div class="widget-header widget-header-flat">
<h4 class="widget-title lighter">
<i class="ace-icon fa fa-share green"></i>
Social media sharing
</h4>
</div>
<div class="col-md-5 pull-right">
<h5>On these networks</h5>
<table class="table dss-option-table table-condensed table-bordered">
<tbody>
<tr class="info">
<td>Facebook</td>
<td>Twitter</td>
</tr>
<tr>
<td style="text-align: center; vertical-align: middle">
<div class="widget-body">
<div class="widget-main padding-4">
<div class="col-xs-6 bordered-right">
<label class="control-label bolder blue">Share this activity</label>
<div class="control-group form-inline">
<div class="checkbox">
<label>
<input type="checkbox" name="activity_sharing_plays" class="ace"
id="activity_sharing_plays" <%= renderCheckbox(activity_sharing_plays) %>>
<span class="lbl"> Plays</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="activity_sharing_likes" class="ace"
id="activity_sharing_likes" <%= renderCheckbox(activity_sharing_likes) %>>
<span class="lbl"> Likes</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="activity_sharing_favourites" class="ace"
id="activity_sharing_favourites" <%= renderCheckbox(activity_sharing_favourites) %>>
<span class="lbl"> Favourites</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="activity_sharing_comments" class="ace"
id="activity_sharing_comments" <%= renderCheckbox(activity_sharing_comments) %>>
<span class="lbl"> Comments</span>
</label>
</div>
</div>
</div>
<div class="col-xs-6 bordered-left">
<label class="control-label bolder blue">On these networks</label>
<div class="control-group form-inline">
<div class="checkbox">
<label>
<input type="checkbox" name="activity_sharing_networks_facebook"
class="ace"
id="activity_sharing_networks_facebook"
<%= renderCheckbox(activity_sharing_networks_facebook) %>>
</td>
<td>
<span class="lbl"> Facebook</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="activity_sharing_networks_twitter"
class="ace"
id="activity_sharing_networks_twitter"
<%= renderCheckbox(activity_sharing_networks_twitter) %>>
</td>
</tr>
</tbody>
</table>
<span class="lbl"> Twitter</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="hr hr-double hr-dotted hr18"></div>
<div class="row">
<div class="widget-box transparent">
<div class="widget-header widget-header-flat">
<h4 class="widget-title lighter">
<i class="ace-icon fa fa-envelope red"></i>
Email alerts
</h4>
</div>
<div class="widget-body">
<div class="widget-main padding-4">
<div class="control-group form-inline">
<div class="checkbox">
<label>
<input type="checkbox" name="email_notification_plays" class="ace"
id="email_notification_plays" <%= renderCheckbox(email_notification_plays) %>>
<span class="lbl"> Plays</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="email_notification_plays" class="ace"
id="email_notification_likes" <%= renderCheckbox(email_notification_likes) %>>
<span class="lbl"> Likes</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="email_notification_plays" class="ace"
id="email_notification_favourites" <%= renderCheckbox(email_notification_favourites) %>>
<span class="lbl"> Favourites</span>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="email_notification_plays" class="ace"
id="email_notification_comments" <%= renderCheckbox(email_notification_comments) %>>
<span class="lbl"> Comments</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>