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 ])
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
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())