def new_contact_ticket(request): ticket_created = False if request.POST: form = __get_contact_form(request) if form.is_valid(): ticket = Ticket() ticket.title = form.cleaned_data['title'] ticket.source = TICKET_SOURCE_CONTACT_FORM ticket.status = TICKET_STATUS_NEW ticket.queue = Queue.objects.get(name=QUEUE_SUPPORT_REQUESTS) tc = TicketComment() if request.user.is_authenticated(): ticket.sender = request.user tc.sender = request.user else: ticket.sender_email = form.cleaned_data['email'] tc.text = form.cleaned_data['message'] ticket.save() tc.ticket = ticket tc.save() ticket_created = True # TODO: send email else: form = __get_contact_form(request, False) return render_to_response('tickets/contact.html', locals(), context_instance=RequestContext(request))
def ticket(request, ticket_id): ticket = Ticket.objects.get(pk=int(ticket_id)) if request.method == "POST": form = NewTicketCommentForm(request.POST) if form.is_valid(): ticket = Ticket.objects.get(pk=int(ticket_id)) comment = TicketComment(commenter=request.user, ticket=ticket, content=form.cleaned_data["content"]) if request.POST.has_key("email"): subject = "[%s] [Comment] %s" % (SETTINGS.TICKET_APP_NAME, ticket.title) message = ( '%s left a comment on your ticket. \n%s \n<a href="%s/tickets/view/%d/">You can view your ticket here. </a>' % (request.user, form.cleaned_data["content"], SETTINGS.TICKET_DOMAIN, ticket.id) ) from_email = SETTINGS.TICKET_FROM_EMAIL recipient_list = (ticket.submitter_email,) send_mail(subject, message, from_email, recipient_list) comment.save() # Display the information about a queue and every comment, POST or not. # print ticket.title # If user is not authenticated, forbidden # TODO change this to must be admin if request.user.is_authenticated() == False: return HttpResponseForbidden # IF user is authenticated, but doesn't own the ticket and isn't an admin, forbidden if request.user.is_authenticated() and ticket.owner != ticket.owner: if requesut.user.is_admin() == False: return HttpResponseForbidden template_data = {} # Pass ticket in as non-editable template_data["ticket"] = ticket comments = TicketComment.objects.filter(ticket=ticket) # print comments template_data["comments"] = comments comment_form = NewTicketCommentForm() template_data["comment_form"] = comment_form return render_to_response("ticket.html", context_instance=RequestContext(request, template_data))
def ticket(request, ticket_key): can_view_moderator_only_messages = _can_view_mod_msg(request) clean_status_forms = True clean_comment_form = True ticket = get_object_or_404(Ticket, key=ticket_key) if ticket.content: # Becuase it can happen that some tickets have linked content which has dissapeared or on deletion time the ticket # has not been propertly updated, we need to check whether the sound that is linked does in fact exist. If it does # not, we set the linked content to None and the status of the ticket to closed as should have been set at sound # deletion time. sound_id = ticket.content.object_id try: Sound.objects.get(id=sound_id) except Sound.DoesNotExist: ticket.content = None ticket.status = TICKET_STATUS_CLOSED ticket.save() if request.method == 'POST': invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() # Left ticket message if is_selected(request, 'recaptcha') or (request.user.is_authenticated() and is_selected(request, 'message')): tc_form = _get_tc_form(request) if tc_form.is_valid(): tc = TicketComment() tc.text = tc_form.cleaned_data['message'] tc.moderator_only = tc_form.cleaned_data.get( 'moderator_only', False) if tc.text: if request.user.is_authenticated(): tc.sender = request.user tc.ticket = ticket tc.save() if not request.user.is_authenticated(): email_to = Ticket.MODERATOR_ONLY elif request.user == ticket.sender: email_to = Ticket.MODERATOR_ONLY else: email_to = Ticket.USER_ONLY ticket.send_notification_emails( ticket.NOTIFICATION_UPDATED, email_to) else: clean_comment_form = False # update sound ticket elif is_selected(request, 'tm') or is_selected(request, 'ss'): ticket_form = TicketModerationForm(request.POST, prefix="tm") sound_form = SoundStateForm(request.POST, prefix="ss") if ticket_form.is_valid() and sound_form.is_valid(): clean_status_forms = True clean_comment_form = True sound_state = sound_form.cleaned_data.get('state') # Sound should be deleted if sound_state == 'DE': if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED tc = TicketComment( sender=request.user, text= "Moderator %s deleted the sound and closed the ticket" % request.user, ticket=ticket, moderator_only=False) tc.save() ticket.send_notification_emails( ticket.NOTIFICATION_DELETED, ticket.USER_ONLY) # Set another sound state that's not delete else: if ticket.content: ticket.content.content_object.moderation_state = sound_state # Mark the index as dirty so it'll be indexed in Solr if sound_state == "OK": ticket.content.content_object.mark_index_dirty() ticket.content.content_object.save() ticket.status = ticket_form.cleaned_data.get('status') tc = TicketComment( sender=request.user, text= "Moderator %s set the sound to %s and the ticket to %s." % (request.user, 'pending' if sound_state == 'PE' else sound_state, ticket.status), ticket=ticket, moderator_only=False) tc.save() ticket.send_notification_emails( ticket.NOTIFICATION_UPDATED, ticket.USER_ONLY) ticket.save() if clean_status_forms: ticket_form = TicketModerationForm(initial={'status': ticket.status}, prefix="tm") state = ticket.content.content_object.moderation_state if ticket.content else 'DE' sound_form = SoundStateForm(initial={'state': state}, prefix="ss") if clean_comment_form: tc_form = _get_tc_form(request, False) num_sounds_pending = ticket.sender.profile.num_sounds_pending_moderation() tvars = { "ticket": ticket, "num_sounds_pending": num_sounds_pending, "tc_form": tc_form, "ticket_form": ticket_form, "sound_form": sound_form, "can_view_moderator_only_messages": can_view_moderator_only_messages } return render(request, 'tickets/ticket.html', tvars)
def moderation_assigned(request, user_id): can_view_moderator_only_messages = _can_view_mod_msg(request) clear_forms = True if request.method == 'POST': mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket = Ticket.objects.get( id=mod_sound_form.cleaned_data.get("ticket", False)) invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() action = mod_sound_form.cleaned_data.get("action") msg = msg_form.cleaned_data.get("message", False) moderator_only = msg_form.cleaned_data.get("moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() if action == "Approve": ticket.status = TICKET_STATUS_CLOSED ticket.content.content_object.change_moderation_state( "OK") # change_moderation_state does the saving ticket.save() ticket.content.content_object.mark_index_dirty() if msg: ticket.send_notification_emails( Ticket.NOTIFICATION_APPROVED_BUT, Ticket.USER_ONLY) else: ticket.send_notification_emails( Ticket.NOTIFICATION_APPROVED, Ticket.USER_ONLY) elif action == "Defer": ticket.status = TICKET_STATUS_DEFERRED ticket.save() # only send a notification if a message was added if msg: ticket.send_notification_emails( Ticket.NOTIFICATION_QUESTION, Ticket.USER_ONLY) elif action == "Return": ticket.assignee = None ticket.status = TICKET_STATUS_NEW # no notification here ticket.save() elif action == "Delete": ticket.send_notification_emails(Ticket.NOTIFICATION_DELETED, Ticket.USER_ONLY) # to prevent a crash if the form is resubmitted if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED ticket.save() elif action == "Whitelist": th = Thread(target=call_command, args=( 'whitelist_user', "%i" % ticket.id, )) th.start() ticket.send_notification_emails( Ticket.NOTIFICATION_WHITELISTED, Ticket.USER_ONLY) messages.add_message( request, messages.INFO, """User %s has been whitelisted but some of their tickets might still appear on this list for some time. Please reload the page in a few seconds to see the updated list of pending tickets""" % ticket.sender.username) else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={'action': 'Approve'}) msg_form = ModerationMessageForm() qs = Ticket.objects.select_related() \ .filter(assignee=user_id) \ .exclude(status=TICKET_STATUS_CLOSED) \ .exclude(content=None) \ .order_by('status', '-created') pagination_response = paginate( request, qs, settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE) pagination_response['page'].object_list = list( pagination_response['page'].object_list) # Because some tickets can have linked content which has disappeared or on deletion time the ticket # has not been properly updated, we need to check whether the sound that is linked does in fact exist. If it does # not, we set the linked content to None and the status of the ticket to closed as should have been set at sound # deletion time. for ticket in pagination_response['page'].object_list: sound_id = ticket.content.object_id try: Sound.objects.get(id=sound_id) except Sound.DoesNotExist: pagination_response['page'].object_list.remove(ticket) ticket.content = None ticket.status = TICKET_STATUS_CLOSED ticket.save() moderator_tickets_count = qs.count() moderation_texts = MODERATION_TEXTS show_pagination = moderator_tickets_count > settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE tvars = locals() tvars.update(pagination_response) return render(request, 'tickets/moderation_assigned.html', tvars)
def ticket(request, ticket_key): can_view_moderator_only_messages = _can_view_mod_msg(request) clean_status_forms = True clean_comment_form = True ticket = get_object_or_404(Ticket, key=ticket_key) if request.method == 'POST': invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() # Left ticket message if is_selected(request, 'recaptcha') or (request.user.is_authenticated() and is_selected(request, 'message')): tc_form = _get_tc_form(request) if tc_form.is_valid(): tc = TicketComment() tc.text = tc_form.cleaned_data['message'] tc.moderator_only = tc_form.cleaned_data.get('moderator_only', False) if tc.text: if request.user.is_authenticated(): tc.sender = request.user tc.ticket = ticket tc.save() if not request.user.is_authenticated(): email_to = Ticket.MODERATOR_ONLY elif request.user == ticket.sender: email_to = Ticket.MODERATOR_ONLY else: email_to = Ticket.USER_ONLY ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, email_to) else: clean_comment_form = False # update sound ticket elif is_selected(request, 'tm') or is_selected(request, 'ss'): ticket_form = TicketModerationForm(request.POST, prefix="tm") sound_form = SoundStateForm(request.POST, prefix="ss") if ticket_form.is_valid() and sound_form.is_valid(): clean_status_forms = True clean_comment_form = True sound_state = sound_form.cleaned_data.get('state') # Sound should be deleted if sound_state == 'DE': if ticket.sound: ticket.sound.delete() ticket.sound = None ticket.status = TICKET_STATUS_CLOSED tc = TicketComment(sender=request.user, text="Moderator %s deleted the sound and closed the ticket" % request.user, ticket=ticket, moderator_only=False) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_DELETED, ticket.USER_ONLY) # Set another sound state that's not delete else: if ticket.sound: ticket.sound.moderation_state = sound_state # Mark the index as dirty so it'll be indexed in Solr if sound_state == "OK": ticket.sound.mark_index_dirty() ticket.sound.save() ticket.status = ticket_form.cleaned_data.get('status') tc = TicketComment(sender=request.user, text="Moderator %s set the sound to %s and the ticket to %s." % (request.user, 'pending' if sound_state == 'PE' else sound_state, ticket.status), ticket=ticket, moderator_only=False) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, ticket.USER_ONLY) ticket.save() if clean_status_forms: ticket_form = TicketModerationForm(initial={'status': ticket.status}, prefix="tm") state = ticket.sound.moderation_state if ticket.sound else 'DE' sound_form = SoundStateForm(initial={'state': state}, prefix="ss") if clean_comment_form: tc_form = _get_tc_form(request, False) num_sounds_pending = ticket.sender.profile.num_sounds_pending_moderation() tvars = {"ticket": ticket, "num_sounds_pending": num_sounds_pending, "tc_form": tc_form, "ticket_form": ticket_form, "sound_form": sound_form, "can_view_moderator_only_messages": can_view_moderator_only_messages} return render(request, 'tickets/ticket.html', tvars)
def moderation_assigned(request, user_id): clear_forms = True if request.method == 'POST': mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket_ids = mod_sound_form.cleaned_data.get("ticket", '').split('|') tickets = Ticket.objects.filter(id__in=ticket_ids) msg = msg_form.cleaned_data.get("message", False) action = mod_sound_form.cleaned_data.get("action") notification = None users_to_update = set() packs_to_update = set() if action == "Approve": tickets.update(status=TICKET_STATUS_CLOSED) Sound.objects.filter(ticket__in=tickets).update( is_index_dirty=True, moderation_state='OK', moderation_date=datetime.datetime.now()) if msg: notification = Ticket.NOTIFICATION_APPROVED_BUT else: notification = Ticket.NOTIFICATION_APPROVED elif action == "Defer": tickets.update(status=TICKET_STATUS_DEFERRED) # only send a notification if a message was added if msg: notification = Ticket.NOTIFICATION_QUESTION elif action == "Return": tickets.update(status=TICKET_STATUS_NEW, assignee=None) # no notification here elif action == "Delete": # to prevent a crash if the form is resubmitted tickets.update(status=TICKET_STATUS_CLOSED) # if tickets are being deleted we have to fill users_to_update # and sounds_to_update before we delete the sounds and they dissapear # from the ticket (thus losing reference) for ticket in tickets: users_to_update.add(ticket.sound.user.profile) if ticket.sound.pack: packs_to_update.add(ticket.sound.pack) Sound.objects.filter(ticket__in=tickets).delete() notification = Ticket.NOTIFICATION_DELETED elif action == "Whitelist": ticket_ids = list(tickets.values_list('id',flat=True)) gm_client = gearman.GearmanClient(settings.GEARMAN_JOB_SERVERS) gm_client.submit_job("whitelist_user", json.dumps(ticket_ids), wait_until_complete=False, background=True) notification = Ticket.NOTIFICATION_WHITELISTED users = set(tickets.values_list('sender__username', flat=True)) messages.add_message(request, messages.INFO, """User(s) %s has/have been whitelisted. Some of tickets might still appear on this list for some time. Please reload the page in a few seconds to see the updated list of pending tickets""" % ", ".join(users)) for ticket in tickets: if action != "Delete": # We only fill here users_to_update and packs_to_update if action is not # "Delete". See comment in "Delete" action case some lines above users_to_update.add(ticket.sound.user.profile) if ticket.sound.pack: packs_to_update.add(ticket.sound.pack) invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() moderator_only = msg_form.cleaned_data.get("moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() # Send emails if notification: ticket.send_notification_emails(notification, Ticket.USER_ONLY) # Update number of sounds for each user for profile in users_to_update: profile.update_num_sounds() # Process packs for pack in packs_to_update: pack.process() else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={'action': 'Approve'}) msg_form = ModerationMessageForm() qs = Ticket.objects.select_related() \ .filter(assignee=user_id) \ .exclude(status=TICKET_STATUS_CLOSED) \ .exclude(sound=None) \ .order_by('status', '-created') pagination_response = paginate(request, qs, settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE) pagination_response['page'].object_list = list(pagination_response['page'].object_list) # Because some tickets can have related sound which has disappeared or on deletion time the ticket # has not been properly updated, we need to check whether the sound that is related does in fact # exist. If it does not, we set the related sound to None and the status of the ticket to closed # as should have been set at sound deletion time. for ticket in pagination_response['page'].object_list: if not ticket.sound: pagination_response['page'].object_list.remove(ticket) ticket.status = TICKET_STATUS_CLOSED ticket.save() moderator_tickets_count = qs.count() moderation_texts = MODERATION_TEXTS show_pagination = moderator_tickets_count > settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE tvars = { "moderator_tickets_count": moderator_tickets_count, "moderation_texts": moderation_texts, "page": pagination_response['page'], "paginator": pagination_response['paginator'], "current_page": pagination_response['current_page'], "show_pagination": show_pagination, "mod_sound_form": mod_sound_form, "msg_form": msg_form, "selected": "queue" } return render(request, 'tickets/moderation_assigned.html', tvars)
def ticket(request, ticket_key): can_view_moderator_only_messages = __can_view_mod_msg(request) clean_status_forms = True clean_comment_form = True ticket = get_object_or_404(Ticket, key=ticket_key) if request.method == 'POST': invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() # Left ticket message if is_selected(request, 'recaptcha') or (request.user.is_authenticated() and is_selected(request, 'message')): tc_form = __get_tc_form(request) if tc_form.is_valid(): tc = TicketComment() tc.text = tc_form.cleaned_data['message'] tc.moderator_only = tc_form.cleaned_data.get( 'moderator_only', False) if tc.text: if request.user.is_authenticated(): tc.sender = request.user tc.ticket = ticket tc.save() if not request.user.is_authenticated(): email_to = Ticket.MODERATOR_ONLY elif request.user == ticket.sender: email_to = Ticket.MODERATOR_ONLY else: email_to = Ticket.USER_ONLY ticket.send_notification_emails( ticket.NOTIFICATION_UPDATED, email_to) else: clean_comment_form = False # update sound ticket elif is_selected(request, 'tm') or is_selected(request, 'ss'): ticket_form = TicketModerationForm(request.POST, prefix="tm") sound_form = SoundStateForm(request.POST, prefix="ss") if ticket_form.is_valid() and sound_form.is_valid(): clean_status_forms = True clean_comment_form = True sound_state = sound_form.cleaned_data.get('state') # Sound should be deleted if sound_state == 'DE': if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED tc = TicketComment( sender=request.user, text= "Moderator %s deleted the sound and closed the ticket" % request.user, ticket=ticket, moderator_only=False) tc.save() ticket.send_notification_emails( ticket.NOTIFICATION_DELETED, ticket.USER_ONLY) # Set another sound state that's not delete else: if ticket.content: ticket.content.content_object.moderation_state = sound_state # Mark the index as dirty so it'll be indexed in Solr if sound_state == "OK": ticket.content.content_object.mark_index_dirty() ticket.content.content_object.save() ticket.status = ticket_form.cleaned_data.get('status') tc = TicketComment(sender=request.user, text="Moderator %s set the sound to %s and the ticket to %s." % \ (request.user, 'pending' if sound_state == 'PE' else sound_state, ticket.status), ticket=ticket, moderator_only=False) tc.save() ticket.send_notification_emails( ticket.NOTIFICATION_UPDATED, ticket.USER_ONLY) ticket.save() if clean_status_forms: ticket_form = TicketModerationForm(initial={'status': ticket.status}, prefix="tm") sound_form = SoundStateForm(initial={'state': ticket.content.content_object.moderation_state \ if ticket.content else 'DE'}, prefix="ss") if clean_comment_form: tc_form = __get_tc_form(request, False) return render_to_response('tickets/ticket.html', locals(), context_instance=RequestContext(request))
def moderation_assigned(request, user_id): can_view_moderator_only_messages = __can_view_mod_msg(request) clear_forms = True if request.method == 'POST': mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket = Ticket.objects.get( id=mod_sound_form.cleaned_data.get("ticket", False)) invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() action = mod_sound_form.cleaned_data.get("action") msg = msg_form.cleaned_data.get("message", False) moderator_only = msg_form.cleaned_data.get("moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() if action == "Approve": ticket.status = TICKET_STATUS_CLOSED ticket.content.content_object.moderation_state = "OK" ticket.content.content_object.save() ticket.save() ticket.content.content_object.mark_index_dirty() if msg: ticket.send_notification_emails( Ticket.NOTIFICATION_APPROVED_BUT, Ticket.USER_ONLY) else: ticket.send_notification_emails( Ticket.NOTIFICATION_APPROVED, Ticket.USER_ONLY) elif action == "Defer": ticket.status = TICKET_STATUS_DEFERRED ticket.save() # only send a notification if a message was added if msg: ticket.send_notification_emails( Ticket.NOTIFICATION_QUESTION, Ticket.USER_ONLY) elif action == "Return": ticket.assignee = None ticket.status = TICKET_STATUS_NEW # no notification here ticket.save() elif action == "Delete": ticket.send_notification_emails(Ticket.NOTIFICATION_DELETED, Ticket.USER_ONLY) # to prevent a crash if the form is resubmitted if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED ticket.save() elif action == "Whitelist": th = Thread(target=call_command, args=( 'whitelist_user', ticket.id, )) th.start() ticket.send_notification_emails( Ticket.NOTIFICATION_WHITELISTED, Ticket.USER_ONLY) messages.add_message( request, messages.INFO, 'User %s has been whitelisted but some of his tickets might ' 'still appear on this list for some time. Please reload the page in a few ' 'seconds to see the updated list of pending tickets' % ticket.sender.username) else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={'action': 'Approve'}) msg_form = ModerationMessageForm() qs = Ticket.objects.select_related() \ .filter(assignee=user_id) \ .exclude(status=TICKET_STATUS_CLOSED) \ .exclude(content=None) \ .order_by('status', '-created') paginaion_response = paginate(request, qs, MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE) paginaion_response['page'].object_list = list( paginaion_response['page'].object_list) for ticket in paginaion_response['page'].object_list: sound_id = ticket.content.object_id try: Sound.objects.get(id=sound_id) except: paginaion_response['page'].object_list.remove(ticket) try: # Try to delete ticket so error does not happen again ticket.delete() except: pass moderator_tickets_count = qs.count() moderation_texts = MODERATION_TEXTS show_pagination = moderator_tickets_count > MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE return render_to_response('tickets/moderation_assigned.html', combine_dicts(paginaion_response, locals()), context_instance=RequestContext(request))
def moderation_assigned(request, user_id): can_view_moderator_only_messages = __can_view_mod_msg(request) clear_forms = True if request.method == 'POST': mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket = Ticket.objects.get(id=mod_sound_form.cleaned_data.get("ticket", False)) invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() action = mod_sound_form.cleaned_data.get("action") msg = msg_form.cleaned_data.get("message", False) moderator_only = msg_form.cleaned_data.get("moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() if action == "Approve": ticket.status = TICKET_STATUS_CLOSED ticket.content.content_object.change_moderation_state("OK") # change_moderation_state does the saving ticket.save() ticket.content.content_object.mark_index_dirty() if msg: ticket.send_notification_emails(Ticket.NOTIFICATION_APPROVED_BUT, Ticket.USER_ONLY) else: ticket.send_notification_emails(Ticket.NOTIFICATION_APPROVED, Ticket.USER_ONLY) elif action == "Defer": ticket.status = TICKET_STATUS_DEFERRED ticket.save() # only send a notification if a message was added if msg: ticket.send_notification_emails(Ticket.NOTIFICATION_QUESTION, Ticket.USER_ONLY) elif action == "Return": ticket.assignee = None ticket.status = TICKET_STATUS_NEW # no notification here ticket.save() elif action == "Delete": ticket.send_notification_emails(Ticket.NOTIFICATION_DELETED, Ticket.USER_ONLY) # to prevent a crash if the form is resubmitted if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED ticket.save() elif action == "Whitelist": th = Thread(target=call_command, args=('whitelist_user', ticket.id,)) th.start() ticket.send_notification_emails(Ticket.NOTIFICATION_WHITELISTED, Ticket.USER_ONLY) messages.add_message(request, messages.INFO, 'User %s has been whitelisted but some of his tickets might ' 'still appear on this list for some time. Please reload the page in a few ' 'seconds to see the updated list of pending tickets' % ticket.sender.username) else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={'action': 'Approve'}) msg_form = ModerationMessageForm() qs = Ticket.objects.select_related() \ .filter(assignee=user_id) \ .exclude(status=TICKET_STATUS_CLOSED) \ .exclude(content=None) \ .order_by('status', '-created') paginaion_response = paginate(request, qs, settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE) paginaion_response['page'].object_list = list(paginaion_response['page'].object_list) for ticket in paginaion_response['page'].object_list: sound_id = ticket.content.object_id try: Sound.objects.get(id=sound_id) except: paginaion_response['page'].object_list.remove(ticket) try: # Try to delete ticket so error does not happen again ticket.delete() except: pass moderator_tickets_count = qs.count() moderation_texts = MODERATION_TEXTS show_pagination = moderator_tickets_count > settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE return render_to_response('tickets/moderation_assigned.html', combine_dicts(paginaion_response, locals()), context_instance=RequestContext(request))
def ticket(request, ticket_key): can_view_moderator_only_messages = _can_view_mod_msg(request) clean_status_forms = True clean_comment_form = True ticket = get_object_or_404(Ticket.objects.select_related( 'sound__license', 'sound__user'), key=ticket_key) if request.method == 'POST': invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() # Left ticket message if is_selected(request, 'recaptcha') or (request.user.is_authenticated and is_selected(request, 'message')): tc_form = _get_tc_form(request) if tc_form.is_valid(): tc = TicketComment() tc.text = tc_form.cleaned_data['message'] tc.moderator_only = tc_form.cleaned_data.get( 'moderator_only', False) if tc.text: if request.user.is_authenticated: tc.sender = request.user tc.ticket = ticket tc.save() if not request.user.is_authenticated: email_to = Ticket.MODERATOR_ONLY elif request.user == ticket.sender: email_to = Ticket.MODERATOR_ONLY else: email_to = Ticket.USER_ONLY ticket.send_notification_emails( ticket.NOTIFICATION_UPDATED, email_to) else: clean_comment_form = False # update sound ticket elif is_selected(request, 'ss'): sound_form = SoundStateForm(request.POST, prefix='ss') if sound_form.is_valid(): clean_status_forms = True clean_comment_form = True sound_action = sound_form.cleaned_data.get('action') comment = 'Moderator {} '.format(request.user) notification = None # If there is no one assigned, then changing the state self-assigns the ticket if ticket.assignee is None: ticket.assignee = request.user if sound_action == 'Delete': if ticket.sound: ticket.sound.delete() ticket.sound = None ticket.status = TICKET_STATUS_CLOSED comment += 'deleted the sound and closed the ticket' notification = ticket.NOTIFICATION_DELETED elif sound_action == 'Defer': ticket.status = TICKET_STATUS_DEFERRED ticket.sound.change_moderation_state( 'PE') # not sure if this state have been used before comment += 'deferred the ticket' elif sound_action == "Return": ticket.status = TICKET_STATUS_NEW ticket.assignee = None ticket.sound.change_moderation_state('PE') comment += 'returned the ticket to new sounds queue' elif sound_action == 'Approve': ticket.status = TICKET_STATUS_CLOSED ticket.sound.change_moderation_state('OK') comment += 'approved the sound and closed the ticket' notification = ticket.NOTIFICATION_APPROVED elif sound_action == 'Whitelist': _whitelist_gearman([ ticket.id ]) # async job should take care of whitelisting comment += 'whitelisted all sounds from user {}'.format( ticket.sender) notification = ticket.NOTIFICATION_WHITELISTED if notification is not None: ticket.send_notification_emails(notification, ticket.USER_ONLY) if ticket.sound is not None: ticket.sound.save() ticket.save() tc = TicketComment(sender=request.user, text=comment, ticket=ticket, moderator_only=False) tc.save() if clean_status_forms: default_action = 'Return' if ticket.sound and ticket.sound.moderation_state == 'OK' else 'Approve' sound_form = SoundStateForm(initial={'action': default_action}, prefix="ss") if clean_comment_form: tc_form = _get_tc_form(request, False) num_sounds_pending = ticket.sender.profile.num_sounds_pending_moderation() tvars = { "ticket": ticket, "num_sounds_pending": num_sounds_pending, "tc_form": tc_form, "sound_form": sound_form, "can_view_moderator_only_messages": can_view_moderator_only_messages } return render(request, 'tickets/ticket.html', tvars)
def moderation_assigned(request, user_id): clear_forms = True mod_sound_form = None msg_form = None if request.method == 'POST': mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket_ids = mod_sound_form.cleaned_data.get("ticket", '').split('|') tickets = Ticket.objects.filter(id__in=ticket_ids) msg = msg_form.cleaned_data.get("message", False) action = mod_sound_form.cleaned_data.get("action") notification = None users_to_update = set() packs_to_update = set() if action == "Approve": tickets.update(status=TICKET_STATUS_CLOSED) sounds_update_params = { 'is_index_dirty': True, 'moderation_state': 'OK', 'moderation_date': datetime.datetime.now() } is_explicit_choice_key = mod_sound_form.cleaned_data.get( "is_explicit") if is_explicit_choice_key == IS_EXPLICIT_ADD_FLAG_KEY: sounds_update_params['is_explicit'] = True elif is_explicit_choice_key == IS_EXPLICIT_REMOVE_FLAG_KEY: sounds_update_params['is_explicit'] = False # Otherwise is_explicit_choice_key = IS_EXPLICIT_KEEP_USER_PREFERENCE_KEY, don't update the # 'is_explicit' field and leave it as the user originally set it Sound.objects.filter(ticket__in=tickets).update( **sounds_update_params) if msg: notification = Ticket.NOTIFICATION_APPROVED_BUT else: notification = Ticket.NOTIFICATION_APPROVED elif action == "Defer": tickets.update(status=TICKET_STATUS_DEFERRED) # only send a notification if a message was added if msg: notification = Ticket.NOTIFICATION_QUESTION elif action == "Return": tickets.update(status=TICKET_STATUS_NEW, assignee=None) # no notification here elif action == "Delete": # to prevent a crash if the form is resubmitted tickets.update(status=TICKET_STATUS_CLOSED) # if tickets are being deleted we have to fill users_to_update # and sounds_to_update before we delete the sounds and they dissapear # from the ticket (thus losing reference) for ticket in tickets: users_to_update.add(ticket.sound.user.profile) if ticket.sound.pack: packs_to_update.add(ticket.sound.pack) Sound.objects.filter(ticket__in=tickets).delete() # After we delete sounds that these tickets are associated with, # we refresh the ticket list so that sound_id is null and this does # not affect the TicketComment post_save trigger tickets = Ticket.objects.filter(id__in=ticket_ids) notification = Ticket.NOTIFICATION_DELETED elif action == "Whitelist": ticket_ids = list(tickets.values_list('id', flat=True)) _whitelist_gearman(ticket_ids) notification = Ticket.NOTIFICATION_WHITELISTED users = set(tickets.values_list('sender__username', flat=True)) messages.add_message( request, messages.INFO, """User(s) %s has/have been whitelisted. Some of tickets might still appear on this list for some time. Please reload the page in a few seconds to see the updated list of pending tickets""" % ", ".join(users)) for ticket in tickets: if action != "Delete": # We only fill here users_to_update and packs_to_update if action is not # "Delete". See comment in "Delete" action case some lines above users_to_update.add(ticket.sound.user.profile) if ticket.sound.pack: packs_to_update.add(ticket.sound.pack) invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() moderator_only = msg_form.cleaned_data.get( "moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() # Send emails if notification: ticket.send_notification_emails(notification, Ticket.USER_ONLY) # Update number of sounds for each user for profile in users_to_update: profile.update_num_sounds() # Process packs for pack in packs_to_update: pack.process() else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={'action': 'Approve'}) msg_form = ModerationMessageForm() qs = Ticket.objects.select_related('sound') \ .filter(assignee=user_id) \ .exclude(status=TICKET_STATUS_CLOSED) \ .exclude(sound=None) \ .order_by('status', '-created') pagination_response = paginate( request, qs, settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE) pagination_response['page'].object_list = list( pagination_response['page'].object_list) # Because some tickets can have related sound which has disappeared or on deletion time the ticket # has not been properly updated, we need to check whether the sound that is related does in fact # exist. If it does not, we set the related sound to None and the status of the ticket to closed # as should have been set at sound deletion time. for ticket in pagination_response['page'].object_list: if not ticket.sound: pagination_response['page'].object_list.remove(ticket) ticket.status = TICKET_STATUS_CLOSED ticket.save() moderator_tickets_count = qs.count() show_pagination = moderator_tickets_count > settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE tvars = { "moderator_tickets_count": moderator_tickets_count, "moderation_texts": MODERATION_TEXTS, "page": pagination_response['page'], "paginator": pagination_response['paginator'], "current_page": pagination_response['current_page'], "show_pagination": show_pagination, "max_selected_tickets_in_right_panel": settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE_SELECTED_COLUMN, "mod_sound_form": mod_sound_form, "msg_form": msg_form, "default_autoplay": request.GET.get('autoplay', 'on') == 'on', "default_include_deferred": request.GET.get('include_d', '') == 'on', } return render(request, 'tickets/moderation_assigned.html', tvars)
def moderation_assigned(request, user_id): clear_forms = True if request.method == 'POST': mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket_ids = mod_sound_form.cleaned_data.get("ticket", '').split('|') tickets = Ticket.objects.filter(id__in=ticket_ids) msg = msg_form.cleaned_data.get("message", False) action = mod_sound_form.cleaned_data.get("action") notification = None users_to_update = set() packs_to_update = set() if action == "Approve": tickets.update(status=TICKET_STATUS_CLOSED) Sound.objects.filter(ticket__in=tickets).update( is_index_dirty=True, moderation_state='OK', moderation_date=datetime.datetime.now()) if msg: notification = Ticket.NOTIFICATION_APPROVED_BUT else: notification = Ticket.NOTIFICATION_APPROVED elif action == "Defer": tickets.update(status=TICKET_STATUS_DEFERRED) # only send a notification if a message was added if msg: notification = Ticket.NOTIFICATION_QUESTION elif action == "Return": tickets.update(status=TICKET_STATUS_NEW, assignee=None) # no notification here elif action == "Delete": # to prevent a crash if the form is resubmitted tickets.update(status=TICKET_STATUS_CLOSED) # if tickets are being deleted we have to fill users_to_update # and sounds_to_update before we delete the sounds and they dissapear # from the ticket (thus losing reference) for ticket in tickets: users_to_update.add(ticket.sound.user.profile) if ticket.sound.pack: packs_to_update.add(ticket.sound.pack) Sound.objects.filter(ticket__in=tickets).delete() notification = Ticket.NOTIFICATION_DELETED elif action == "Whitelist": ticket_ids = list(tickets.values_list('id', flat=True)) gm_client = gearman.GearmanClient(settings.GEARMAN_JOB_SERVERS) gm_client.submit_job("whitelist_user", json.dumps(ticket_ids), wait_until_complete=False, background=True) notification = Ticket.NOTIFICATION_WHITELISTED users = set(tickets.values_list('sender__username', flat=True)) messages.add_message( request, messages.INFO, """User(s) %s has/have been whitelisted. Some of tickets might still appear on this list for some time. Please reload the page in a few seconds to see the updated list of pending tickets""" % ", ".join(users)) for ticket in tickets: if action != "Delete": # We only fill here users_to_update and packs_to_update if action is not # "Delete". See comment in "Delete" action case some lines above users_to_update.add(ticket.sound.user.profile) if ticket.sound.pack: packs_to_update.add(ticket.sound.pack) invalidate_template_cache("user_header", ticket.sender.id) invalidate_all_moderators_header_cache() moderator_only = msg_form.cleaned_data.get( "moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() # Send emails if notification: ticket.send_notification_emails(notification, Ticket.USER_ONLY) # Update number of sounds for each user for profile in users_to_update: profile.update_num_sounds() # Process packs for pack in packs_to_update: pack.process() else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={'action': 'Approve'}) msg_form = ModerationMessageForm() qs = Ticket.objects.select_related() \ .filter(assignee=user_id) \ .exclude(status=TICKET_STATUS_CLOSED) \ .exclude(sound=None) \ .order_by('status', '-created') pagination_response = paginate( request, qs, settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE) pagination_response['page'].object_list = list( pagination_response['page'].object_list) # Because some tickets can have related sound which has disappeared or on deletion time the ticket # has not been properly updated, we need to check whether the sound that is related does in fact # exist. If it does not, we set the related sound to None and the status of the ticket to closed # as should have been set at sound deletion time. for ticket in pagination_response['page'].object_list: if not ticket.sound: pagination_response['page'].object_list.remove(ticket) ticket.status = TICKET_STATUS_CLOSED ticket.save() moderator_tickets_count = qs.count() moderation_texts = MODERATION_TEXTS show_pagination = moderator_tickets_count > settings.MAX_TICKETS_IN_MODERATION_ASSIGNED_PAGE tvars = { "moderator_tickets_count": moderator_tickets_count, "moderation_texts": moderation_texts, "page": pagination_response['page'], "paginator": pagination_response['paginator'], "current_page": pagination_response['current_page'], "show_pagination": show_pagination, "mod_sound_form": mod_sound_form, "msg_form": msg_form, "selected": "queue" } return render(request, 'tickets/moderation_assigned.html', tvars)
def ticket(request, ticket_key): can_view_moderator_only_messages = __can_view_mod_msg(request) clean_status_forms = True clean_comment_form = True ticket = get_object_or_404(Ticket, key=ticket_key) if request.method == "POST": # Left ticket message if is_selected(request, "recaptcha") or (request.user.is_authenticated() and is_selected(request, "message")): tc_form = __get_tc_form(request) if tc_form.is_valid(): tc = TicketComment() tc.text = tc_form.cleaned_data["message"] tc.moderator_only = tc_form.cleaned_data.get("moderator_only", False) if tc.text: if request.user.is_authenticated(): tc.sender = request.user tc.ticket = ticket tc.save() if not request.user.is_authenticated(): email_to = Ticket.MODERATOR_ONLY elif request.user == ticket.sender: email_to = Ticket.MODERATOR_ONLY else: email_to = Ticket.USER_ONLY ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, email_to) else: clean_comment_form = False # update sound ticket elif is_selected(request, "tm") or is_selected(request, "ss"): ticket_form = TicketModerationForm(request.POST, prefix="tm") sound_form = SoundStateForm(request.POST, prefix="ss") if ticket_form.is_valid() and sound_form.is_valid(): clean_status_forms = True clean_comment_form = True sound_state = sound_form.cleaned_data.get("state") # Sound should be deleted if sound_state == "DE": if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED tc = TicketComment( sender=request.user, text="Moderator %s deleted the sound and closed the ticket" % request.user, ticket=ticket, moderator_only=False, ) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_DELETED, ticket.USER_ONLY) # Set another sound state that's not delete else: if ticket.content: ticket.content.content_object.moderation_state = sound_state # Mark the index as dirty so it'll be indexed in Solr if sound_state == "OK": ticket.content.content_object.mark_index_dirty() ticket.content.content_object.save() ticket.status = ticket_form.cleaned_data.get("status") tc = TicketComment( sender=request.user, text="Moderator %s set the sound to %s and the ticket to %s." % (request.user, "pending" if sound_state == "PE" else sound_state, ticket.status), ticket=ticket, moderator_only=False, ) tc.save() ticket.send_notification_emails(ticket.NOTIFICATION_UPDATED, ticket.USER_ONLY) ticket.save() if clean_status_forms: ticket_form = TicketModerationForm(initial={"status": ticket.status}, prefix="tm") sound_form = SoundStateForm( initial={"state": ticket.content.content_object.moderation_state if ticket.content else "DE"}, prefix="ss" ) if clean_comment_form: tc_form = __get_tc_form(request, False) return render_to_response("tickets/ticket.html", locals(), context_instance=RequestContext(request))
def moderation_assigned(request, user_id): can_view_moderator_only_messages = __can_view_mod_msg(request) clear_forms = True if request.method == "POST": mod_sound_form = SoundModerationForm(request.POST) msg_form = ModerationMessageForm(request.POST) if mod_sound_form.is_valid() and msg_form.is_valid(): ticket = Ticket.objects.get(id=mod_sound_form.cleaned_data.get("ticket", False)) action = mod_sound_form.cleaned_data.get("action") msg = msg_form.cleaned_data.get("message", False) moderator_only = msg_form.cleaned_data.get("moderator_only", False) if msg: tc = TicketComment(sender=ticket.assignee, text=msg, ticket=ticket, moderator_only=moderator_only) tc.save() if action == "Approve": ticket.status = TICKET_STATUS_CLOSED ticket.content.content_object.moderation_state = "OK" ticket.content.content_object.save() ticket.save() ticket.content.content_object.mark_index_dirty() if msg: ticket.send_notification_emails(Ticket.NOTIFICATION_APPROVED_BUT, Ticket.USER_ONLY) else: ticket.send_notification_emails(Ticket.NOTIFICATION_APPROVED, Ticket.USER_ONLY) elif action == "Defer": ticket.status = TICKET_STATUS_DEFERRED ticket.save() # only send a notification if a message was added if msg: ticket.send_notification_emails(Ticket.NOTIFICATION_QUESTION, Ticket.USER_ONLY) elif action == "Return": ticket.assignee = None ticket.status = TICKET_STATUS_NEW # no notification here ticket.save() elif action == "Delete": ticket.send_notification_emails(Ticket.NOTIFICATION_DELETED, Ticket.USER_ONLY) # to prevent a crash if the form is resubmitted if ticket.content: ticket.content.content_object.delete() ticket.content.delete() ticket.content = None ticket.status = TICKET_STATUS_CLOSED ticket.save() elif action == "Whitelist": # Get all currently pending sound tickets for user whitelist_user = ticket.sender whitelist_user.profile.is_whitelisted = True whitelist_user.profile.save() pending_tickets = Ticket.objects.filter(sender=whitelist_user, source="new sound").exclude( status=TICKET_STATUS_CLOSED ) # Set all sounds to OK and the tickets to closed for pending_ticket in pending_tickets: if pending_ticket.content: pending_ticket.content.content_object.moderation_state = "OK" pending_ticket.content.content_object.save() pending_ticket.content.content_object.mark_index_dirty() # This could be done with a single update, but there's a chance # we lose a sound that way (a newly created ticket who's sound # is not set to OK, but the ticket is closed). pending_ticket.status = TICKET_STATUS_CLOSED pending_ticket.save() ticket.send_notification_emails(Ticket.NOTIFICATION_WHITELISTED, Ticket.USER_ONLY) else: clear_forms = False if clear_forms: mod_sound_form = SoundModerationForm(initial={"action": "Approve"}) msg_form = ModerationMessageForm() moderator_tickets = ( Ticket.objects.select_related() .filter(assignee=user_id) .exclude(status=TICKET_STATUS_CLOSED) .exclude(content=None) .order_by("status", "-created") ) moderator_tickets_count = len(moderator_tickets) moderation_texts = MODERATION_TEXTS return render_to_response("tickets/moderation_assigned.html", locals(), context_instance=RequestContext(request))