def email2ticket(string): """ Parse un mail et crée ou modifie le ticket concerné """ errors = [] mail = email.message_from_string(string) cur = None match = pattern_from.search(mail.get('From', '')) mail_from = mail.get('Return-Path', mail.get('Reply-To', match.groups()[0] if match else None)) references = mail.get('References', '').split() if not references: references = mail.get('In-Reply-To', '').split() if references: ticket = Ticket.objects.get(message_id__in=references) else: ticket = Ticket() # Get first part for part in mail.walk(): if part.get_content_type() in ('text/html', 'text/plain'): cur = part break if cur is None: return send_error(mail_from, ['Impossible de parser le message']) content = cur.get_payload(decode=True) if cur.get_content_type() == 'text/html': enc = cur.get_charsets()[0] content = content.decode(enc, 'ignore') content = html2text(content) match = pattern_body.search(content) if not match: errors.append('Contenu vide ou non encadré par [contenu][/contenu]') content = None else: content = match.groups()[0] user = User.objects.get(pk=settings.EMAIL_USER_PK) if references and content: # New comment form = type("", (), {})() form.cleaned_data = {'comment': content, 'internal': False} form.instance = ticket request = type("", (), {})() request.user = user post_comment(form, request) print "Ticket commenté ", ticket.pk elif not references: # New ticket try: subject = mail.get('Subject', '') match = pattern_subject.search(subject) ticket.client = Client.objects.get(pk=match.groups()[0]) subject = subject[match.span()[1]:] ticket.title = " ".join([part[0].decode(part[1] or 'utf8') for part in email.header.decode_header(subject)]) except: errors.append('Impossible de parser le sujet, client invalide ou sujet mal formé') if errors: send_error(mail_from, errors) else: ticket.message_id = mail.get('Message-ID', None) ticket.opened_by = user ticket.state = State.objects.get(pk=settings.TICKET_STATE_NEW) ticket.category = Category.objects.get(pk=settings.EMAIL_TICKET_CATEGORY_DEFAULT) ticket.text = content ticket.save() print "Ticket crée : ", ticket.pk elif errors: send_error(mail_from, errors) # Get attachements for part in mail.walk(): filename = part.get_filename() content_type = part.get_content_type() if filename and content_type in settings.IMAP_ALLOWED_CONTENT_TYPES: ticket_file = TicketFile(ticket=ticket, filename=filename, content_type=content_type, data=part.get_payload(decode=True)) ticket_file.save()
def modify(request, ticket_id): def exit_action(): saveaction = request.POST.get("savebutton", "save") if saveaction == "save": return redirect("ticket_modify", ticket_id=ticket_id) elif saveaction == "new": return redirect("ticket_partial_new") elif saveaction == "return": backlinks = request.backlinks precedent = backlinks[-1:] if not precedent: return redirect("ticket_modify", ticket_id=ticket_id) else: return precedent[0].redirect(request) else: raise PermissionDenied("Hacking attempt!") qs = Ticket.objects.all().filter_ticket_by_user(request.user, no_client=True) ticket = get_object_or_404(qs, pk=ticket_id) # Si c'est un fils rediriger vers le pêre au bon endroit # (C'est utile uniquement pour le chargement de la page) if ticket.parent: return http.HttpResponseRedirect("/ticket/modify/%d/#child%s" % (ticket.parent_id, ticket_id)) if not ticket.text and ticket.title == INVALID_TITLE: ticket.title = None # Si le ticket n'est pas rattaché à aucun client, on l'affecte au client de l'utilisateur if not ticket.client: ticket.client = request.user.my_userprofile.client if request.user.has_perm("ticket.add_ticket_full"): template_name = "ticket/modify.html" TicketForm = NewTicketForm child = ticket.child.order_by('date_open') TicketChildForm = ChildForm else: template_name = "ticket/modify_small.html" TicketForm = NewTicketSmallForm child = ticket.child.filter(diffusion=True).order_by('date_open') TicketChildForm = ChildFormSmall ChildFormSet = modelformset_factory(Ticket, form=TicketChildForm, extra=0, can_delete=True) if request.method == "POST": if (request.POST.get("_validate-ticket", None) and request.user.has_perm("ticket.can_validate_ticket") and ticket.validated_by is None): ticket.validated_by = request.user ticket.save() # Instanciating the TicketForm changes ticket... So we need to store it # Before in order to do permission checking. ticket_old_assigned_to_pk = ticket.assigned_to and ticket.assigned_to.pk or None form = TicketForm(request.POST, request.FILES, instance=ticket, user=request.user) # Il faut valider les fils en premier pour ne pas se faire jetter si on ferme tout child_formset = ChildFormSet(request.POST, queryset=child) deleted_forms = child_formset.deleted_forms if hasattr(child_formset, 'deleted_forms') else [] # Save existing childs for f in child_formset.initial_forms: if not f in deleted_forms and f.is_valid(): f.save() post_comment(f, request) for f in deleted_forms: f.instance.delete() # Add new childs if request.user.has_perm('ticket.can_add_child'): for f in child_formset.extra_forms: if f.is_valid(): new_child = copy_model_instance(ticket) # Valeurs à écraser for a in f.Meta.fields: setattr(new_child, a, f.cleaned_data.get(a)) new_child.opened_by = request.user new_child.date_open = datetime.datetime.now() new_child.parent = ticket new_child.save() f.instance = new_child post_comment(f, request) if form.is_valid(): # Si l'utilisateur peut assigner ce ticket à l'utilisateur passé en POST if not request.user.is_superuser and \ form.cleaned_data["assigned_to"] and \ ticket_old_assigned_to_pk != form.cleaned_data["assigned_to"].pk and \ form.cleaned_data["assigned_to"] not in ClaritickUser.objects.get(pk=request.user.pk).get_child_users(): raise PermissionDenied() form.save() post_comment(form, request) update_ticket_last_seen(request, ticket.pk) # Alarme automatique if (ticket.priority and ticket.priority.alarm and not ticket.ticketalarm_set.all()): ticket.ticketalarm_set.create(reason=ticket.priority.alarm, user_open=request.user) # Appel du client if form.cleaned_data['appel']: ticket.ticketappel_set.create(user=request.user) # Rappels de ticket rappel = None if form.cleaned_data['calendar_rappel']: ident = ticket.pk current_user = User.objects.get(pk=request.user.id) # Select or create existing rappel try: rappel = Rappel.objects.filter(ticket=ident) \ .filter(user=current_user).get() except Rappel.DoesNotExist: rappel = Rappel() rappel.ticket = ticket rappel.date_email = None rappel.date = form.cleaned_data['calendar_rappel'] rappel.user = current_user rappel.save() if form.cleaned_data['delete_rappel'] and rappel: rappel.delete() file = form.cleaned_data["file"] if file: ticket_file = TicketFile(ticket=ticket, filename=file.name, content_type=file.content_type) if file.multiple_chunks(): dataList = [] for chunk in file.chunks(): dataList.append(chunk) data = "".join(dataList) else: data = file.read() ticket_file.data = data ticket_file.save() # BonDeCommande if form.cleaned_data["bondecommande"]: bdc = form.cleaned_data["bondecommande"] if bdc.ticket: raise PermissionDenied() if ticket.client and bdc.client != ticket.client: raise PermissionDenied("Etes vous sur de vouloir faire ça ? Ce n'est pas le meme client.") bdc.ticket = ticket bdc.save() return exit_action() else: try: rappel = Rappel.objects.get(ticket=ticket, user=request.user) rappel_date = rappel.date except Rappel.DoesNotExist: rappel_date = "" form = TicketForm(instance=ticket, user=request.user, initial={"calendar_rappel": rappel_date}) child_formset = ChildFormSet(queryset=child) for f in child_formset.forms: filter_form_for_user(f, request.user) comments = django.contrib.comments.get_model().objects.filter(content_type__model="ticket").\ filter(models.Q(object_pk__in=[str(c.pk) for c in child]) | models.Q(object_pk=str(ticket.pk))) ticket.comment = [] for c in comments: if c.object_pk == str(ticket.pk): ticket.comment.append(c) else: for f in child_formset.forms: if not hasattr(f.instance, 'comment'): f.instance.comment = [] if c.object_pk == str(f.instance.pk): f.instance.comment.append(c) update_ticket_last_seen(request, ticket.pk) # List of rappel other user about the same ticket list_rappel_other_user = Rappel.objects.all() \ .select_related('user__username') \ .filter(ticket=ticket.pk) \ .exclude(user=request.user) # Bon de commande bondecommades = BonDeCommande.objects.all().filter_by_user(request.user).filter(ticket=ticket.pk) return render_to_response(template_name, { "form": form, "child_formset": child_formset, "bondecommandes": bondecommades, "list_rappel_other_user": list_rappel_other_user, }, context_instance=RequestContext(request))