# Create your views here. from django.conf import settings from django.contrib import auth from django.http import HttpResponse from django.http import HttpResponsePermanentRedirect from django.template import loader from django.template import Context from django.shortcuts import render_to_response from django.views.decorators.http import require_POST from django.db.models import Q from django.db.models import Count from datetime import date from datetime import datetime from datetime import timedelta import re import os import sha import time import urllib from backend.models import SJLike from backend.models import SJRoom from backend.models import SJContent from backend.models import SJSearch from backend.models import SJUserProfile from browser import Browser API_HEADER = '#@scanjam 0.3b\n' ROOM_CHAT_LOG_SIZE = 50 ROOM_VIDEO_LOG_SIZE = 50 ACCESS_USER = 0 ACCESS_MODERATOR = 1 ACCESS_ADMIN = 9 LASTSEEN_TIMEOUT= 7 MAX_BG_SIZE = 400 * 1024 HTML_TITLE_RE = re.compile('([^<]+)') YT_INFO = "http://gdata.youtube.com/feeds/api/videos/" YT_INFO_SUFFIX = "?v=2" YT_PREFIX = "http://www.youtube.com/watch?v=" YT_ID_RE = re.compile('http.*v=([^&]+)&?#?') VIMEO_PREFIX = "http://vimeo.com/" VIMEO_ID_RE = re.compile('^https?://.*vimeo.com/([0-9]+)*') SC_PREFIX = "http://api.soundcloud.com/resolve.xml?client_id=iFkfwAx5U1rkd6FImp0Tg&url=" BANDCAMP_KEY = "PENDING" BANDCAMP_API_URL = "http://api.bandcamp.com/api/url/1/info?key="+BANDCAMP_KEY+"&url=" BANDCAMP_API_BAND = "http://api.bandcamp.com/api/band/3/discography?key="+BANDCAMP_KEY+"&band_id=" BANDCAMP_API_ALBUM = "http://api.bandcamp.com/api/album/2/info?key="+BANDCAMP_KEY+"&album_id=" BANDCAMP_API_TRACK = "http://api.bandcamp.com/api/track/1/info?key="+BANDCAMP_KEY+"&track_id=" DEFAULT_BG = "http://scannerjammer.fm/bgz/gridzy9.jpg" # # Common funtions # def is_image(url): path, ext = os.path.splitext(url) return ext.lower() in ['.gif', '.jpg', '.jpeg', '.png'] def is_number(s): try: int(s) return True except: return False def title_from_url (url): return url.split("/")[-1].replace(".mp3", "").replace("%20"," ").replace("_"," ") def headers(response): """ Setup additional headers for response """ response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' response['Access-Control-Allow-Headers'] = 'x-requested-with' response['Access-Control-Max-Age'] = '3628800' response['Content-type'] = 'text/plain; charset=UTF-8' def response_error(error, response=None): """ Add API error name with setup headers to response """ if not response: response = HttpResponse() headers(response) response.write(API_HEADER) response.write('0\t%s\n' % error) return response def response_success(message='OK', response=None): """ Add API OK with setup headers to response """ if not response: response = HttpResponse() headers(response) response.write(API_HEADER) if message: response.write(message + '\n') return response def check_form_fields(request, form_fields): """ Check form fields presence """ for field, value in request.POST.iteritems(): print field, '= "%s"' % value for field in form_fields: if field not in request.POST: return response_error('INCOMPLETE FORM') if not request.POST[field]: return response_error('NO %s' % field) def user_response_str(request, user=None): """ Return API response string for user """ if not user: user = request.user if user.is_authenticated(): user_id = user.id username = user.username session_id = request.session.session_key user_access = user.get_profile().access else: user_id = 0 username = 'anonymous' session_id = sha.new('No valid session').hexdigest() user_access = 0 return '%d\t%s\t%s\t%d\n' % (user_id, username, session_id, user_access) def videos_response_str(videos): """ Return string with list of videos """ out = u"" for v in videos: s = v.settings if s.get('removed', 0): continue out += u"VIDEO\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n" % ( str(v.id), str(datetime_to_timestamp(v.datetime)), str(v.user.id), v.user.username, s['url'], s['title'], v.sjlike_set.count() ) return out def videos_response_list(videos): """ Return list of videos """ retval = [] for v in videos: s = v.settings if s.get('removed', 0): continue l = [ v.id, datetime_to_timestamp(v.datetime), v.user.id, v.user.username, s['url'], s['title'], v.sjlike_set.count() ] retval.append(l) return retval def settings_response_str(label, settings): """ Return string of settings """ strio = u"" for key, value in settings.iteritems(): strio+=('%s\n' % '\t'.join([label, key, value])) return strio def texts_response_str(texts): """ Return string of chat messages """ strio = u"" out = u"" for text in texts: out += ('%d\t%s\t%s\t%s\n' % ( #out += ('%d\t%s\t%d\t%d\t%s\t%s\n' % ( text.id, datetime_to_timestamp(text.datetime), #text.user.id, FIXME #text.room.id, text.user.username, text.settings.get('text', '') )) return out def likes_response_str(likes): """ Return string of likes """ strio = u"" for like in likes: strio+=('LIKE\t%s\n' % like.user.username) return strio def store_video_youtube(room, user, ytid): """ """ ytinfourl = YT_INFO+ytid+YT_INFO_SUFFIX ytinfo = urllib.urlopen(ytinfourl).read() ytmatch = HTML_TITLE_RE.search(ytinfo) title = '___' if ytmatch: title = ytmatch.group(1) video = SJContent(room=room, content_type='video', user=user, datetime=datetime.now()) url = YT_PREFIX+ytid video.settings = {'url': url, 'title': title, 'thumbnail': 'http://img.youtube.com/vi/' + url[-11:] + '/1.jpg'} video.save() return video.id def store_video_vimeo(room, user, vimeoid): """ """ vimeoinfourl = VIMEO_PREFIX+vimeoid vimeoinfo = urllib.urlopen(vimeoinfourl).read() match = HTML_TITLE_RE.search(vimeoinfo) title = '___' if match: title = match.group(1) title = title[0:-9] video = SJContent(room=room, content_type='video', user=user, datetime=datetime.now()) video.settings = {'url': VIMEO_PREFIX+vimeoid, 'title': title, 'thumbnail': ''} video.save() return video.id def store_video_soundcloud(room, user, url): """ """ scinfourl = SC_PREFIX+url scinfo = urllib.urlopen(scinfourl).read() title = "___" if "" in scinfo: match = HTML_TITLE_RE.search(scinfo) title = '___' if match: title = match.group(1) elif "<user>" in scinfo: scinfourl = SC_PREFIX+url+"/tracks" scinfo = urllib.urlopen(scinfourl).read() match = HTML_TITLE_RE.search(scinfo) title = '___' if match: title = match.group(1) video = SJContent(room=room, content_type='video', user=user, datetime=datetime.now()) video.settings = {'url': url, 'title': title, 'thumbnail': ''} video.save() return video.id def store_media_str(room, user, msg): """ """ strio= u"" user_profile = user.get_profile() words = msg.split() music = None image = None for word in words: if 'youtube.com' in word: ytid = '' match = YT_ID_RE.match(word) if match: ytid = match.group(1) elif 'user' in word: ytid = word[-11:] elif 'embed' in word: embedpos = word.find("embed") ytid = word[embedpos+6:embedpos+17] elif '/v/' in word: embedpos = word.find("/v/") ytid = word[embedpos+3:embedpos+14] elif '/feeds/api/videos/' in word: embedpos = word.find("/feeds/api/videos/") ytid = word[embedpos+18:embedpos+29] else: continue videos = SJContent.objects.filter(id=store_video_youtube(room, user, ytid)) strio+=(videos_response_str(videos)) elif "http://youtu.be/" in word: try: ytid = word[16:27] videos = SJContent.objects.filter(id=store_video_youtube(room, user, ytid)) strio+=(videos_response_str(videos)) except: pass elif "vimeo.com" in word: try: match = VIMEO_ID_RE.match(word) if not match: continue vimeoid = match.group(1) videos = SJContent.objects.filter(id=store_video_vimeo(room, user, vimeoid)) strio+=(videos_response_str(videos)) except: pass elif "soundcloud.com" in word: try: videos = SJContent.objects.filter(id=store_video_soundcloud(room, user, word)) strio+=(videos_response_str(videos)) except: pass elif word[-3:] == "mp3": music = word elif word.startswith("http"): url = SJContent(room=room, content_type='url', user=user, datetime=datetime.now()) url.settings = {'url': word} url.save() if is_image(word): image = word if image is not None and music is not None: title = title_from_url(music) audio = SJContent(room=room, content_type='video', user=user, datetime=datetime.now()) audio.settings = {'url': image+music, 'title': title, 'thumbnail': ''} audio.save() strio+=(videos_response_str([audio])) return strio def thraw(settings_text): settings = dict() if settings_text: for line in settings_text.split('\n'): column = line.split('\t') if len(column) == 2: settings[column[0]] = column[1] return settings def freeze(settings): return '\n'.join(['%s\t%s' % (str(key), str(value)) for key, value in settings.iteritems()]) def datetime_to_timestamp(dt): return int(time.mktime(dt.timetuple())) def now_timestamp(): return int(time.mktime(time.localtime())) def yesterday_datetime(): return datetime.now() - timedelta(days=1) def lastseen_datetime(): return datetime.now() - timedelta(seconds=LASTSEEN_TIMEOUT) # # AUTH API # @require_POST def api_auth_login(request): """ Log in user. Public API """ form_fields = ['username', 'password'] response = check_form_fields(request, form_fields) if response: return response user = auth.authenticate(username=request.POST['username'], password=request.POST['password']) if user: if user.is_active: auth.login(request, user) response = response_success() response.write(user_response_str(request)) return response else: return response_error('USER DISABLED') else: if auth.models.User.objects.filter(username=request.POST['username']): return response_error('WRONG PASSWORD') else: return response_error('NO SUCH USER') @require_POST def api_auth_logout(request): """ Log out user. Public API """ auth.logout(request) return response_success() @require_POST def api_auth_sneakin(request): """ Sneak in user. Public API """ form_fields = ['userid', 'username'] response = check_form_fields(request, form_fields) if response: return response try: user = auth.models.User.objects.get(username=request.POST['username']) if user.id != int(request.POST['userid']): return response_error('NO MATCH') except: return response_error('NO SUCH USER') # Hack to authenticate user manually for backend in auth.get_backends(): user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) break auth.login(request, user) response = response_success() response.write(user_response_str(request, user)) return response @require_POST def api_auth_register(request): """ Register new user. Public API """ form_fields = ['username', 'password'] response = check_form_fields(request, form_fields) if response: return response if auth.models.User.objects.filter(username=request.POST['username']): return response_error('USER EXISTS') user = auth.models.User.objects.create_user(username=request.POST['username'], email='default@noemail.com', password=request.POST['password']) user.is_active = True try: user.save() except: return response_error('DB ERROR') user_profile = SJUserProfile(user=user) try: user_profile.save() except: return response_error('DB ERROR') response = response_success() response.write(user_response_str(request, user)) return response @require_POST def api_auth_available(request): """ Check if user exists. Public API """ form_fields = ['username'] response = check_form_fields(request, form_fields) if response: return response if auth.models.User.objects.filter(username=request.POST['username']): return response_error('USER EXISTS') return response_success() @require_POST def api_auth_checkin(request): """ Check in user. Private API """ if request.user.is_authenticated(): response = response_success() response.write(user_response_str(request)) return response return HttpResponse() @require_POST def api_auth_password(request): """ Change user password. Private API """ form_fields = ['username', 'password'] response = check_form_fields(request, form_fields) if response: return response if request.user.is_authenticated() and request.user.username == request.POST['username']: try: user = auth.models.User.objects.get(username=request.POST['username']) user.set_password(request.POST['password']) user.save() user_profile = user.get_profile() user_profile.save() except auth.models.User.DoesNotExist: return response_error('NO SUCH USER') except: return response_error('DB ERROR') return response_success() return HttpResponse() # # USER API # @require_POST def api_user_videos(request): """ View list of user videos. Public API """ form_fields = ['user'] response = check_form_fields(request, form_fields) if response: return response try: query = Q(user=auth.models.User.objects.get(id=request.POST['user'])) except auth.models.User.DoesNotExist: return response_error('NO SUCH USER') except: return response_error('DB ERROR') if 'start' in request.POST: try: timestamp = float(request.POST['start']) query = query & Q(datetime__lte=datetime.fromtimestamp(timestamp)) except: pass videos = SJContent.objects.filter(content_type='video').filter(query).order_by('-datetime')[0:ROOM_VIDEO_LOG_SIZE] if not videos: return response_error('NO VIDEOS') response = response_success() for v in videos: s = v.settings l = '\t'.join([ str(v.id), str(v.datetime), str(v.user.id), v.user.username, s['url'], s['title'], ]) response.write(l + '\n') return response @require_POST def api_user_likes(request): """ View list of liked videos. Public API """ form_fields = ['user'] response = check_form_fields(request, form_fields) if response: return response try: query = Q(sjlike__user=auth.models.User.objects.get(id=request.POST['user'])) except auth.models.User.DoesNotExist: return response_error('NO SUCH USER') except: return response_error('DB ERROR') if 'start' in request.POST: try: timestamp = float(request.POST['start']) query = query & Q(datetime__lte=datetime.fromtimestamp(timestamp)) except: pass videos = SJContent.objects.filter(content_type='video').filter(query).order_by('-datetime')[0:ROOM_VIDEO_LOG_SIZE] if not videos: return response_error('NO VIDEOS') response = response_success() for v in videos: l = '\t'.join([str(v.user.id), str(v.id), str(v.datetime)]) response.write(l + '\n') return response @require_POST def api_user_top(request): """ Public API """ form_fields = ['user'] response = check_form_fields(request, form_fields) if response: return response return HttpResponse('Not implemented yet!\n') @require_POST def api_user_settings(request): """ Update user settings. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['userid', 'bio', 'settings'] response = check_form_fields(request, form_fields) if response: return response if (user.id != int(request.POST['userid'])) and (user_profile.access < ACCESS_ADMIN): return response_error('YOU CAN ONLY EDIT YOURSELF MAN') settings = user_profile.settings settings.update(thraw(request.POST['settings'])) user_profile.settings = settings user_profile.save() return response_success() # # ROOM API # @require_POST def api_room_watch(request): """ View room videos. Public API """ form_fields = ['room'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') response = response_success(str(now_timestamp())) last = 0 if 'last' in request.POST: last =int(request.POST['last']) - 1 videos = SJContent.objects.filter(room=room, content_type='video').order_by('-datetime')[0:ROOM_CHAT_LOG_SIZE] if videos and last <= datetime_to_timestamp(videos[0].datetime): response.write(videos_response_str([v for v in videos if last <= datetime_to_timestamp(v.datetime)])) return response @require_POST def api_room_list(request): """ View list of rooms. Public API """ videos = SJContent.objects.filter(content_type='video', datetime__gt=yesterday_datetime()) s = '' for room in SJRoom.objects.filter(private=False): s += '\t'.join([ str(room.id), room.name, str(datetime_to_timestamp(room.datetime)), str(videos.filter(room=room).count()), room.settings.get('bg', ''), ]) s += '\n' return response_success(s) @require_POST def api_room_view(request): """ View room's video, settings and chats. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') user_profile.lastseen_chat = datetime.now() user_profile.save() response = response_success('\t'.join([u.username for u in room.users.all()])) videos = SJContent.objects.filter(room=room, content_type='video').order_by('-datetime')[0:ROOM_VIDEO_LOG_SIZE] response.write(videos_response_str(videos)) response.write(settings_response_str('ROOM', room.settings)) texts = SJContent.objects.filter(room=room, content_type='text').order_by('-datetime').distinct()[0:ROOM_CHAT_LOG_SIZE] response.write(texts_response_str(texts)) return response @require_POST def api_room_join(request): """ Join user into a room. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except SJRoom.DoesNotExist: if request.POST['room'] and user_profile.access > ACCESS_USER: #print '--> New room', request.POST['room'] room = SJRoom.objects.create(user=user, datetime=datetime.now(), name=request.POST['room']) else: return response_error('NO ROOM') if user not in room.users.all(): room.users.add(user) room.save() user_profile.lastseen_chat = datetime.now() user_profile.save() response = response_success('%d\t%s\t%d' % (user.id, user.username, user_profile.access)) response.write('%s\n' % '\t'.join([u.username for u in room.users.all()])) videos = SJContent.objects.filter(room=room, content_type='video').order_by('-datetime')[0:ROOM_CHAT_LOG_SIZE] response.write(videos_response_str(videos)) if 'enqueue' in request.POST and request.POST['enqueue']: #print 'EXPECTED TO ENQUEUE', request.POST['enqueue'] videos = SJContent.objects.filter(room=room, content_type='video', id=request.POST['enqueue']) response.write(videos_response_str(videos)) response.write(settings_response_str('ROOM', room.settings)) texts = SJContent.objects.filter(room=room, content_type='text').order_by('-datetime').distinct()[0:ROOM_CHAT_LOG_SIZE] response.write(texts_response_str(texts)) return response @require_POST def api_room_read(request): """ Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') response = response_success(str(datetime_to_timestamp(datetime.now()))) response.write('%s\n' % '\t'.join([u.username for u in room.users.all()])) last = 0 if 'last' in request.POST: last =int(request.POST['last']) - 15 if last <= datetime_to_timestamp(room.settings_update): response.write(settings_response_str('ROOM', room.settings)) videos = SJContent.objects.filter(room=room, content_type='video').order_by('-datetime')[0:ROOM_CHAT_LOG_SIZE] if videos and last <= datetime_to_timestamp(videos[0].datetime): response.write(videos_response_str([v for v in videos if last <= datetime_to_timestamp(v.datetime)])) texts = SJContent.objects.filter(room=room, content_type='text').order_by('-datetime')[0:ROOM_CHAT_LOG_SIZE] if texts and last <= datetime_to_timestamp(texts[0].datetime): response.write(texts_response_str([t for t in texts if last <= datetime_to_timestamp(t.datetime)])) return response @require_POST def api_room_poll(request): """ View room poll. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') nowtime = datetime.now() lastseentime = lastseen_datetime() if user not in room.users.all(): room.users.add(user) room.save() user_profile.lastseen_chat = nowtime user_profile.save() room.users.filter(sjuserprofile__lastseen_chat__lt=lastseentime).delete() room.save() if 'cam' in request.POST and request.POST['cam']: user_profile.lastseen_webcam = nowtime user_profile.save() response = response_success(str(datetime_to_timestamp(nowtime))) response.write('%s\n' % '\t'.join([u.username for u in room.users.all()])) last = 0 if 'last' in request.POST: last =int(request.POST['last']) - 15 if last <= datetime_to_timestamp(room.settings_update): response.write(settings_response_str('ROOM', room.settings)) videos = SJContent.objects.filter(room=room, content_type='video').order_by('-datetime')[0:ROOM_CHAT_LOG_SIZE] if videos and last <= datetime_to_timestamp(videos[0].datetime): response.write(videos_response_str([v for v in videos if last <= datetime_to_timestamp(v.datetime)])) texts = SJContent.objects.filter(room=room, content_type='text').order_by('-datetime')[0:ROOM_CHAT_LOG_SIZE] if texts and last <= datetime_to_timestamp(texts[0].datetime): response.write(texts_response_str([t for t in texts if last <= datetime_to_timestamp(t.datetime)])) likes = SJLike.objects.filter(content__content_type='video', content__user=user)[0:ROOM_CHAT_LOG_SIZE] response.write(likes_response_str(likes)) user_webcams = room.users.filter(sjuserprofile__lastseen_webcam__gt=lastseentime) response.write('CAM\t%d\n' % user_webcams.count()) return response @require_POST def api_room_settings(request): """ Update room settings. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room', 'settings'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') settings = room.settings new_settings = thraw(request.POST['settings']) if 'bg' in new_settings and 'bg' in settings and new_settings['bg'] != settings['bg']: try: url = new_settings['bg'] browser = Browser() req = browser.get(url) data = req.read() if len(data) > MAX_BG_SIZE: return response_error('BG_DATA\t%d\t%d\n' % (len(data), MAX_BG_SIZE)) bg = SJContent(room=room, content_type='background', user=user, datetime=datetime.now()) bg.settings = {'url': url} bg.save() except: return response_error('BG_DATA') settings.update(new_settings) room.settings = settings room.save() return response_success() @require_POST def api_room_say(request): """ Room message view and store. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room', 'msg'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') text = SJContent(room=room, content_type='text', user=user, datetime=datetime.now()) text.settings = {'text': request.POST['msg']} text.save() response = response_success('%d\t%s\t%s\t%s' % (text.id, str(datetime_to_timestamp(text.datetime)), user.username, request.POST['msg'])) if 'http' in request.POST['msg']: response.write(store_media_str(room, user, request.POST['msg'])) return response @require_POST def api_room_video(request): """ Room message store view. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['room', 'msg'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') response = response_success(message='') if 'http' in request.POST['msg']: response.write(store_media_str(room, user, request.POST['msg'])) return response # # VIDEO API # @require_POST def api_video_date(request): """ View top videos by date. Public API """ year = request.POST.get('year', '') month = request.POST.get('month', '') day = request.POST.get('day', '') if is_number(year) and is_number(month) and is_number(day): today = datetime(int(year), int(month), int(day)) else: today = datetime.fromtimestamp(time.mktime(date.today().timetuple())) tomorrow = today + timedelta(days=1) videos = SJContent.objects.filter(content_type='video').filter(Q(datetime__gt=today) & Q(datetime__lt=tomorrow)).annotate(likes=Count('sjlike')).order_by('-likes') backgrounds = SJContent.objects.filter(content_type='background', datetime__lt=tomorrow).order_by('-datetime') if backgrounds: url = backgrounds[0].settings.get('url', DEFAULT_BG) else: url = DEFAULT_BG response = response_success('BG\t%s' % url) response.write(videos_response_str(videos)) return response @require_POST def api_video_view(request): """ Video view. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['video'] response = check_form_fields(request, form_fields) if response: return response try: video = SJContent.objects.get(id=request.POST['video'], content_type='video') settings = video.settings if 'views' not in settings: settings['views'] = 0 settings['views'] += 1 video.settings = settings video.save() except: return response_error('NO SUCH VIDEO') return response_success('VIEWED\t%s' % request.POST['video']) @require_POST def api_video_like(request): """ Like video. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['video'] response = check_form_fields(request, form_fields) if response: return response try: video = SJContent.objects.get(id=request.POST['video'], content_type='video') if not SJLike.objects.filter(user=user, content=video): settings = video.settings if 'likes' not in settings: settings['likes'] = 0 settings['likes'] += 1 video.settings = settings video.save() autor_profile = video.user.get_profile() autor_profile.score += 1 autor_profile.save() like = SJLike.objects.create(user=user, datetime=datetime.now(), content=video) except: return response_error('NO SUCH VIDEO') return response_success('LIKED\t%s' % request.POST['video']) @require_POST def api_video_unlike(request): """ Unlike video. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['video'] response = check_form_fields(request, form_fields) if response: return response try: video = SJContent.objects.get(id=request.POST['video'], content_type='video') likes = SJLike.objects.filter(user=user, content=video) if likes: settings = video.settings if 'likes' not in settings: settings['likes'] = 0 autor_profile = video.user.get_profile() for like in likes: settings['likes'] -= 1 autor_profile.score -= 1 like.delete() video.settings = settings video.save() autor_profile.save() except: return response_error('NO SUCH VIDEO') return response_success('UNLIKED\t%s' % request.POST['video']) @require_POST def api_video_remove(request): """ Remove video view. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() if user_profile.access < ACCESS_MODERATOR: return response_error('INSUFFICIENT ACCESS') form_fields = ['video', 'room'] response = check_form_fields(request, form_fields) if response: return response try: room = SJRoom.objects.get(name=request.POST['room']) except: return response_error('NO ROOM') try: video = SJContent.objects.get(id=request.POST['video'], content_type='video', room=room) settings = video.settings settings['removed'] = 1 video.settings = settings video.save() except: return response_error('NO SUCH VIDEO') return response_success('%s\tREMOVED' % request.POST['video']) @require_POST def api_video_search(request): """ Search video view. Private API """ user = request.user if not user.is_authenticated(): return response_error('NO LOGGED IN') user_profile = user.get_profile() form_fields = ['q'] response = check_form_fields(request, form_fields) if response: return response start = 0 if 'start' in request.POST and is_number(request.POST['start']): start = int(request.POST['start']) limit = 10 if 'limit' in request.POST and is_number(request.POST['limit']): limit = int(request.POST['limit']) if limit > 100: limit = 100 videos = SJContent.objects.filter(content_type='video') words = {} videos_by_url = {} videos_by_id = {} for video in videos: settings = video.settings url = settings.get('url', '') likes = SJLike.objects.filter(content=video).count() username = video.user.username if url in videos_by_url: videos_by_url[url]['score'] += likes if username not in videos_by_url[url]['users']: videos_by_url[url]['users'].append(username) continue settings['id'] = video.id settings['users'] = [username] settings['score'] = likes if 'thumbnail' not in settings: settings['thumbnail'] = '' videos_by_url[url] = settings videos_by_id[video.id] = settings terms = re.split(r'\W+', settings['title']) terms.extend(settings['users']) for term in terms: term = term.lower() if len(term) >= 2: if term not in words: words[term] = [] words[term].append(settings['id']) terms = re.split(r'\W+', request.POST['q'].lower()) match = {} for term in terms: if term in words: for videoid in words[term]: if videoid not in match: match[videoid] = 1 else: match[videoid] += 1 results = [] count = 0 for videoid in sorted(sorted(match, key=lambda x: videos_by_id[x]['score'], reverse=True), key=lambda x: match[x], reverse=True): count += 1 if count > limit: break if count < start: continue settings = videos_by_id[videoid] results.append(settings) response = response_success(message='') for result in results: response.write('%s\n' % ( '\t'.join([str(result['id']), str(result['score']), result['users'][0], str(len(result['users'])), result['title'], result['url'], result['thumbnail']]) )) count = len(match) if start == 0: search = SJSearch(user=user, datetime=datetime.now()) settings = { 'terms': request.POST['q'], 'count': count, } if count: settings['url']= results[0]['url'] settings['title'] = results[0]['title'] else: settings['url']= '' settings['title'] = '' search.settings = settings search.save() return response # # Common views # def stats(request): """ View statistics """ uptime = str(datetime.now() - settings.START_TIME) videos_today = SJContent.objects.filter(content_type='video', datetime__gt=yesterday_datetime()).count() videos_total = SJContent.objects.filter(content_type='video').count() likes_today = SJLike.objects.filter(content__content_type='video', datetime__gt=yesterday_datetime()).count() likes_total = SJLike.objects.filter(content__content_type='video').count() users_total = auth.models.User.objects.filter(is_active=True).count() users_today = auth.models.User.objects.filter(is_active=True, last_login__gt=yesterday_datetime()) try: main_room = SJRoom.objects.get(name='main') users_in_main_room = main_room.users.all() except: users_in_main_room = [] new_users_today = auth.models.User.objects.filter(is_active=True, date_joined__gt=yesterday_datetime()).order_by('-date_joined') rooms_total = SJRoom.objects.all().count() main_room_peak = len(users_in_main_room) return render_to_response('stats.html', {'users_total': users_total, 'users_today': users_today, 'new_users_today': new_users_today, 'videos_total': videos_total, 'videos_today': videos_today, 'likes_total': likes_total, 'likes_today': likes_today, 'rooms_total': rooms_total, 'main_room_peak': main_room_peak, 'users_in_main_room': users_in_main_room, 'uptime': uptime}) def redirect(request): """ Permanent redirect """ response = HttpResponsePermanentRedirect(redirect_to='http://scannerjammer.fm') template = loader.get_template('redirect.html') response.write(template.render(Context())) return response