Exemplo n.º 1
0
    def get_pg_sql_insert_clause(self, document_language: str,
                                 document_ids: List) -> SQLInsertClause:
        document_ids = self.python_value_to_indexed_field_value(
            document_ids)  # type: Set[int]

        links = list()  # List[Tuple[str, str]]

        if document_ids:
            for document_id, document_name, document_type_code, project_id \
                    in Document.all_objects \
                    .filter(pk__in=document_ids) \
                    .values_list('id', 'name', 'document_type__code', 'project_id') \
                    .order_by('id'):
                links.append((document_name,
                              doc_editor_url(document_type_code, project_id,
                                             document_id)))

            links = [
                '<a href="{1}">{0}</a>'.format(doc_name, doc_id)
                for doc_name, doc_id in links
            ]
            document_ids = [str(doc_id) for doc_id in document_ids]

        return SQLInsertClause(
            '"{ids_column}", '
            '"{links_column}"'.format(ids_column=self.document_ids_column,
                                      links_column=self.document_links_column),
            [], '%s, %s', [
                ', '.join(document_ids) if document_ids else None,
                '\n'.join(links) if links else None
            ])
Exemplo n.º 2
0
    def get_json_data(self, **kwargs):
        data = super().get_json_data()

        for item in data['data']:
            item['document_a__url'] = \
                doc_editor_url(item['document_a__document_type__code'],
                               item['document_a__project_id'], item['document_a__pk'])
            item['document_b__url'] = \
                doc_editor_url(item['document_b__document_type__code'],
                               item['document_b__project_id'], item['document_b__pk'])
            item['project_a__url'] = \
                project_documents_url(item['document_a__document_type__code'],
                                      item['document_a__project_id'])
            item['project_b__url'] = \
                project_documents_url(item['document_b__document_type__code'],
                                      item['document_b__project_id'])
        return data
    def render_notification(
        package_id: str,
        subscription: DocumentNotificationSubscription,
        data: DocumentNotificationSource,
        log_routine: Optional[Callable[[str], None]] = None
    ) -> Optional[RenderedNotification]:
        if package_id in NotificationRenderer.package_already_sent_user_ids:
            already_sent_user_ids = NotificationRenderer.package_already_sent_user_ids[
                package_id]
        else:
            already_sent_user_ids = set()
            NotificationRenderer.package_already_sent_user_ids[
                package_id] = already_sent_user_ids

        document_type = data.document.document_type
        event_info = subscription.get_event_info()
        if not event_info:
            return None

        NotificationRenderer.get_document_fields(data, document_type,
                                                 subscription, data.changes)
        doc_field_values = data.field_values
        if not doc_field_values:
            return None
        display_fields = set(doc_field_values.keys())

        recipients = subscription.resolve_recipients(data.field_values)
        recipients = {
            r
            for r in recipients if r.id not in already_sent_user_ids
        } if recipients else None
        if not recipients:
            return None

        changes_filtered = dict()
        if data.changes:
            for code, old_new in data.changes.items():
                if code in FIELD_CODES_HIDE_BY_DEFAULT:
                    continue
                if old_new[0] == old_new[1] or data.field_values.get(
                        code) == old_new[0]:
                    continue
                changes_filtered[code] = old_new
        changes = changes_filtered

        display_fields.update(changes.keys())

        template_context = {
            'app_url':
            root_url(),
            'doc_url':
            doc_editor_url(document_type.code, data.document.project_id,
                           data.document.pk),
            'event_code':
            event_info.code,
            'event_title':
            event_info.title,
            'event_initiator':
            data.changed_by_user,
            'document':
            data.field_values,
            'fields': [{
                'code': h.field_code,
                'title': h.field_title,
                'type': h.field_type,
                'value': data.field_values.get(h.field_code),
                'changed': h.field_code in changes,
                'changes': changes.get(h.field_code),
            } for h in data.field_handlers if h.field_code in display_fields],
            'changes':
            changes,
            'changed_by_user':
            data.changed_by_user,
            'logo_url':
            'images/logo.png'
        }  # type: Dict[str, Any]

        subject_template = subscription.subject or event_info.default_subject
        header_template = subscription.header or event_info.default_header

        subject = Template(subject_template).render(template_context)
        header = Template(header_template).render(template_context)

        template_context.update({'subject': subject, 'header': header})

        html = None

        html_template = get_notification_template_resource(
            os.path.join(subscription.template_name, 'template.html'))
        if html_template:
            template_src = html_template.decode('utf-8')
            template_obj = Template(template_src)
            html = template_obj.render(template_context)

        txt_template_name = os.path.join(subscription.template_name,
                                         'template.txt')
        txt_template = get_notification_template_resource(txt_template_name)
        if not txt_template:
            raise RuntimeError(f'Txt template not found: {txt_template_name}')
        txt = Template(txt_template.decode('utf-8')).render(template_context)

        image_dir = os.path.join(subscription.template_name, 'images')

        return RenderedNotification(dst_users=recipients,
                                    subject=subject,
                                    txt=txt,
                                    html=html,
                                    image_dir=image_dir,
                                    cc=subscription.get_cc_addrs())
    def render_notification_pack(
            package_ids: List[str],
            subscription: DocumentNotificationSubscription,
            data: List[DocumentNotificationSource]
    ) -> List[RenderedNotification]:
        notifications_pack = []  # type: List[RenderedNotification]
        if not data:
            return notifications_pack
        event_info = subscription.get_event_info()
        if not event_info:
            return notifications_pack

        already_sent_user_ids = set()
        for pack_id in package_ids:
            if pack_id in NotificationRenderer.package_already_sent_user_ids:
                stored = NotificationRenderer.package_already_sent_user_ids[
                    pack_id]
                if stored:
                    already_sent_user_ids.update(stored)
            else:
                NotificationRenderer.package_already_sent_user_ids[
                    pack_id] = set()

        # merge message bodies
        # all the documents have the same type
        document_type = data[0].document.document_type

        template_context = {
            'app_url': root_url(),
            'event_code': event_info.code,
            'event_title': event_info.title,
            'documents': [],
            'logo_url': 'images/logo.png'
        }

        # get recipients per message, split message packs by recipients
        msgs_by_recipients = {}  # type:[str, List[DocumentNotificationSource]]
        recipients_by_key = {}  # type:[str, List[User]]
        for msg_data in data:
            NotificationRenderer.get_document_fields(msg_data, document_type,
                                                     subscription,
                                                     msg_data.changes)
            if not msg_data.field_values:
                continue

            recipients = subscription.resolve_recipients(
                msg_data.field_values)  # type:Set[User]
            recipients = {
                r
                for r in recipients if r.id not in already_sent_user_ids
            } if recipients else None
            if not recipients:
                continue
            recp_ids = [str(r.pk) for r in recipients]
            recp_ids.sort()
            recp_key = ','.join(recp_ids)
            if recp_key in msgs_by_recipients:
                msgs_by_recipients[recp_key].append(msg_data)
            else:
                msgs_by_recipients[recp_key] = [msg_data]
                recipients_by_key[recp_key] = recipients

        for recp_key in msgs_by_recipients:
            recipients = recipients_by_key[recp_key]
            for msg_data in msgs_by_recipients[recp_key]:
                doc_field_values = msg_data.field_values
                display_fields = set(doc_field_values.keys())

                changes_filtered = dict()

                if msg_data.changes:
                    for code, old_new in msg_data.changes.items():
                        if code in FIELD_CODES_HIDE_BY_DEFAULT:
                            continue
                        if old_new[0] == old_new[
                                1] or msg_data.field_values.get(
                                    code) == old_new[0]:
                            continue
                        changes_filtered[code] = old_new
                changes = changes_filtered

                display_fields.update(changes.keys())

                document_context = {
                    'doc_url':
                    doc_editor_url(document_type.code,
                                   msg_data.document.project_id,
                                   msg_data.document.pk),
                    'event_initiator':
                    msg_data.changed_by_user,
                    'document':
                    msg_data.field_values,
                    'fields': [{
                        'code': h.field_code,
                        'title': h.field_title,
                        'type': h.field_type,
                        'value': msg_data.field_values.get(h.field_code),
                        'changed': h.field_code in changes,
                        'changes': changes.get(h.field_code),
                    } for h in msg_data.field_handlers
                               if h.field_code in display_fields],
                    'changes':
                    changes,
                    'changed_by_user':
                    msg_data.changed_by_user
                }  # type: Dict[str, Any]
                template_context['documents'].append(document_context)

            html = None
            subject_template = subscription.subject or event_info.default_bulk_subject
            header_template = subscription.header or event_info.default_bulk_header

            subject = Template(subject_template).render(template_context)
            header = Template(header_template).render(template_context)

            template_context.update({'subject': subject, 'header': header})

            html_template = get_notification_template_resource(
                os.path.join(subscription.template_name, 'template_pack.html'))
            if html_template:
                html = Template(
                    html_template.decode('utf-8')).render(template_context)

            txt_template_name = os.path.join(subscription.template_name,
                                             'template_pack.txt')
            txt_template = get_notification_template_resource(
                txt_template_name)
            if not txt_template:
                raise RuntimeError(
                    'Txt template not found: {0}'.format(txt_template_name))
            txt = Template(
                txt_template.decode('utf-8')).render(template_context)

            image_dir = os.path.join(subscription.template_name, 'images')

            notification = RenderedNotification(dst_users=recipients,
                                                subject=subject,
                                                txt=txt,
                                                html=html,
                                                image_dir=image_dir,
                                                cc=subscription.get_cc_addrs())
            notifications_pack.append(notification)
        return notifications_pack
Exemplo n.º 5
0
def render_notification(already_sent_user_ids: Set,
                        subscription: DocumentNotificationSubscription,
                        document: Document,
                        field_handlers: List[FieldHandler],
                        field_values: Dict[str, Any],
                        changes: Dict[str, Tuple[Any, Any]] = None,
                        changed_by_user: User = None) -> Optional[RenderedNotification]:
    document_type = document.document_type
    event_info = subscription.get_event_info()
    if not event_info:
        return None
    recipients = subscription.resolve_recipients(field_values)
    recipients = {r for r in recipients if r.id not in already_sent_user_ids} if recipients else None
    if not recipients:
        return None

    display_fields = set(subscription.generic_fields or {})
    display_fields.update(FIELD_CODES_SHOW_BY_DEFAULT_GENERIC if document_type.is_generic()
                          else FIELD_CODES_SHOW_BY_DEFAULT_NON_GENERIC)
    display_fields.update({f.code for f in subscription.user_fields.all() if f.document_type == document_type})

    changes_filtered = dict()

    if changes:
        for code, old_new in changes.items():
            if code in FIELD_CODES_HIDE_BY_DEFAULT:
                continue
            if old_new[0] == old_new[1] or field_values.get(code) == old_new[0]:
                continue
            changes_filtered[code] = old_new
    changes = changes_filtered

    display_fields.update(changes.keys())

    template_context = {
        'app_url': root_url(),
        'doc_url': doc_editor_url(document_type.code, document.project_id, document.pk),
        'event_code': event_info.code,
        'event_title': event_info.title,
        'event_initiator': changed_by_user,
        'document': field_values,
        'fields': [{
            'code': h.field_code,
            'title': h.field_title,
            'type': h.field_type,
            'value': field_values.get(h.field_code),
            'changed': h.field_code in changes,
            'changes': changes.get(h.field_code),
        } for h in field_handlers if h.field_code in display_fields],
        'changes': changes,
        'changed_by_user': changed_by_user
    }  # type: Dict[str, Any]

    subject_template = subscription.subject or event_info.default_subject
    header_template = subscription.header or event_info.default_subject

    subject = Template(subject_template).render(template_context)
    header = Template(header_template).render(template_context)

    template_context.update({
        'subject': subject,
        'header': header
    })

    html = None

    html_template = get_notification_template_resource(os.path.join(subscription.template_name, 'template.html'))
    if html_template:
        html = Template(html_template.decode('utf-8')).render(template_context)

    txt_template_name = os.path.join(subscription.template_name, 'template.txt')
    txt_template = get_notification_template_resource(txt_template_name)
    if not txt_template:
        raise RuntimeError('Txt template not found: {0}'.format(txt_template_name))
    txt = Template(txt_template.decode('utf-8')).render(template_context)

    image_dir = os.path.join(subscription.template_name, 'images')

    return RenderedNotification(dst_users=recipients,
                                subject=subject,
                                txt=txt,
                                html=html,
                                image_dir=image_dir,
                                cc=subscription.get_cc_addrs())