from datetime import datetime import os import logging from django.conf.urls import url from django.contrib.auth.decorators import login_required from django.core.files.base import ContentFile from django.core.files.storage import FileSystemStorage from django.db.models import get_model from django.http import HttpResponse, HttpResponseNotFound from annoying.decorators import render_to from django.shortcuts import render_to_response from django.utils import simplejson from django.views.decorators.csrf import csrf_exempt, csrf_protect from django.views.decorators.http import require_POST from jfu.http import upload_receive, UploadResponse from core.utils import live from dss import localsettings, settings from spa.models import UserProfile, Release from spa.models.mix import Mix from spa.models.comment import Comment from core.serialisers import json from core.tasks import create_waveform_task from spa.models.notification import Notification logger = logging.getLogger(__name__) class AjaxHandler(object): # Get an instance of a logger def __init__(self, api_name="v1"): self.api_name = api_name @property def urls(self): pattern_list = [ url(r'^mix/add_comment/$', 'spa.ajax.mix_add_comment', name='mix_add_comment'), url(r'^mix/comments/(?P\d+)/$', 'spa.ajax.mix_comments', name='ajax_mix_comments'), url(r'^header/$', 'spa.ajax.header', name='header'), url(r'^session_play_count/$', 'spa.ajax.session_play_count'), url(r'^mix_stream_url/(?P\d+)/$', 'spa.ajax.get_mix_stream_url'), url(r'^release_player/(?P\d+)/$', 'spa.ajax.release_player'), url(r'^live_now_playing/$', 'spa.ajax.live_now_playing'), url(r'^mark_read/$', 'spa.ajax.mark_read'), url(r'^facebook_post_likes_allowed/$', 'spa.ajax.facebook_post_likes_allowed', name='ajax_facebook_post_likes_allowed'), url(r'^upload_mix_image/(?P\d+)/$', 'spa.ajax.upload_mix_image', name='ajax_upload_mix_image'), url(r'^upload_release_image/(?P\d+)/$', 'spa.ajax.upload_release_image', name='ajax_upload_release_image'), url(r'^upload_avatar_image/$', 'spa.ajax.upload_avatar_image', name='ajax_upload_avatar_image'), url(r'^lookup/search/$', 'spa.ajax.lookup_search', name='ajax_lookup'), url(r'^lookup/(?P\w+)/$', 'spa.ajax.lookup', name='ajax_lookup'), ] return pattern_list def _get_json(payload, key='value'): data = { key: payload } return simplejson.dumps(data) @render_to('inc/header.html') def header(request): return HttpResponse(render_to_response('inc/header.html')) def session_play_count(request): """ :param request: :return: Number of tracks played in this session """ if not request.user.is_authenticated(): if 'play_count' in request.session: result = simplejson.dumps({ 'play_count': request.session['play_count'] }) else: result = simplejson.dumps({ 'play_count': '0' }) else: result = simplejson.dumps({ 'play_count': '0' }) return HttpResponse(result, mimetype='application/json') def get_mix_stream_url(request, mix_id): try: if not request.user.is_authenticated(): if 'play_count' in request.session: request.session['play_count'] += 1 else: request.session['play_count'] = 1 mix = Mix.objects.get(pk=mix_id) mix.add_play(request.user) data = { 'stream_url': mix.get_stream_path(), 'description': mix.description, 'item_url': mix.get_absolute_url(), 'title': mix.title } return HttpResponse(simplejson.dumps(data), mimetype="application/json") except Exception, e: logger.exception("Error getting mix stream url") raise #HttpResponse("Error getting mix stream url", status=401) def live_now_playing(request): now_playing_info = live.get_now_playing( localsettings.JS_SETTINGS['LIVE_STREAM_URL'], localsettings.JS_SETTINGS['LIVE_STREAM_PORT'], localsettings.JS_SETTINGS['LIVE_STREAM_MOUNT']) try: if now_playing_info is not None: return HttpResponse( simplejson.dumps({ 'stream_url': 'http://%s:%s/%s' % ( localsettings.JS_SETTINGS['LIVE_STREAM_URL'], localsettings.JS_SETTINGS['LIVE_STREAM_PORT'], localsettings.JS_SETTINGS['LIVE_STREAM_MOUNT']), 'description': now_playing_info['stream_description'], 'title': now_playing_info['current_song'] }), mimetype="application/json") except: return HttpResponseNotFound(now_playing_info) return None @render_to('inc/release_player.html') def release_player(request, release_id): return HttpResponse('Hello Sailor') def mix_add_comment(request): if request.POST: comment = Comment() comment.mix_id = request.POST['mixid'] comment.user = request.user comment.comment = request.POST['comment'] comment.time_index = request.POST['position'] comment.save() return HttpResponse(_get_json('Comment posted', 'description')) else: return HttpResponse(_get_json('Error posting', 'description')) @render_to('inc/comment_list.html') def mix_comments(request, mix_id): return { "results": Comment.objects.filter(mix_id=mix_id), } @login_required def mark_read(request): profile = request.user.get_profile() if profile is not None: Notification.objects.filter(to_user=profile).update(accepted_date=datetime.now()) return HttpResponse('Success', status=200) pass return HttpResponse('Unauthorized', status=401) @login_required() def facebook_post_likes_allowed(request): profile = request.user.get_profile() if profile is not None: likes_allowed = profile.activity_sharing & UserProfile.ACTIVITY_SHARE_LIKES facebook_allowed = profile.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK return HttpResponse(_get_json(bool(likes_allowed & facebook_allowed)), mimetype="application/json") return HttpResponse(_get_json(False), mimetype="application/json") @csrf_exempt def upload_release_image(request, release_id): try: if 'release_image' in request.FILES and release_id is not None: release = Release.objects.get(pk=release_id) if release is not None: release.release_image = request.FILES['release_image'] release.save() return HttpResponse(_get_json("Success")) except Exception, ex: logger.exception("Error uploading release image") return HttpResponse(_get_json("Failed")) def upload_mix_image(request, mix_id): try: if len(request.FILES) != 0: mix = Mix.objects.get(pk=mix_id) if mix: mix.mix_image = request.FILES[request.FILES.keys()[0]] mix.save() return HttpResponse(json.dumps({'status': 'OK', 'url': mix.get_image_url()})) except Exception, ex: logger.exception("Error uploading avatar: %s", ex.message) return HttpResponse(json.dumps({'status': 'failed', 'message': ex.message})) return HttpResponse(json.dumps({'status': 'failed', 'message': 'No image file found'})) def upload_avatar_image(request): # TODO: fergal.moran@gmail.com # Problem here that only the current user can update avatar # Might need to allow staff to change other's avatars? try: if len(request.FILES) != 0: profile = request.user.get_profile() if profile: profile.avatar_image = request.FILES[request.FILES.keys()[0]] profile.avatar_type = 'custom' profile.save() return HttpResponse(json.dumps({'status': 'OK', 'url': profile.get_avatar_image()})) except Exception, ex: logger.exception("Error uploading avatar: %s", ex.message) return HttpResponse(json.dumps({'status': 'failed', 'message': ex.message})) return HttpResponse(json.dumps({'status': 'failed', 'message': 'No image file found'})) @require_POST @login_required @csrf_protect def upload(request): # The assumption here is that jQuery File Upload # has been configured to send files one at a time. # If multiple files can be uploaded simultaneously, # 'file' may be a list of files. try: uid = request.POST['upload-hash'] in_file = request.FILES['file'] if request.FILES else None file_name, extension = os.path.splitext(in_file.name) file_storage = FileSystemStorage(location=os.path.join(settings.CACHE_ROOT, "mixes")) cache_file = file_storage.save("%s%s" % (uid, extension), ContentFile(in_file.read())) response = '' try: create_waveform_task.delay(in_file=os.path.join(file_storage.base_location, cache_file), uid=uid) except: logger.debug("Unable to connect to celery") response = 'Unable to connect to waveform generation task, there may be a delay in getting your mix online' file_dict = { 'response': response, 'size': in_file.size, 'uid': uid } return UploadResponse(request, file_dict) except Exception, ex: logger.exception(ex.message) raise @csrf_exempt def lookup_search(request): query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else '' if query != '': filter_field = Mix.get_lookup_filter_field() kwargs = { '{0}__{1}'.format(filter_field, 'icontains'): query, } rows = Mix.objects.values("title").filter(**kwargs) #results = serializers.serialize("json", rows, fields="title",) results = json.dumps(rows) return HttpResponse(results, mimetype='application/json') @csrf_exempt def lookup(request, source): query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else '' if query != '': model = get_model('spa', source) if model is not None: filter_field = model.get_lookup_filter_field() kwargs = { '{0}__{1}'.format(filter_field, 'icontains'): query, } rows = model.objects.filter(**kwargs) results = json.to_ajax(rows, filter_field) return HttpResponse(simplejson.dumps(results), mimetype='application/json') return HttpResponse(_get_json("Key failure in lookup"), mimetype='application/json')