views.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. from django.shortcuts import render, get_object_or_404, redirect
  2. from django.views import generic
  3. from django.urls import reverse
  4. from django.contrib.auth.decorators import login_required
  5. import hashlib, uuid
  6. from os.path import splitext
  7. import logging
  8. logger = logging.getLogger('django')
  9. from .models import Media
  10. from .forms import MediaForm, UploadForm
  11. # Create your views here.
  12. class IndexView(generic.ListView):
  13. model = Media
  14. def get_queryset(self):
  15. return Media.objects.order_by('-pub_date')
  16. class TagIndex(generic.ListView):
  17. model = Media
  18. def get_queryset(self):
  19. return Media.objects.filter(tags__slug__in=[self.kwargs['slug']])
  20. class DetailView(generic.DetailView):
  21. model = Media
  22. def chunked_upload(request):
  23. model = Media
  24. return render(request, 'mediaconvert/chunked_upload.html')
  25. ''' Turn this into an UpdateView? '''
  26. @login_required
  27. def media_edit(request, pk):
  28. media = get_object_or_404(Media, pk=pk)
  29. if request.method == "POST":
  30. form = MediaForm(request.POST, instance=media)
  31. if form.is_valid():
  32. if 'delete' in request.POST:
  33. user = media.user
  34. media.delete()
  35. return redirect('accounts:detail', pk=user.pk)
  36. media = form.save()
  37. return redirect('media_detail', pk=media.pk)
  38. else:
  39. form = MediaForm(instance=media)
  40. return render(request, 'mediaconvert/media_edit.html', {'form': form})
  41. def handle_uploaded_file(request, f, uri=None):
  42. if uri is None:
  43. uri = uuid.uuid4().hex
  44. logger.info('Logged in as %s' % request.user)
  45. return Media.objects.create(user=request.user, uri=uri, title=splitext(f.name)[0], upload=f)
  46. @login_required
  47. def media_new(request):
  48. if request.method == "POST":
  49. logger.info('Upload received: %s' % request.POST)
  50. logger.info('Files: %s' % request.FILES)
  51. form = UploadForm(request.POST, request.FILES)
  52. if form.is_valid():
  53. files = request.FILES.getlist('chunked_upload')
  54. logger.info('Receiving %d files' % len(files))
  55. for f in files:
  56. uploaded_file = handle_uploaded_file(request, f)
  57. logger.info('Received file: %s' % uploaded_file)
  58. logger.info('Received all files')
  59. if len(files) > 1:
  60. logger.info('Redirecting to account page')
  61. return redirect('accounts:detail', pk=request.user.pk)
  62. else:
  63. logger.info('Redirecting to single media page')
  64. return redirect('media_detail', pk=uploaded_file.pk)
  65. else:
  66. form = UploadForm()
  67. return render(request, 'mediaconvert/media_new.html', {'form': form})
  68. from .models import MediaChunkedUpload
  69. from chunked_upload.views import ChunkedUploadView, ChunkedUploadCompleteView
  70. class MediaChunkedUploadView(ChunkedUploadView):
  71. model = MediaChunkedUpload
  72. field_name = 'chunked_upload'
  73. # def check_permissions(self, request):
  74. # # by passing here we allow non-authenticated users to upload
  75. # pass
  76. def hash_for_file(hasher, f, block_size=100*1024):
  77. h = hasher()
  78. ''' Record the current position in the file object '''
  79. pos = f.tell()
  80. ''' Seek to 0 to calculate the hash properly (the whole file) '''
  81. f.seek(0)
  82. while True:
  83. data = f.read(block_size)
  84. logger.info('reading %s bytes, found %s bytes' % (block_size, len(data)))
  85. if not data:
  86. break
  87. h.update(data)
  88. ''' Return to the original position '''
  89. f.seek(pos)
  90. logger.info('hash calculated to %s' % h.hexdigest())
  91. return h
  92. class MediaChunkedUploadCompleteView(ChunkedUploadCompleteView):
  93. model = MediaChunkedUpload
  94. uploaded = None
  95. # def check_permissions(self, request):
  96. # # by passing here we allow non-authenticated users to upload
  97. # pass
  98. def on_completion(self, uploaded_file, request):
  99. self.uploaded = handle_uploaded_file(request, uploaded_file, uri=request.POST.get('upload_id'))
  100. logger.info('File upload completed')
  101. def get_response_data(self, chunked_upload, request):
  102. return {
  103. 'message': ("You successfully uploaded '%s' (%s bytes)!" %
  104. (chunked_upload.filename, chunked_upload.offset)),
  105. 'location': reverse('media_edit', kwargs={'pk': self.uploaded.pk}),
  106. }