def clean(self): task = self.cleaned_data['task'] assignee = self.cleaned_data.get('assignee', -1) if assignee != -1: # There are a bunch of edge cases here that we need to check. unassigning_from_self = ( not assignee ) and task.assignee and task.assignee.id == self.user.id assigning_to_self = assignee and self.user.id == assignee.id can_assign_to_other_people = can_assign_task(task, self.user) # Users can always unassign a task from themselves. if not unassigning_from_self: # They can also assign a task TO themselves, assuming they can # perform it (which is checked further down). if not assigning_to_self: # Otherwise they must have assign permissions in the team. if not can_assign_to_other_people: raise forms.ValidationError( _(u'You do not have permission to assign this task.' )) if assignee is None: return self.cleaned_data else: if not can_perform_task(assignee, task): raise forms.ValidationError( _(u'This user cannot perform that task.')) return self.cleaned_data
def _check_team_video_locking(self, user, video_id, language_code, is_translation, mode, is_edit): """Check whether the a team prevents the user from editing the subs. Returns a dict appropriate for sending back if the user should be prevented from editing them, or None if the user can safely edit. """ video = models.Video.objects.get(video_id=video_id) team_video = video.get_team_video() if not team_video: # If there's no team video to worry about, just bail early. return None if team_video.team.is_visible: message = _( u"These subtitles are moderated. See the %s team page for information on how to contribute." % str(team_video.team)) else: message = _(u"Sorry, these subtitles are privately moderated.") # Check that there are no open tasks for this action. tasks = team_video.task_set.incomplete().filter( language__in=[language_code, '']) if tasks: task = tasks[0] # can_assign verify if the user has permission to either # 1. assign the task to himself # 2. do the task himself (the task is assigned to him) if not user.is_authenticated() or ( task.assignee and task.assignee != user) or ( not task.assignee and not can_assign_task(task, user)): return { "can_edit": False, "locked_by": str(task.assignee or task.team), "message": message } # Check that the team's policies don't prevent the action. if mode not in ['review', 'approve']: if is_translation: can_edit = can_create_and_edit_translations( user, team_video, language_code) else: can_edit = can_create_and_edit_subtitles( user, team_video, language_code) if not can_edit: return { "can_edit": False, "locked_by": str(team_video.team), "message": message }
def assign_task_for_editor(video, language_code, user): team_video = video.get_team_video() if team_video is None: return None task_set = team_video.task_set.incomplete().filter(language=language_code) tasks = list(task_set[:1]) if tasks: task = tasks[0] if task.assignee is None and can_assign_task(task, user): task.assignee = user task.save() if task.assignee != user: return _("Another user is currently performing " "the %s task for these subtitles" % task.get_type_display())
def _complete_task(user, video, subtitle_language, saved_version, approved): team_video = video.get_team_video() task = (team_video.task_set.incomplete_review_or_approve().get( language=subtitle_language.language_code)) if task.assignee is None and can_assign_task(task, user): task.assignee = user elif task.assignee != user: raise ValueError("Task not assigned to user") task.new_subtitle_version = subtitle_language.get_tip() task.approved = approved task.complete() if saved_version is None: if saved_version is None: version_id = None else: version_id = saved_version.id video_changed_tasks.delay(team_video.video_id, version_id)
def _handle_outstanding_tasks(outstanding_tasks, version, team_video, committer, complete): """Handle any existing tasks for this subtitle addition.""" from teams.permissions import can_assign_task language_code = version.language_code # There are tasks for this video. If this version isn't published yet, it # belongs to those tasks, so update them. if version.visibility != 'public': outstanding_tasks.update(new_subtitle_version=version, language=language_code) # There may be existing subtitle/translate tasks. outstanding_subtrans_tasks = ( team_video.task_set.incomplete_subtitle_or_translate() .filter(language=language_code) ) if outstanding_subtrans_tasks.exists(): for task in outstanding_subtrans_tasks.all(): # If there are any outstanding subtitle/translate tasks that are # unassigned, we can go ahead and assign them to the committer (as long # as they have permission to do so). if not task.assignee and committer and can_assign_task(task, committer): task.assignee = committer # We save here only if the subtitles are not complete, because # .complete() actually saves the task too. if not complete: task.save() # Also, if the subtitles are complete, we can mark that outstanding # subtitle/translate task as complete. if complete: task.new_subtitle_version = version task.complete()
def assign_task_for_editor(self): """Try to assign any unassigned tasks to our user. If we can't assign the task, return False. """ if self.team_video is None: return True task_set = self.team_video.task_set.incomplete().filter( language=self.language_code) tasks = list(task_set[:1]) if tasks: task = tasks[0] if task.assignee is None and can_assign_task(task, self.user): task.assignee = self.user task.set_expiration() task.save() if task.assignee != self.user: msg = fmt(_("Another user is currently performing " "the %(task_type)s task for these subtitles"), task_type=task.get_type_display()) messages.error(self.request, msg) return False return True
def verify_tasks(self, is_complete): video = self.cleaned_data['video'] language = self.cleaned_data['language'] team_video = video.get_team_video() if team_video: tasks = team_video.task_set.incomplete_subtitle_or_translate( ).filter(language__in=[language, '']) if tasks.exists(): task = tasks.get() if not task.assignee and self.user and can_assign_task( task, self.user): task.assignee = self.user # we save only if is_complete because # .complete() actually saves the task too if not is_complete: task.save() if is_complete: task.complete()
def clean(self): video = self.cleaned_data['video'] language = self.cleaned_data['language'] video_language = self.cleaned_data['video_language'] subtitle_language = video.subtitle_language(language) # first verify if this language for this video already exists. # if exists, verify if it's not writelocked if subtitle_language: if subtitle_language.is_writelocked and subtitle_language.writelock_owner != self.user: raise forms.ValidationError( _(u"Sorry, we can't upload your subtitles because work on this language is already in progress." )) # we can't let the user upload a subtitle to a language that already # have dependents. that will fork the dependents and make everything break. # see sifter #1075 if video.subtitlelanguage_set.filter( standard_language=subtitle_language).exists(): for language in video.subtitlelanguage_set.filter( standard_language=subtitle_language): # if it exists, let's verify if the version is not empty if language.latest_subtitles(public_only=False): raise forms.ValidationError( _(u"Sorry, we cannot upload subtitles for this language because this would ruin translations made from it" )) team_video = video.get_team_video() if team_video: blocking_tasks = team_video.task_set.incomplete_subtitle_or_translate( ).filter(language__in=[language, '']) if blocking_tasks.exists(): task = blocking_tasks.get() # only block if the user can't assign the task # aka he can't do himself or he can't actually # assign it to himself. # also block if the task is assigned to another user if (task.assignee and task.assignee != self.user) or ( not task.assignee and not can_assign_task(task, self.user)): raise forms.ValidationError( _(u"Sorry, we can't upload your subtitles because work on this language is already in progress." )) # Now we know that there are no transcribe/translate tasks that # should block this upload. # # However, if there are any review/approve tasks open they should # block it, even if the user is the assignee. # # TODO: Remove this restriction? blocking_tasks = team_video.task_set.incomplete_review_or_approve( ).filter(language=language) if blocking_tasks.exists(): raise forms.ValidationError( _(u"Sorry, we can't upload your subtitles because a draft for this language is already in moderation." )) # There are no tasks for this video that should block the upload. # The last thing to check is that the team's transcription policy doesn't block this. if video_language and (not subtitle_language or subtitle_language.is_original): if not can_create_and_edit_subtitles(self.user, team_video, language): raise forms.ValidationError( _(u"Sorry, we can't upload your subtitles because this language is moderated and you don't have sufficient permission." )) else: if not can_create_and_edit_translations( self.user, team_video, language): raise forms.ValidationError( _(u"Sorry, we can't upload your subtitles because this language is moderated and you don't have sufficient permission." )) return self.cleaned_data