from django.shortcuts import render from django.contrib.auth.decorators import login_required from django.http import HttpResponseBadRequest, JsonResponse, HttpResponse from .models import SyncTask from .forms import SyncTaskForm from .jobs import sync_douban_job import tempfile import os from threading import Thread import openpyxl from django.utils.datastructures import MultiValueDictKeyError from openpyxl.utils.exceptions import InvalidFileException from zipfile import BadZipFile @login_required def sync_douban(request): """ Sync douban data from .xlsx file generated by doufen """ if request.method == 'POST': # validate sunmitted data try: uploaded_file = request.FILES['xlsx'] wb = openpyxl.open(uploaded_file, read_only=True, data_only=True, keep_links=False) wb.close() except (MultiValueDictKeyError, InvalidFileException, BadZipFile) as e : # raise e return HttpResponseBadRequest(content="invalid excel file") form = SyncTaskForm(request.POST) if form.is_valid(): # stop all preivous task SyncTask.objects.filter(user=request.user, is_finished=False).update(is_finished=True) form.save() temp_dir = tempfile.TemporaryDirectory() filename = os.path.join(temp_dir.name, uploaded_file.name) with open(filename, 'wb+') as destination: for chunk in uploaded_file.chunks(): destination.write(chunk) task = Thread( target=sync_douban_job, args=(form.instance, request.user, filename, temp_dir), daemon=True ) task.start() return HttpResponse(status=204) else: return HttpResponseBadRequest() else: return HttpResponseBadRequest() @login_required def query_progress(request): task = request.user.user_synctasks.order_by('-id').first() if task is not None: return JsonResponse({ 'progress': task.get_progress() }) else: return JsonResponse() def query_last_task(request): task = request.user.user_synctasks.order_by('-id').first() if task is not None: return JsonResponse({ 'total_items': task.total_items, 'success_items': task.success_items, 'finished_items': task.finished_items, 'status': task.get_status_emoji(), 'is_finished': task.is_finished, 'failed_urls': task.failed_urls, 'ended_time': task.ended_time if task.is_finished else None, }) else: return JsonResponse()