# -*- coding: utf-8 -*- # vi:si:et:sw=4:sts=4:ts=4 from __future__ import division import os.path import re from datetime import datetime from urllib2 import unquote import mimetypes from django import forms from django.core.paginator import Paginator from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.db.models import Q, Avg, Count, Sum from django.http import HttpResponse, Http404 from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404 from django.template import RequestContext from django.conf import settings try: import simplejson as json except ImportError: from django.utils import simplejson as json from oxdjango.decorators import login_required_json from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response from oxdjango.http import HttpFileResponse import ox import models from backend.utils import oxid, parse_path import backend.models #@login_required_json def api_update(request): ''' //both are optional, idea is to have 2 requests first with files, and after that with info for the requested oshashes param data files: [ {oshash:, name:, folder:, oshash:, ctime:, atime:, mtime:, } ] info: {oshash: object} return {'status': {'code': int, 'text': string}, 'data': {info: list, data: list, file: list}} ''' data = json.loads(request.POST['data']) user = request.user response = json_response({'info': [], 'rename': [], 'file': []}) if 'files' in data: all_files = [] for f in data['files']: folder = f['folder'] name = f['name'] oshash = f['oshash'] all_files.append(oshash) same_folder = models.FileInstance.objects.filter(folder=folder, user=user) if same_folder.count() > 0: movie = same_folder[0].file.movie else: movie = None path = os.path.join(folder, name) instance = models.FileInstance.objects.filter(file__oshash=oshash, user=user) if instance.count()>0: instance = instance[0] updated = False for key in ('atime', 'mtime', 'ctime', 'name', 'folder'): if f[key] != getattr(instance, key): setattr(instance, key, f[key]) updated=True if updated: f.save() else: #look if oshash is known file_object = models.File.objects.filter(oshash=oshash) if file_object.count() > 0: file_object = file_object[0] instance = models.FileInstance() instance.file = file_object for key in ('atime', 'mtime', 'ctime', 'name', 'folder'): setattr(instance, key, f[key]) instance.save() #new oshash, add to database else: if not movie: movie_info = parse_path(folder) movie = backend.models.getMovie(movie_info) f = models.File() f.oshash = oshash f.name = name f.movie = movie f.save() response['info'].append(oshash) instance = models.FileInstance() instance.user = user instance.file = f for key in ('atime', 'mtime', 'ctime', 'name', 'folder'): setattr(instance, key, f[key]) instance.save() #remove deleted files #FIXME: can this have any bad consequences? i.e. on the selction of used movie files. models.FileInstance.objects.filter(user=user).exclude(file__oshash__in=all_files).delete() user_profile = user.get_profile() user_profile.files_updated = datetime.now() user_profile.save() if 'info' in data: for oshash in data['info']: info = data['info'][oshash] instance = models.FileInstance.objects.filter(file__oshash=oshash, user=user) if instance.count()>0: instance = instance[0] if not instance.file.info: instance.file.info = info instance.file.save() files = models.FileInstance.objects.filter(user=user, file__available=False) response['data'] = [f.file.oshash for f in files.filter(file__is_video=True)] response['files'] = [f.file.oshash for f in files.filter(file__is_subtitle=True)] return render_to_json_response(response) #@login_required_json #FIXME: is this part of the api or does it have to be outside due to multipart? def api_upload(request): ''' multipart param data oshash: string frame: [] //multipart frames return {'status': {'code': int, 'text': string}, 'data': {info: object, rename: object}} ''' user = request.user f = get_object_or_404(models.File, oshash=request.POST['oshash']) if f.frames.count() == 0 and 'frame' in request.FILES: for frame in request.FILES['frame']: name = frame.name position = float(os.path.splitext(name)[0]) fr = models.Frame(file=f, position=position) fr.save() fr.frame.save(frame, name) response = json_response({}) else: response = json_response(status=403, text='permissino denied') return render_to_json_response(response) class VideoChunkForm(forms.Form): chunk = forms.FileField() chunkId = forms.IntegerField(required=False) done = forms.IntegerField(required=False) @login_required_json def firefogg_upload(request): #handle video upload if request.method == 'POST': #init upload profile = request.POST.get('profile', request.GET['profile']) #FIXME: check for valid profile if 'oshash' in request.POST: #404 if oshash is not know, files must be registered via update api first f = get_object_or_404(models.File, oshash=request.POST['oshash']) stream, created = models.Stream.objects.get_or_create(file=file, profile=profile) if stream.video: #FIXME: check permission here instead of just starting over stream.video.delete() stream.available = False stream.save() response = { #is it possible to no hardcode url here? 'uploadUrl': request.build_absolute_uri('/api/upload/?oshash=%s&profile=%s' % (f.oshash, profile)), 'result': 1 } return render_to_json_response(response) #post next chunk if 'chunk' in request.FILES and 'oshash' in request.GET: print "all chunk now" stream = get_object_or_404(models.Stream, oshash=request.GET['oshash'], profile=profile) form = VideoChunkForm(request.POST, request.FILES) if form.is_valid() and stream.editable(request.user): c = form.cleaned_data['chunk'] chunk_id = form.cleaned_data['chunkId'] response = { 'result': 1, 'resultUrl': request.build_absolute_uri('/') } if not stream.save_chunk(c, chunk_id): response['result'] = -1 elif form.cleaned_data['done']: #FIXME: send message to encode deamon to create derivates instead stream.available = True stream.save() response['result'] = 1 response['done'] = 1 return render_to_json_response(response) print request.GET, request.POST response = json_response(status=400, text='this request requires POST') return render_to_json_response(response) """ @login_required_json def list_files(request): ''' GET list > { "files": { "a41cde31c581e11d": {"path": "E/Example, The/An Example.avi", "size":1646274}, } } ''' response = {} response['files'] = {} qs = models.UserFile.filter(user=request.user) p = Paginator(qs, 1000) for i in p.page_range: page = p.page(i) for f in page.object_list: response['files'][f.movie_file.oshash] = {'path': f.path, 'size': f.movie_file.size} return render_to_json_response(response) def find_files(request): response = {} query = _parse_query(request) response['files'] = {} qs = models.UserFile.filter(user=request.user).filter(movie_file__movie__id__in=query['q']) p = Paginator(qs, 1000) for i in p.page_range: page = p.page(i) for f in page.object_list: response['files'][f.movie_file.oshash] = {'path': f.path, 'size': f.movie_file.size} return render_to_json_response(response) def api_fileInfo(request): ''' param data oshash string return {'status': {'code': int, 'text': string}, 'data': {imdbId:string }} ''' if 'data' in request.POST: oshash = json.loads(request.POST['data']) elif 'oshash' in request.GET: oshash = request.GET['oshash'] f = models.MovieFile.objects.get(oshash=oshash) response = {'data': f.json()} return render_to_json_response(response) def api_subtitles(request): ''' param data oshash string language string subtitle string return if no language is provided: {data: {languages: array}} if language is set: {data: {subtitle: string}} if subtitle is set: saves subtitle for given language ''' if 'data' in request.POST: data = json.loads(request.POST['data']) oshash = data['oshash'] language = data.get('language', None) srt = data.get('subtitle', None) if srt: user = request.user sub = models.Subtitles.objects.get_or_create(user, oshash, language) sub.srt = srt sub.save() else: response = json_response({}) if language: q = models.Subtitles.objects.filter(movie_file__oshash=oshash, language=language) if q.count() > 0: response['data']['subtitle'] = q[0].srt return render_to_json_response(response) l = models.Subtitles.objects.filter(movie_file__oshash=oshash).values('language') response['data']['languages'] = [f['language'] for f in l] return render_to_json_response(response) """