def voiceslots_match(self, slot, request): vs = self.voiceslots().filter( verbiage=slot.verbiage, bravo_checksum=slot.bravo_checksum).exclude(pk=slot.pk).exclude( status=VoiceSlot.MISSING) for s in vs: s.status = slot.status if s.status == VoiceSlot.PASS: a = Action.objects.filter( scope__voiceslot=slot, type=Action.TESTER_PASS_SLOT).order_by('-time')[0] Action.log(a.actor, Action.AUTO_PASS_SLOT, 'Slot passed as identical to {0}'.format(slot.name), s) elif s.status == VoiceSlot.FAIL: a = Action.objects.filter( scope__voiceslot=slot, type=Action.TESTER_FAIL_SLOT).order_by('-time')[0] Action.log( a.actor, Action.AUTO_FAIL_SLOT, u'{0} (duplicate of {1})'.format(a.description, a.scope.voiceslot.name), s) s.save() return vs.count()
def failed(request, pid): if request.method == 'GET': if request.GET.get('export', False) == 'csv': return contexts.failed_csv(get_object_or_404(Project, pk=pid), HttpResponse(content_type='text/csv')) #Defective defective = [] project = get_object_or_404(Project, pk=pid) failing_slots = project.voiceslots().filter(status=VoiceSlot.FAIL) for slot in failing_slots: action = Action.objects.filter( scope__voiceslot=slot, type__in=[Action.TESTER_FAIL_SLOT, Action.AUTO_FAIL_SLOT]).latest('time') temp = { 'name': slot.name, 'language': slot.language.name, 'path': slot.filepath(), 'test_time': action.time, 'fail_note': action.description } defective.append(temp) context = RequestContext(request, { 'project': project, 'project_defective': defective }) Action.log(request.user, Action.REPORT_GENERATION, 'Viewed failed report dashboard', project) return render(request, "reports/failed.html", context) return HttpResponseNotFound()
def test_voiceslot_action_success(self): user = User.objects.first() Action.log(user, Action.TESTER_PASS_SLOT, u"'sup?", VoiceSlot.objects.first()) a = Action.objects.get(description=u"'sup?") self.assertEqual(a.scope.voiceslot, VoiceSlot.objects.first()) self.assertEqual(a.scope.language, Language.objects.first()) self.assertEqual(a.scope.project, Project.objects.first())
def test_project_voiceslots_fail(self): Action.log(self.user, Action.TESTER_FAIL_SLOT, self.description, self.voiceslot_fail) response = self.client.get(reverse('reports:failed', args=[self.project.id, ]), ) self.assertContains(response, self.voiceslot_fail.name) self.assertContains(response, self.description)
def test_project_progress_voiceslots_auto_fail(self): Action.log(self.user, Action.AUTO_FAIL_SLOT, self.description, self.voiceslot) self.action = Action.objects.get(actor=self.user) response = self.client.get(reverse('reports:report_project', args=[self.project.id, ]), follow=True) self.assertEqual(response.status_code, 200)
def join_project(request, pid): if request.method == 'GET': p = get_object_or_404(Project, pk=pid) page = request.GET.get('page', '') p.users.add(request.user) p.save() Action.log(request.user, Action.TESTER_JOIN_PROJECT, u'Joined project', p) messages.info(request, "You joined the project!") if page == "home": return redirect("core:home") elif page == "projects": return redirect("projects:projects") return redirect("projects:project", pid=pid) return HttpResponseNotFound()
def archive_project(request, pid): if request.method == 'GET': p = get_object_or_404(Project, pk=pid) action = Action.ARCHIVE_PROJECT note = 'Archive Project.' if p.status == Project.TESTING: p.status = Project.CLOSED elif p.status == Project.CLOSED: p.status = Project.TESTING action = Action.UN_ARCHIVE_PROJECT note = 'Un Archive Project.' p.save() Action.log(request.user, action, note, p) return redirect("projects:project", pid)
def leave_project(request, pid): if request.method == 'GET': p = get_object_or_404(Project, pk=pid) page = request.GET.get('page', '') p.users.remove(request.user) p.save() Action.log(request.user, Action.TESTER_LEAVE_PROJECT, u'Left project', p) messages.info(request, "You left the project") if page == "home": return redirect("core:home") elif page == "projects": return redirect("projects:projects") return redirect("projects:project", pid=pid) return HttpResponseNotFound()
def fetch(request, pid): if request.method == 'GET': p = get_object_or_404(Project, pk=pid) if p.bravo_server: try: with pysftp.Connection( p.bravo_server.address, username=p.bravo_server.account, private_key=settings.PRIVATE_KEY) as sftp: result = helpers.fetch_slots_from_server( p, sftp, request.user) if result['valid']: messages.success(request, result["message"]) Action.log(request.user, Action.UPDATE_FILE_STATUSES, 'File status update ran', p) else: messages.danger(request, result['message']) return redirect("projects:project", pid) except pysftp.ConnectionException: messages.danger( request, "Connection error to server \"{0}\"".format( p.bravo_server.name)) return redirect("projects:project", pid) except pysftp.CredentialException: messages.danger( request, "Credentials error to server \"{0}\"".format( p.bravo_server.name)) return redirect("projects:project", pid) except pysftp.AuthenticationException: messages.danger( request, "Authentication error to server \"{0}\"".format( p.bravo_server.name)) return redirect("projects:project", pid) except pysftp.SSHException: messages.danger( request, "SSH error to server \"{0}\"".format(p.bravo_server.name)) return redirect("projects:project", pid) messages.danger(request, "No server associated with project") return redirect("projects:project", pid) return HttpResponseNotFound()
def able_update_file_status(request, p): try: with pysftp.Connection(p.bravo_server.address, username=p.bravo_server.account, private_key=settings.PRIVATE_KEY) as sftp: result = helpers.fetch_slots_from_server(p, sftp, request.user) if result['valid']: messages.success(request, result["message"]) Action.log(request.user, Action.UPDATE_FILE_STATUSES, 'File status update ran', p) return True else: messages.danger(request, result['message']) return False except (pysftp.ConnectionException, pysftp.CredentialException, pysftp.AuthenticationException, pysftp.SSHException): messages.danger( request, "Connection error to server \"{0}\"".format(p.bravo_server.name)) return False
def verify_file_transfer(request, pid): """View to identify potential problems with file transfer from Bravo to Preprod""" p = get_object_or_404(Project, pk=pid) if request.method == 'GET': # Send list of Producer applications on GET request. apps = p.get_applications() json_data = json.dumps({'apps': apps}) return HttpResponse(json_data, content_type="application/json") elif request.method == 'POST': status = ElpisStatus.objects.get_or_create(project=p)[0] if status.running: return HttpResponse(json.dumps({ 'success': False, 'message': 'Task already running' }), content_type="application/json") apps = request.POST.getlist('applications') query_item = verify_file_transfer_task.delay(project_id=pid, apps=apps) status.query_id = query_item status.running = True status.save() Action.log(request.user, Action.ELPIS_RUN, 'Elpis run initiated', p) return HttpResponse(json.dumps({'success': True}), content_type="application/json")
def initiate_status_update(request, pid): """ Kicks off the request from "Update File Statuses" """ if not request.method == "POST": raise Http404 project = Project.objects.get(pk=pid) status = UpdateStatus.objects.get_or_create(project=project)[0] if status.running: return HttpResponse(json.dumps({ 'success': False, 'message': 'Task already running' }), content_type="application/json") query_item = update_file_statuses.delay(project_id=pid, user_id=request.user.pk) status.query_id = query_item status.running = True status.save() Action.log(request.user, Action.UPDATE_FILE_STATUSES, 'Updated file statuses', Project.objects.get(pk=pid)) return HttpResponse(json.dumps({'success': True}), content_type="application/json")
def missing(request, pid): if request.method == 'GET': if request.GET.get('export', False) == 'csv': return contexts.missing_csv(get_object_or_404(Project, pk=pid), HttpResponse(content_type='text/csv')) # Missing missing = [] project = get_object_or_404(Project, pk=pid) missing_slots = project.voiceslots_missing().order_by('path', 'name') for item in missing_slots: temp = {'filepath': item.filepath, 'language': item.language.name} missing.append(temp) context = RequestContext(request, { 'project': project, 'missing_slots': missing }) Action.log(request.user, Action.REPORT_GENERATION, 'Viewed missing report dashboard', project) return render(request, "reports/missing.html", context) return HttpResponseNotFound()
def queue(request, pid): if request.method == 'GET': # check if voice slot already listened finish_listen = request.GET.get('listened', 'notyet') fail_select = request.GET.get('fail_select', False) p = get_object_or_404(Project, pk=pid) # check if update file status from bravo server if not p.voiceslots().filter(status=VoiceSlot.READY).exists(): messages.danger(request, 'No files are pending test.') return redirect('projects:project', pid=pid) lang = get_object_or_404(Language, project=p, name=request.GET.get('language', '__malformed').lower()) slots_out = request.user.voiceslot_set.all() # TODO check this block if slots_out.count() > 0: slot = slots_out.order_by('?').first() if slot.language.pk == lang.pk: try: slot_file = slot.download() except IOError: slot.status = VoiceSlot.MISSING slot.save() return queue(request, pid) return render( request, "projects/testslot.html", contexts.context_testslot(request.user_agent.browser, p, slot, slot_file, finish_listen, fail_select)) else: for slot in slots_out: slot.check_in(request.user) slot = lang.voiceslot_set.filter( status=VoiceSlot.READY, checked_out=False).order_by('?').first() # check if all voice slots have been tested if not slot: messages.warning(request, 'No new voice slots available to be tested') return redirect('projects:project', pid=pid) # check if project has default bravo server if not p.bravo_server: messages.warning(request, 'Please set default bravo server') return redirect('projects:project', pid=pid) try: slot_file = slot.download() except IOError: slot.status = VoiceSlot.MISSING slot.save() return queue(request, pid) return render( request, "projects/testslot.html", contexts.context_testslot(request.user_agent.browser, p, slot, slot_file, finish_listen, fail_select)) elif request.method == 'POST': p = get_object_or_404(Project, pk=pid) lang = get_object_or_404(Language, project=p, name=request.GET.get('language', '__malformed').lower()) tested_slot = get_object_or_404(VoiceSlot, pk=request.POST.get('slot-id', -1)) if "cancel_test" in request.POST: tested_slot.check_in(request.user) return redirect("projects:project", pid=pid) elif "submit_test" in request.POST: test_result = request.POST.get('slot_status', False) finish_listen_post = request.POST.get('finish_listen', 'notyet') already_listen_post = request.GET.get('listened', 'notyet') fail_select = request.GET.get('fail_select', False) # finish_listen to check if finish listened without Pass/Fail selection if not test_result and (finish_listen_post == 'heard' or already_listen_post == 'heard') and fail_select != 'selected': messages.danger(request, "Please enter a pass or fail") return HttpResponseRedirect( reverse("projects:queue", args=(p.pk, )) + "?language=" + lang.name + '&listened=heard') elif test_result == 'pass': tested_slot.status = VoiceSlot.PASS tested_slot.check_in(request.user) tested_slot.save() Action.log( request.user, Action.TESTER_PASS_SLOT, '{0} passed in queue testing'.format(tested_slot.name), tested_slot) # do updates to files here and get count for p pass count = p.voiceslots_match(tested_slot, request) else: if not request.POST.get('notes', False): messages.danger(request, "Please provide notes on test failure") return HttpResponseRedirect( reverse("projects:queue", args=(p.pk, )) + "?language=" + lang.name + '&listened=heard&fail_select=selected') tested_slot.status = VoiceSlot.FAIL tested_slot.check_in(request.user) tested_slot.save() Action.log(request.user, Action.TESTER_FAIL_SLOT, request.POST['notes'], tested_slot) # do updates to files here and get count for p failure count = p.voiceslots_match(tested_slot, request) p.failure_count += 1 p.tests_run += 1 p.save() if count > 0: messages.success(request, "{0} matching slots updated".format(count)) slot_filter = lang.voiceslot_set.filter(status=VoiceSlot.READY, checked_out=False) if slot_filter.count() > 0: slot = slot_filter.order_by('?').first() else: ten_minutes_ago = datetime.now() - timedelta(minutes=10) slot_filter = lang.voiceslot_set.filter( status=VoiceSlot.READY, checked_out=True, checked_out_time__lte=ten_minutes_ago) if slot_filter.count() > 0: slot = slot_filter.order_by('?').first() else: messages.success( request, "All slots in this language are tested or recently checked out for testing." ) return redirect("projects:project", pid=pid) slot_file = slot.download() # reset if finish listen to not yet #finish_listen = 'notyet' #fail_select = False #return render(request, "projects/testslot.html", contexts.context_testslot(request.user_agent.browser, p, slot, slot_file, finish_listen, fail_select)) return HttpResponseRedirect( reverse("projects:queue", args=(p.pk, )) + "?language=" + lang.name) else: return HttpResponseNotFound()
def report_project(request, pid): if request.method == 'GET': project = get_object_or_404(Project, pk=pid) if not project.root_path: messages.danger(request, 'Please set project root path') return redirect('reports:reports') vuids = project.vuid_set.all() if vuids.count() == 0: messages.danger(request, 'Please upload prompt list file') return redirect('reports:reports') if not project.voiceslots().filter(status__in=[ VoiceSlot.READY, VoiceSlot.PASS, VoiceSlot.FAIL, VoiceSlot.MISSING ]).exists(): messages.danger(request, 'Please update file statuses from bravo server') return redirect('reports:reports') # Get VUID upload_date vuid_upload_date = None if vuids.count() == 1: vuid_upload_date = project.vuid_set.all()[0].upload_date elif vuids.count() > 1: # find least vuid upload date vuid_upload_date = project.vuid_set.all()[0].upload_date for vuid in project.vuid_set.all(): if vuid.upload_date < vuid_upload_date: vuid_upload_date = vuid.upload_date # Progress of project # First check vuid upload_date if vuid_upload_date: # Second check Actions type outputs = { 'date': [], 'fail': [], 'pass': [], 'new': [], 'missing': [] } try: end = date.fromtimestamp(float( request.GET.get('end'))) + timedelta(days=1) except (TypeError, ValueError): end = datetime.now().date() + timedelta(days=1) try: start = date.fromtimestamp(float( request.GET.get('start'))) + timedelta(days=1) except (TypeError, ValueError): start = end - timedelta(days=10) start_original = start while start <= end: statuses = project.status_as_of( time.mktime(start.timetuple()) - 1) #print start, end, statuses if start == start_original: start += timedelta(days=1) continue outputs['date'].append( (start - timedelta(days=1)).strftime("%Y-%m-%d")) outputs['fail'].append( int(statuses[Action.TESTER_FAIL_SLOT] + statuses[Action.AUTO_FAIL_SLOT])) outputs['pass'].append( int(statuses[Action.TESTER_PASS_SLOT] + statuses[Action.AUTO_PASS_SLOT])) outputs['new'].append(int(statuses[Action.AUTO_NEW_SLOT])) outputs['missing'].append( int(statuses[Action.AUTO_MISSING_SLOT])) start += timedelta(days=1) else: outputs = None context = RequestContext( request, { 'project': project, 'project_progress': outputs, 'start': float( request.GET.get('start', time.mktime(start_original.timetuple()))), 'end': time.mktime(end.timetuple()) - 3601, 'feed': Action.objects.filter( scope__project=project).order_by('-time')[0:10] }) Action.log(request.user, Action.REPORT_GENERATION, 'Viewed progress report dashboard', project) return render(request, "reports/report_project.html", context)
def testslot(request, pid, vsid): if request.method == 'GET': finish_listen = request.GET.get('listened', 'notyet') fail_select = request.GET.get('fail_select', False) p = get_object_or_404(Project, pk=pid) slot = get_object_or_404(VoiceSlot, pk=vsid) if p.bravo_server: try: with pysftp.Connection( p.bravo_server.address, username=p.bravo_server.account, private_key=settings.PRIVATE_KEY) as conn: remote_path = slot.filepath() filename = "{0}.wav".format(str(uuid.uuid4())) filenamezip = filename + ".gz" local_path = os.path.join(settings.MEDIA_ROOT, filename) local_path_zip = os.path.join(settings.MEDIA_ROOT, filenamezip) if conn.exists(remote_path): conn.get(remote_path, local_path) else: conn.get(remote_path + ".gz", local_path_zip) with gzip.open(local_path_zip, 'rb') as in_file: out_file = open(local_path, 'wb') s = in_file.read() with open(local_path, 'w') as f: f.write(s) filepath = settings.MEDIA_URL + filename slot.check_out(request.user) except IOError as e: messages.danger( request, "File missing on server \"{0}\"".format( p.bravo_server.name)) slot.status = VoiceSlot.MISSING slot.save() Action.log(request.user, Action.AUTO_MISSING_SLOT, 'Slot found missing by individual slot test', slot) return redirect("projects:project", pid) except pysftp.ConnectionException: messages.danger( request, "Connection error to server \"{0}\"".format( p.bravo_server.name)) return redirect("projects:project", pid) except pysftp.CredentialException: messages.danger( request, "Credentials error to server \"{0}\"".format( p.bravo_server.name)) return redirect("projects:project", pid) except pysftp.AuthenticationException: messages.danger( request, "Authentication error to server \"{0}\"".format( p.bravo_server.name)) return redirect("projects:project", pid) except pysftp.SSHException: messages.danger( request, "SSH error to server \"{0}\"".format(p.bravo_server.name)) return redirect("projects:project", pid) return render( request, "projects/testslot.html", contexts.context_testslot(request.user_agent.browser, p, slot, filepath, finish_listen, fail_select)) messages.danger(request, "No server associated with project") return redirect("projects:project", pid) return submitslot(request, vsid)
def project(request, pid): if request.method == 'GET': p = get_object_or_404(Project, pk=pid) # status = UpdateStatus.objects.get_or_create(project=p)[0] # if status.running: # status.running = False # status.save() return render( request, "projects/project.html", contexts.context_project( p, server_form=ServerForm( initial={'server': p.current_server_pk()}))) elif request.method == 'POST': messages.danger(request, '1') if "update_server" in request.POST: form = ServerForm(request.POST) p = get_object_or_404(Project, pk=pid) if form.is_valid(): server = form.cleaned_data['server'] if server is None: if p.bravo_server is None: return redirect("projects:project", pid=pid) p.bravo_server = None p.save() else: if p.bravo_server is not None: if server == p.bravo_server.name: return redirect("projects:project", pid=pid) # force update file status from bravo server old_bravo_server = p.bravo_server p.bravo_server = Server.objects.get(name=server) p.save() if not able_update_file_status(request, p): p.bravo_server = old_bravo_server p.save() messages.warning( request, 'Cannot update file status, set Bravo Server back') return redirect("projects:project", pid=pid) Action.log(request.user, Action.UPDATE_BRAVO_SERVER, u'Bravo server updated to ' + unicode(server), p) messages.success(request, "Updated server successfully") return redirect("projects:project", pid=pid) messages.danger(request, "Unable to update server") return render(request, "projects/project.html", contexts.context_project(p, server_form=form)) elif "upload_file" in request.POST: messages.danger(request, '2') form = UploadForm(request.POST, request.FILES) p = get_object_or_404(Project, pk=pid) if form.is_valid(): messages.danger(request, '3') # if user not member in CS, PM, Superuser cannot upload if not (request.user.usersettings.creative_services or request.user.usersettings.project_manager or request.user.is_superuser): messages.danger(request, 'You have no authority to upload.') elif 'file' in request.FILES and request.FILES[ 'file'].name.endswith('.xlsx'): result = helpers.upload_vuid(form.cleaned_data['file'], request.user, p) if result['valid']: messages.success(request, result["message"]) else: messages.danger(request, result['message']) elif 'file' in request.FILES: messages.danger( request, "Invalid file type, unable to upload (must be .xlsx)") return redirect("projects:project", pid=pid) messages.danger(request, "Unable to upload file") return render( request, "projects/project.html", contexts.context_project( p, upload_form=form, server_form=ServerForm( initial={'server': p.current_server_pk()}))) elif "update_root_path" in request.POST: messages.danger(request, '4') form = ProjectRootPathForm(request.POST) p = get_object_or_404(Project, pk=pid) if form.is_valid(): root_path = form.cleaned_data['root_path'] if not os.path.isabs(root_path): messages.danger(request, 'Bravo Server Root Path Format Incorrect') return redirect('projects:project', pid=pid) #remove last slash of root path while root_path and root_path[-1] == '/': root_path = root_path[:-1] if p.root_path and not helpers.verify_update_root_path( p, root_path): messages.danger(request, 'New root path not allowed') return redirect('projects:project', pid=pid) p.root_path = root_path p.save() Action.log( request.user, Action.UPDATE_ROOT_PATH, u'Bravo server root path updated to ' + unicode(root_path), p) messages.success(request, 'Updated Bravo Server Path Successfully') return redirect('projects:project', pid=pid) messages.danger(request, '5') messages.danger( request, 'valid? ' + str(UploadForm(request.POST, request.FILES))) return redirect("projects:project", pid=pid) return HttpResponseNotFound()
def new(request): if request.method == 'GET': return render(request, "projects/new.html", contexts.context_new()) elif request.method == 'POST': if "create_project" in request.POST: form = ProjectForm(request.POST, request.FILES) if form.is_valid(): # Check if default Bravo Server exist try: bravo_server = Server.objects.get(active=True) except Server.DoesNotExist: messages.danger(request, "Please set default Bravo Server first.") return render(request, "projects/new.html", contexts.context_new(form)) n = form.cleaned_data['name'] root_path = form.cleaned_data['root_path'] if root_path and not os.path.isabs(root_path): messages.danger(request, 'Bravo Server Root Path Format Incorrect') return render(request, 'projects/new.html', contexts.context_new(form)) # remove last slash of root path while root_path and root_path[-1] == '/': root_path = root_path[:-1] p = Project(name=n) try: p.full_clean() p.save() p.users.add(request.user) p.bravo_server = bravo_server # set default bravo server p.root_path = root_path p.save() messages.success(request, "Created project") if 'file' in request.FILES and request.FILES[ 'file'].name.endswith('.xlsx'): result = helpers.upload_vuid(form.cleaned_data['file'], request.user, p) if result['valid']: messages.success(request, result["message"]) else: messages.danger(request, result['message']) elif 'file' in request.FILES: messages.danger( request, "Invalid file type, unable to upload (must be .xlsx)" ) Action.log(request.user, Action.CREATE_PROJECT, '{0} created'.format(p.name), p) return redirect("projects:project", pid=p.pk) except ValidationError as e: if 'name' in e.message_dict: messages.danger(request, e.message_dict.get('name')[0]) return render(request, "projects/new.html", contexts.context_new(form)) messages.danger(request, "Unable to create project") return render(request, "projects/new.html", contexts.context_new(form)) return HttpResponseNotFound()
def update_file_statuses(project_id, user_id): """Background process to update file statuses from Bravo server""" try: sleep(1.25) # Stupid fix for a stupid race condition project = Project.objects.get(pk=int(project_id)) status = UpdateStatus.objects.get_or_create(project__pk=project_id)[0] user = User.objects.get(pk=int(user_id)) # Connect to Bravo server and get filenames and md5sums with pysftp.Connection(project.bravo_server.address, username=project.bravo_server.account, private_key=settings.PRIVATE_KEY) as sftp: result = sftp.execute( 'find {0}/ -name "*.wav"'.format(project.root_path) + ' -exec md5sum {} \; -exec stat -c"%Y" {} \;') FileStatus = namedtuple('FileStatus', 'md5 path modified') file_statuses = [] try: for i in range(0, len(result), 2): md5 = result[i].split()[0] filename = ' '.join(result[i].split()[1:]) modified = result[i + 1].strip() file_statuses.append(FileStatus(md5, filename, modified)) except IndexError: print "Update IndexError Result:" print repr(result) # Find and update matching voiceslots slots = project.voiceslots() for fs in file_statuses: if slots.filter(name=fs.path.split('/')[-1][:-4]).exists(): slot_candidates = slots.filter( name=fs.path.split('/')[-1][:-4]) for slot in slot_candidates: if fs.path == slot.filepath(): if slot.status in (VoiceSlot.NEW, VoiceSlot.MISSING, VoiceSlot.READY): slot.bravo_checksum = fs.md5 slot.bravo_time = datetime.utcfromtimestamp( float(fs.modified)).replace(tzinfo=pytz.utc) slot.status = VoiceSlot.READY slot.save() Action.log(user, Action.AUTO_NEW_SLOT, "Slot ready for testing", slot) break elif slot.status in (VoiceSlot.PASS, VoiceSlot.FAIL): if fs.md5 != slot.bravo_checksum: slot.bravo_checksum = fs.md5 slot.bravo_time = datetime.fromtimestamp( float( fs.modified)).replace(tzinfo=pytz.utc) slot.status = VoiceSlot.READY slot.save() Action.log(user, Action.AUTO_NEW_SLOT, "Slot changed and needs retesting", slot) break # Find and mark missing voiceslots vuid_set = set(slots.values_list('name', flat=True)) found_set = set([fs.path.split('/')[-1][:-4] for fs in file_statuses]) missing_set = vuid_set - found_set missing_slots = slots.filter(name__in=list(missing_set)) missing_slots.update(status=VoiceSlot.MISSING) # Hack for files found in the wrong language. No es bueno stragglers = slots.filter(status=VoiceSlot.NEW) stragglers.update(status=VoiceSlot.MISSING) for slot in stragglers: Action.log(user, Action.AUTO_MISSING_SLOT, "Slot not found in update", slot) # Missing period to distinguish for slot in missing_slots: Action.log(user, Action.AUTO_MISSING_SLOT, "Slot not found in update.", slot) status.running = False status.save() except Exception as e: logger = get_task_logger(__name__) logger.error("Celery task failed") logger.error(e) logger.error("Project id: {0}".format(project_id)) sleep(3) try: project = Project.objects.get(pk=int(project_id)) logger.error("Waiting would have fixed this.") except Exception as e: logger.error("Waiting didn't fix it")
def submitslot(request, vsid): if request.method == 'POST': if "submit_test" in request.POST: slot = get_object_or_404(VoiceSlot, pk=vsid) p = slot.language.project slot_status = request.POST.get('slot_status', False) finish_listen_post = request.POST.get('finish_listen', 'notyet') already_listen_post = request.GET.get('listened', 'notyet') fail_select = request.GET.get('fail_select', False) if not slot_status and (finish_listen_post == 'heard' or already_listen_post == 'heard') and fail_select != 'selected': messages.danger(request, "Please enter a pass or fail") # return redirect("projects:testslot", pid=p.pk, vsid=vsid) response = redirect("projects:testslot", pid=p.pk, vsid=vsid) response['Location'] += '?listened=heard' return response if slot_status == 'pass': slot.status = VoiceSlot.PASS slot.check_in(request.user) slot.save() helpers.update_checksum(pid=p.pk, vsid=vsid, user=request.user) Action.log(request.user, Action.TESTER_PASS_SLOT, '{0} passed by manual testing'.format(slot.name), slot) # do updates to files here and get count for p pass count = p.voiceslots_match(slot, request) else: if not request.POST.get('notes', False): messages.danger(request, "Please provide notes on test failure") response = redirect("projects:testslot", pid=p.pk, vsid=vsid) response[ 'Location'] += '?listened=heard&fail_select=selected' return response slot.status = VoiceSlot.FAIL slot.check_in(request.user) slot.save() helpers.update_checksum(pid=p.pk, vsid=vsid, user=request.user) Action.log(request.user, Action.TESTER_FAIL_SLOT, request.POST['notes'], slot) # do updates to files here and get count for p failure count = p.voiceslots_match(slot, request) p.failure_count += 1 p.tests_run += 1 p.save() messages.success( request, u"Tested voice slot \"{0}\", {1} matching slots updated". format(slot.name, count)) return redirect("projects:project", pid=p.pk) elif "cancel_test" in request.POST: slot = get_object_or_404(VoiceSlot, pk=vsid) slot.check_in(request.user) return redirect("projects:project", pid=slot.language.project.pk) return HttpResponseNotFound()