def send_reject_notification(task_pk, sent_back): raise NotImplementedError() from teams.models import Task from videos.models import Action from messages.models import Message try: task = Task.objects.select_related( "team_video__video", "team_video", "assignee", "subtitle_version").get( pk=task_pk) except Task.DoesNotExist: return False if task.new_review_base_version: user = task.new_review_base_version.author else: user = version.author if not user.is_active: return False version = task.get_subtitle_version() subject = ugettext(u"Your subtitles were not accepted") task_language = get_language_label(task.language) reviewer = task.assignee video = task.team_video.video subs_url = "%s%s" % (get_url_base(), reverse("videos:translation_history", kwargs={ 'video_id': video.video_id, 'lang': task.language, 'lang_id': version.subtitle_language.pk, })) reviewer_message_url = "%s%s?user=%s" % ( get_url_base(), reverse("messages:new"), reviewer.username) context = { "team":task.team, "title": version.subtitle_language.get_title(), "user":user, "task_language": task_language, "url_base":get_url_base(), "task":task, "reviewer":reviewer, "note":task.body, "sent_back": sent_back, "subs_url": subs_url, "reviewer_message_url": reviewer_message_url, } msg = None if user.notify_by_message: template_name = "messages/team-task-rejected.txt" msg = Message() msg.message_type = 'S' msg.subject = subject msg.content = render_to_string(template_name,context) msg.user = user msg.object = task.team msg.save() template_name = "messages/email/team-task-rejected.html" email_res = send_templated_email(user, subject, template_name, context) Action.create_rejected_video_handler(version, reviewer) return msg, email_res
def change_title_video(self, video_pk, title, user): title = title.strip() if not user.is_authenticated(): return Error(self.authentication_error_msg) if not title: return Error(_(u'Title can\'t be empty')) try: video = Video.objects.get(pk=video_pk) if title and not video.title or video.is_html5( ) or user.is_superuser: if title != video.title: old_title = video.title_display() video.title = title video.slug = slugify(video.title) video.save() update_search_index.delay(Video, video.pk) Action.change_title_handler(video, user) send_change_title_email.delay(video.id, user and user.id, old_title.encode('utf8'), video.title.encode('utf8')) else: return Error(_(u'Title can\'t be changed for this video')) except Video.DoesNotExist: return Error(_(u'Video does not exist')) return Msg(_(u'Title was changed success'))
def change_title_video(self, video_pk, title, user): title = title.strip() if not user.is_authenticated(): return Error(self.authentication_error_msg) if not title: return Error(_(u'Title can\'t be empty')) try: video = Video.objects.get(pk=video_pk) if title and not video.title or video.is_html5() or user.is_superuser: if title != video.title: old_title = video.title_display() video.title = title video.slug = slugify(video.title) video.save() update_search_index.delay(Video, video.pk) Action.change_title_handler(video, user) send_change_title_email.delay(video.id, user and user.id, old_title.encode('utf8'), video.title.encode('utf8')) else: return Error(_(u'Title can\'t be changed for this video')) except Video.DoesNotExist: return Error(_(u'Video does not exist')) return Msg(_(u'Title was changed success'))
def team_member_new(member_pk): if getattr(settings, "MESSAGES_DISABLED", False): return from messages.models import Message from teams.models import TeamMember member = TeamMember.objects.get(pk=member_pk) if not _team_sends_notification(member.team, 'block_team_member_new_message'): return False from videos.models import Action from teams.models import TeamMember # the feed item should appear on the timeline for all team members # as a team might have thousands of members, this one item has # to show up on all of them Action.create_new_member_handler(member) # notify admins and owners through messages notifiable = TeamMember.objects.filter( team=member.team, role__in=[TeamMember.ROLE_ADMIN, TeamMember.ROLE_OWNER]).exclude(pk=member.pk) for m in notifiable: context = { "new_member": member.user, "team": member.team, "user": m.user, "role": member.role, "url_base": get_url_base(), } body = render_to_string("messages/team-new-member.txt", context) subject = ugettext("%s team has a new member" % (member.team)) if m.user.notify_by_message: msg = Message() msg.subject = subject msg.content = body msg.user = m.user msg.object = m.team msg.save() template_name = "messages/email/team-new-member.html" Meter('templated-emails-sent-by-type.teams.new-member').inc() send_templated_email(m.user, subject, template_name, context) # now send welcome mail to the new member template_name = "messages/team-welcome.txt" context = { "team": member.team, "url_base": get_url_base(), "role": member.role, "user": member.user, } body = render_to_string(template_name, context) msg = Message() msg.subject = ugettext("You've joined the %s team!" % (member.team)) msg.content = body msg.user = member.user msg.object = member.team msg.save() template_name = "messages/email/team-welcome.html" Meter('templated-emails-sent-by-type.teams.welcome').inc() send_templated_email(msg.user, msg.subject, template_name, context)
def test_profile_page(self): video = Video.objects.all()[0] video.title = 'new title' video.save() Action.change_title_handler(video, self.user) self.assertTrue(self.user.action_set.exists()) self._simple_test('profiles:profile', [self.user.id])
def team_member_leave(team_pk, user_pk): if getattr(settings, "MESSAGES_DISABLED", False): return from messages.models import Message from teams.models import TeamMember, Team user = User.objects.get(pk=user_pk) team = Team.objects.get(pk=team_pk) if not team_sends_notification(team,'block_team_member_leave_message') or not user.is_active: return False from videos.models import Action # the feed item should appear on the timeline for all team members # as a team might have thousands of members, this one item has # to show up on all of them Action.create_member_left_handler(team, user) # notify admins and owners through messages notifiable = TeamMember.objects.filter(team=team, user__is_active=True, role__in=[TeamMember.ROLE_ADMIN, TeamMember.ROLE_OWNER]) subject = fmt( ugettext(u"%(user)s has left the %(team)s team"), user=user, team=team) for m in notifiable: context = { "parting_member": user, "team":team, "user":m.user, "url_base":get_url_base(), } body = render_to_string("messages/team-member-left.txt",context) if m.user.notify_by_message: msg = Message() msg.message_type = 'S' msg.subject = subject msg.content = body msg.user = m.user msg.object = team msg.save() send_templated_email(m.user, subject, "messages/email/team-member-left.html", context) context = { "team":team, "user":user, "url_base":get_url_base(), } subject = fmt(ugettext("You've left the %(team)s team!"), team=team) if user.notify_by_message: template_name = "messages/team-member-you-have-left.txt" msg = Message() msg.message_type = 'S' msg.subject = subject msg.content = render_to_string(template_name,context) msg.user = user msg.object = team msg.save() template_name = "messages/email/team-member-you-have-left.html" send_templated_email(user, subject, template_name, context)
def ajax_change_video_title(request): from videos.tasks import send_change_title_email video_id = request.POST.get('video_id') title = request.POST.get('title') user = request.user try: video = Video.objects.get(video_id=video_id) if title and not video.title or video.is_html5() or user.is_superuser: old_title = video.title_display() video.title = title video.slug = slugify(video.title) video.save() action = Action(new_video_title=video.title, video=video) action.user = user.is_authenticated() and user or None action.created = datetime.now() action.action_type = Action.CHANGE_TITLE action.save() send_change_title_email.delay(video.id, user and user.id, old_title, video.title) except Video.DoesNotExist: pass return HttpResponse('')
def finished_subtitles(self, request, draft_pk, packets, completed=None): draft = models.SubtitleDraft.objects.get(pk=draft_pk) if not request.user.is_authenticated(): return {'response': 'not_logged_in'} if not draft.language.can_writelock(request): return {"response": "unlockable"} if not draft.matches_request(request): return {"response": "does not match request"} self._save_packets(draft, packets) new_version, new_subs = self._create_version_from_draft( draft, request.user) if len(new_subs) == 0 and draft.language.latest_version() is None: should_save = False else: should_save = new_version.time_change > 0 or new_version.text_change > 0 if should_save: new_version.save() for subtitle in new_subs: subtitle.version = new_version subtitle.save() language = new_version.language language.update_complete_state() language.is_forked = new_version.is_forked language.release_writelock() if not draft.is_dependent() and completed is not None: language.is_complete = completed language.save() new_version.update_percent_done() if language.is_original: language.video.update_complete_state() language.video.save() from videos.models import Action Action.create_caption_handler(new_version) return { "response": "ok", "last_saved_packet": draft.last_saved_packet, "drop_down_contents": self._drop_down_contents(draft.video.video_id) }
def ajax_change_video_title(request): from videos.tasks import send_change_title_email video_id = request.POST.get('video_id') title = request.POST.get('title') user = request.user try: video = Video.objects.get(video_id=video_id) if title and not video.title or video.is_html5() or user.is_superuser: old_title = video.title_display() video.title = title video.slug = slugify(video.title) video.save() update_search_index.delay(Video, video.pk) Action.change_title_handler(video, user) send_change_title_email.delay(video.id, user and user.id, old_title.encode('utf8'), video.title.encode('utf8')) except Video.DoesNotExist: pass return HttpResponse('')
def finished_subtitles(self, request, draft_pk, packets, completed=None): draft = models.SubtitleDraft.objects.get(pk=draft_pk) if not request.user.is_authenticated(): return { 'response': 'not_logged_in' } if not draft.language.can_writelock(request): return { "response" : "unlockable" } if not draft.matches_request(request): return { "response" : "does not match request" } self._save_packets(draft, packets) new_version, new_subs = self._create_version_from_draft(draft, request.user) if len(new_subs) == 0 and draft.language.latest_version() is None: should_save = False else: should_save = new_version.time_change > 0 or new_version.text_change > 0 if should_save: new_version.save() for subtitle in new_subs: subtitle.version = new_version subtitle.save() language = new_version.language language.update_complete_state() language.is_forked = new_version.is_forked language.release_writelock() if not draft.is_dependent() and completed is not None: language.is_complete = completed language.save() new_version.update_percent_done() if language.is_original: language.video.update_complete_state() language.video.save() from videos.models import Action Action.create_caption_handler(new_version) return { "response" : "ok", "last_saved_packet": draft.last_saved_packet, "drop_down_contents" : self._drop_down_contents(draft.video.video_id) }
def _import_video(self, video_url, videoid, title, description, thumbnail, videosrt): videoid_match = VIDEOID_RE.search(videoid) videoid = videoid_match.group(1) video_type = YoutubeVideoType( 'http://www.youtube.com/watch?v={0}'.format(videoid)) try: video_url_obj = VideoUrl.objects.get( url=video_type.convert_to_video_url()) video = video_url_obj.video except ObjectDoesNotExist: video_url_obj = None video = Video() video.youtube_videoid = videoid video.title = title video.description = description if video_type.entry.media.duration: video.duration = int(video_type.entry.media.duration.seconds) video.thumbnail = thumbnail video.save() Action.create_video_handler(video) if videosrt: self._import_srt(video, videosrt) else: SubtitleLanguage(video=video, language='en', is_original=True, is_forked=True).save() if not video_url_obj: video_url_obj = VideoUrl(videoid=videoid, url=video_type.convert_to_video_url(), type=video_type.abbreviation, original=True, primary=True, video=video) video_url_obj.save() self._save_alternate_url(video, video_url)
def _import_video(self, video_url, videoid, title, description, thumbnail, videosrt): videoid_match = VIDEOID_RE.search(videoid) videoid = videoid_match.group(1) video_type = YoutubeVideoType( 'http://www.youtube.com/watch?v={0}'.format(videoid)) try: video_url_obj = VideoUrl.objects.get( url=video_type.convert_to_video_url()) video = video_url_obj.video except ObjectDoesNotExist: video_url_obj = None video = Video() video.youtube_videoid = videoid video.title = title video.description = description if video_type.entry.media.duration: video.duration = int(video_type.entry.media.duration.seconds) video.thumbnail = thumbnail video.save() Action.create_video_handler(video) if videosrt: self._import_srt(video, videosrt) else: SubtitleLanguage(video=video, language='en', is_original=True, is_forked=True).save() if not video_url_obj: video_url_obj = VideoUrl( videoid=videoid, url=video_type.convert_to_video_url(), type=video_type.abbreviation, original=True, primary=True, video=video) video_url_obj.save() self._save_alternate_url(video, video_url)
def finished_subtitles(self, request, video_id, packets, language_code=None): if not request.user.is_authenticated(): return { 'response': 'not_logged_in' } from videos.models import Action video = models.Video.objects.get(video_id=video_id) language = video.subtitle_language(language_code) if not language.can_writelock(request): return { "response" : "unlockable" } last_version = language.latest_version() self._save_packets(last_version, packets) last_version.finished = True last_version.user = request.user last_version.save() language = models.SubtitleLanguage.objects.get(pk=language.pk) language.release_writelock() language.save() Action.create_caption_handler(last_version) return { "response" : "ok", "last_saved_packet": last_version.last_saved_packet, "drop_down_contents" : self._drop_down_contents(request.user, video) }
def ajax_change_video_title(request): video_id = request.POST.get('video_id') title = request.POST.get('title') user = request.user try: video = Video.objects.get(video_id=video_id) if title and not video.title or video.is_html5() or user.is_superuser: old_title = video.title_display() video.title = title video.slug = slugify(video.title) video.save() action = Action(new_video_title=video.title, video=video) action.user = user.is_authenticated() and user or None action.created = datetime.now() action.action_type = Action.CHANGE_TITLE action.save() users = video.notification_list(user) for obj in users: subject = u'Video\'s title changed on Universal Subtitles' context = { 'user': obj, 'domain': Site.objects.get_current().domain, 'video': video, 'editor': user, 'old_title': old_title, 'hash': obj.hash_for_video(video.video_id) } send_templated_email(obj.email, subject, 'videos/email_title_changed.html', context, '*****@*****.**', fail_silently=not settings.DEBUG) except Video.DoesNotExist: pass return HttpResponse('')
def ajax_change_video_title(request): video_id = request.POST.get("video_id") title = request.POST.get("title") user = request.user try: video = Video.objects.get(video_id=video_id) if title and not video.title or video.is_html5() or user.is_superuser: old_title = video.title_display() video.title = title video.slug = slugify(video.title) video.save() action = Action(new_video_title=video.title, video=video) action.user = user.is_authenticated() and user or None action.created = datetime.now() action.action_type = Action.CHANGE_TITLE action.save() users = video.notification_list(user) for obj in users: subject = u"Video's title changed on Universal Subtitles" context = { "user": obj, "domain": Site.objects.get_current().domain, "video": video, "editor": user, "old_title": old_title, "hash": obj.hash_for_video(video.video_id), } send_templated_email( obj.email, subject, "videos/email_title_changed.html", context, "*****@*****.**", fail_silently=not settings.DEBUG, ) except Video.DoesNotExist: pass return HttpResponse("")
def setUp(self): self.user = UserFactory() self.client = APIClient() self.client.force_authenticate(user=self.user) self.list_url = reverse('api:activity-list') # create a bunch of action objects of various types self.team = TeamFactory() self.team_member = TeamMemberFactory(user=self.user, team=self.team) self.video = VideoFactory() TeamVideoFactory(video=self.video, team=self.team) self.user2 = UserFactory() Action.create_video_handler(self.video, self.user) self.video.title = 'new-title' self.video.save() Action.change_title_handler(self.video, self.user) # creating comment will automatically create the action object Comment(content_object=self.video, user=self.user, content="Test Comment").save() v = pipeline.add_subtitles(self.video, 'en', None, author=self.user) Action.create_caption_handler(v, datetime.now()) Action.create_approved_video_handler(v, self.user2) Action.create_rejected_video_handler(v, self.user2) Action.create_new_member_handler(self.team_member) Action.create_member_left_handler(self.team, self.user) self.action_qs = Action.objects.for_user(self.user)
def approved_notification(task_pk, published=False): """ On approval, it can be sent back (published=False) or approved and published """ from teams.models import Task from videos.models import Action from messages.models import Message from teams.models import TeamNotificationSetting try: task = Task.objects.select_related( "team_video__video", "team_video", "assignee", "subtitle_version").get( pk=task_pk) if not team_sends_notification(task.team, 'block_approved_message'): return False except Task.DoesNotExist: return False # some tasks are being created without subtitles version, see # https://unisubs.sifterapp.com/projects/12298/issues/552092/comments if published: subject = ugettext(u"Your subtitles have been approved and published!") template_txt = "messages/team-task-approved-published.txt" template_html ="messages/email/team-task-approved-published.html" # Not sure whether it is the right place to send notification # but should work around the approval when there is no new sub version version = task.get_subtitle_version() TeamNotificationSetting.objects.notify_team(task.team.pk, TeamNotificationSetting.EVENT_SUBTITLE_APPROVED, video_id=version.video.video_id, language_pk=version.subtitle_language.pk, version_pk=version.pk) else: template_txt = "messages/team-task-approved-sentback.txt" template_html ="messages/email/team-task-approved-sentback.html" subject = ugettext(u"Your subtitles have been returned for further editing") version = task.get_subtitle_version() if task.new_review_base_version: user = task.new_review_base_version.author else: user = version.author if not user.is_active: return False task_language = get_language_label(task.language) reviewer = task.assignee video = task.team_video.video subs_url = "%s%s" % (get_url_base(), reverse("videos:translation_history", kwargs={ 'video_id': video.video_id, 'lang': task.language, 'lang_id': version.subtitle_language.pk, })) reviewer_message_url = "%s%s?user=%s" % ( get_url_base(), reverse("messages:new"), reviewer.username) context = { "team":task.team, "title": version.subtitle_language.get_title(), "user":user, "task_language": task_language, "url_base":get_url_base(), "task":task, "reviewer":reviewer, "note":task.body, "subs_url": subs_url, "reviewer_message_url": reviewer_message_url, } msg = None if user.notify_by_message: template_name = template_txt msg = Message() msg.message_type = 'S' msg.subject = subject msg.content = render_to_string(template_name,context) msg.user = user msg.object = task.team msg.save() template_name = template_html email_res = send_templated_email(user, subject, template_name, context) Action.create_approved_video_handler(version, reviewer) return msg, email_res
def team_member_new(member_pk): if getattr(settings, "MESSAGES_DISABLED", False): return from messages.models import Message from teams.models import TeamMember, Setting member = TeamMember.objects.get(pk=member_pk) if not team_sends_notification(member.team,'block_team_member_new_message'): return False from videos.models import Action from teams.models import TeamMember # the feed item should appear on the timeline for all team members # as a team might have thousands of members, this one item has # to show up on all of them Action.create_new_member_handler(member) # notify admins and owners through messages notifiable = TeamMember.objects.filter(team=member.team, user__is_active=True, role__in=[TeamMember.ROLE_ADMIN, TeamMember.ROLE_OWNER]).exclude(pk=member.pk) for m in notifiable: context = { "new_member": member.user, "team":member.team, "user":m.user, "role":member.role, "url_base":get_url_base(), } body = render_to_string("messages/team-new-member.txt",context) subject = fmt( ugettext("%(team)s team has a new member"), team=member.team) if m.user.notify_by_message: msg = Message() msg.message_type = 'S' msg.subject = subject msg.content = body msg.user = m.user msg.object = m.team msg.save() template_name = "messages/email/team-new-member.html" send_templated_email(m.user, subject, template_name, context) # does this team have a custom message for this? team_default_message = None messages = Setting.objects.messages().filter(team=member.team) if messages.exists(): for m in messages: if m.get_key_display() == 'messages_joins': team_default_message = m.data break for ul in UserLanguage.objects.filter(user=member.user).order_by("priority"): localized_message = Setting.objects.messages().filter(team=member.team, language_code=ul.language) if len(localized_message) == 1: if team_default_message: team_default_message += u'\n\n----------------\n\n' + localized_message[0].data else: team_default_message = localized_message[0].data break # now send welcome mail to the new member template_name = "messages/team-welcome.txt" context = { "team":member.team, "url_base":get_url_base(), "role":member.role, "user":member.user, "custom_message": team_default_message, } body = render_to_string(template_name,context) msg = Message() msg.message_type = 'S' msg.subject = fmt( ugettext("You've joined the %(team)s team!"), team=member.team) msg.content = body msg.user = member.user msg.object = member.team msg.save() template_name = "messages/email/team-welcome.html" send_templated_email(msg.user, msg.subject, template_name, context)
def _reviewed_notification(task_pk, status): from teams.models import Task from videos.models import Action from messages.models import Message try: task = Task.objects.select_related( "team_video__video", "team_video", "assignee").get( pk=task_pk) except Task.DoesNotExist: return False notification_setting_name = { REVIEWED_AND_PUBLISHED: 'block_reviewed_and_published_message', REVIEWED_AND_PENDING_APPROVAL: 'block_reviewed_and_pending_approval_message', REVIEWED_AND_SENT_BACK: 'block_reviewed_and_sent_back_message', }[status] version = task.get_subtitle_version() if task.new_review_base_version: user = task.new_review_base_version.author else: user = version.author if not team_sends_notification(task.team, notification_setting_name) or not user.is_active: return False subject = ugettext(u"Your subtitles have been reviewed") if status == REVIEWED_AND_PUBLISHED: subject += ugettext(" and published") task_language = get_language_label(task.language) reviewer = task.assignee video = task.team_video.video subs_url = "%s%s" % (get_url_base(), reverse("videos:translation_history", kwargs={ 'video_id': video.video_id, 'lang': task.language, 'lang_id': version.subtitle_language.pk, })) reviewer_message_url = "%s%s?user=%s" % ( get_url_base(), reverse("messages:new"), reviewer.username) reviewer_profile_url = "%s%s" % (get_url_base(), reverse("profiles:profile", kwargs={'user_id': reviewer.id})) perform_task_url = "%s%s" % (get_url_base(), reverse("teams:perform_task", kwargs={ 'slug': task.team.slug, 'task_pk': task_pk })) context = { "team":task.team, "title": version.subtitle_language.get_title(), "user":user, "task_language": task_language, "url_base":get_url_base(), "task":task, "reviewer":reviewer, "note":task.body, "reviewed_and_pending_approval": status == REVIEWED_AND_PENDING_APPROVAL, "sent_back": status == REVIEWED_AND_SENT_BACK, "reviewed_and_published": status == REVIEWED_AND_PUBLISHED, "subs_url": subs_url, "reviewer_message_url": reviewer_message_url, "reviewer_profile_url": reviewer_profile_url, "perform_task_url": perform_task_url, } msg = None if user.notify_by_message: template_name = "messages/team-task-reviewed.txt" msg = Message() msg.message_type = 'S' msg.subject = subject msg.content = render_to_string(template_name,context) msg.user = user msg.object = task.team msg.save() template_name = "messages/email/team-task-reviewed.html" email_res = send_templated_email(user, subject, template_name, context) if status == REVIEWED_AND_SENT_BACK: if task.type == Task.TYPE_IDS['Review']: Action.create_declined_video_handler(version, reviewer) else: Action.create_rejected_video_handler(version, reviewer) elif status == REVIEWED_AND_PUBLISHED: Action.create_approved_video_handler(version, reviewer) elif status == REVIEWED_AND_PENDING_APPROVAL: Action.create_accepted_video_handler(version, reviewer) return msg, email_res
def approved_notification(task_pk, published=False): """ On approval, it can be sent back (published=False) or approved and published """ from teams.models import Task from videos.models import Action from messages.models import Message try: task = Task.objects.select_related("team_video__video", "team_video", "assignee", "subtitle_version").get(pk=task_pk) except Task.DoesNotExist: return False # some tasks are being created without subtitles version, see # https://unisubs.sifterapp.com/projects/12298/issues/552092/comments if not task.subtitle_version: return False if published: subject = ugettext(u"Your subtitles have been approved and published!") template_txt = "messages/team-task-approved-published.txt" template_html = "messages/email/team-task-approved-published.html" else: template_txt = "messages/team-task-approved-sentback.txt" template_html = "messages/email/team-task-approved-sentback.html" subject = ugettext( u"Your subtitles have been returned for further editing") user = task.subtitle_version.user task_language = get_language_label(task.language) reviewer = task.assignee video = task.team_video.video subs_url = "%s%s" % (get_url_base(), reverse("videos:translation_history", kwargs={ 'video_id': video.video_id, 'lang': task.language, 'lang_id': task.subtitle_version.language.pk, })) reviewer_message_url = "%s%s?user=%s" % ( get_url_base(), reverse("messages:new"), reviewer.username) context = { "team": task.team, "title": task.subtitle_version.language.get_title(), "user": user, "task_language": task_language, "url_base": get_url_base(), "task": task, "reviewer": reviewer, "note": task.body, "subs_url": subs_url, "reviewer_message_url": reviewer_message_url, } msg = None if user.notify_by_message: template_name = template_txt msg = Message() msg.subject = subject msg.content = render_to_string(template_name, context) msg.user = user msg.object = task.team msg.save() template_name = template_html Meter('templated-emails-sent-by-type.teams.approval-result').inc() email_res = send_templated_email(user, subject, template_name, context) Action.create_approved_video_handler(task.subtitle_version, reviewer) return msg, email_res