def notify_new_task_application_slack(instance): instance = clean_instance(instance, Application) if not slack_utils.is_task_notification_enabled(instance.task, slugs.EVENT_APPLICATION): return application_url = '%s/work/%s/applications/' % (TUNGA_URL, instance.task_id) slack_msg = "New application from %s" % instance.user.short_name attachments = [{ slack_utils.KEY_TITLE: instance.task.summary, slack_utils.KEY_TITLE_LINK: application_url, slack_utils.KEY_TEXT: '%s%s%s%s\n\n<%s|View details on Tunga>' % (truncatewords(convert_to_text(instance.pitch), 100), instance.hours_needed and '\n*Workload:* {} hrs'.format(instance.hours_needed) or '', instance.deliver_at and '\n*Delivery Date:* {}'.format( instance.deliver_at.strftime("%d %b, %Y at %H:%M GMT")) or '', instance.remarks and '\n*Remarks:* {}'.format( truncatewords(convert_to_text(instance.remarks), 100)) or '', application_url), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_TUNGA }] slack_utils.send_integration_message(instance.task, message=slack_msg, attachments=attachments)
def render_mail(subject, template_prefix, to_emails, context, bcc=None, cc=None, **kwargs): """ :param subject: :param template_prefix: path to template for email with extension (e.g hello if template name is hello.html) :param to_emails: :param context: variables to be passed into template :param bcc: :param cc: :param kwargs: :return: """ from_email = DEFAULT_FROM_EMAIL if not re.match(r'^\[\s*Tunga', subject): subject = '{} {}'.format(EMAIL_SUBJECT_PREFIX, subject) bodies = {} for ext in ['html', 'txt']: try: template_name = '{0}.{1}'.format(template_prefix, ext) bodies[ext] = render_to_string(template_name, context).strip() except TemplateDoesNotExist: if ext == 'txt': if 'html' in bodies: # Compose text body from html bodies[ext] = convert_to_text(bodies['html']) else: # We need at least one body raise if bodies: msg = EmailMultiAlternatives(subject, bodies['txt'], from_email, to_emails, bcc=bcc, cc=cc) if 'html' in bodies: try: html_body = render_to_string( 'tunga/email/base.html', dict(email_content=bodies['html'])).strip() except TemplateDoesNotExist: html_body = bodies['html'] msg.attach_alternative(premailer.transform(html_body), 'text/html') else: raise TemplateDoesNotExist return msg
def notify_task_application_response_slack(instance, admin=True): instance = clean_instance(instance, Application) application_url = '%s/work/%s/applications/' % (TUNGA_URL, instance.task_id) task_url = '%s/work/%s/' % (TUNGA_URL, instance.task.id) slack_msg = "Task Application {} | <{}|View on Tunga>".format( instance.status == STATUS_ACCEPTED and 'accepted' or 'rejected', task_url) attachments = [{ slack_utils.KEY_TITLE: instance.task.summary, slack_utils.KEY_TITLE_LINK: application_url, slack_utils.KEY_TEXT: '%s%s%s%s\n\n<%s|View on Tunga>' % (truncatewords(convert_to_text(instance.pitch), 100), instance.hours_needed and '\n*Workload:* {} hrs'.format(instance.hours_needed) or '', instance.deliver_at and '\n*Delivery Date:* {}'.format( instance.deliver_at.strftime("%d %b, %Y")) or '', instance.remarks and '\n*Remarks:* {}'.format( truncatewords(convert_to_text(instance.remarks), 100)) or '', application_url), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_TUNGA }] if admin: slack_utils.send_incoming_webhook( SLACK_STAFF_INCOMING_WEBHOOK, { slack_utils.KEY_TEXT: slack_msg, slack_utils.KEY_ATTACHMENTS: attachments, slack_utils.KEY_CHANNEL: SLACK_STAFF_LEADS_CHANNEL }) else: slack_utils.send_integration_message(instance.task, message=slack_msg, attachments=attachments)
def notify_task_application_response_slack(instance, admin=True): instance = clean_instance(instance, Application) application_url = '%s/work/%s/applications/' % (TUNGA_URL, instance.task_id) task_url = '%s/work/%s/' % (TUNGA_URL, instance.task.id) slack_msg = "Task Application {} | <{}|View on Tunga>".format( instance.status == STATUS_ACCEPTED and 'accepted' or 'rejected', task_url ) attachments = [ { slack_utils.KEY_TITLE: instance.task.summary, slack_utils.KEY_TITLE_LINK: application_url, slack_utils.KEY_TEXT: '%s%s%s%s\n\n<%s|View on Tunga>' % (truncatewords(convert_to_text(instance.pitch), 100), instance.hours_needed and '\n*Workload:* {} hrs'.format(instance.hours_needed) or '', instance.deliver_at and '\n*Delivery Date:* {}'.format( instance.deliver_at.strftime("%d %b, %Y") ) or '', instance.remarks and '\n*Remarks:* {}'.format( truncatewords(convert_to_text(instance.remarks), 100) ) or '', application_url), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_TUNGA } ] if admin: slack_utils.send_incoming_webhook( SLACK_STAFF_INCOMING_WEBHOOK, { slack_utils.KEY_TEXT: slack_msg, slack_utils.KEY_ATTACHMENTS: attachments, slack_utils.KEY_CHANNEL: SLACK_STAFF_LEADS_CHANNEL } ) else: slack_utils.send_integration_message(instance.task, message=slack_msg, attachments=attachments)
def notify_new_task_application_slack(instance, admin=True): instance = clean_instance(instance, Application) if not slack_utils.is_task_notification_enabled(instance.task, slugs.EVENT_APPLICATION): return application_url = '%s/work/%s/applications/' % (TUNGA_URL, instance.task_id) slack_msg = "New application from %s" % instance.user.short_name attachments = [ { slack_utils.KEY_TITLE: instance.task.summary, slack_utils.KEY_TITLE_LINK: application_url, slack_utils.KEY_TEXT: '%s%s%s%s\n\n<%s|View on Tunga>' % (truncatewords(convert_to_text(instance.pitch), 100), instance.hours_needed and '\n*Workload:* {} hrs'.format(instance.hours_needed) or '', instance.deliver_at and '\n*Delivery Date:* {}'.format( instance.deliver_at.strftime("%d %b, %Y") ) or '', instance.remarks and '\n*Remarks:* {}'.format( truncatewords(convert_to_text(instance.remarks), 100) ) or '', application_url), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_TUNGA } ] if admin: slack_utils.send_incoming_webhook( SLACK_STAFF_INCOMING_WEBHOOK, { slack_utils.KEY_TEXT: slack_msg, slack_utils.KEY_ATTACHMENTS: attachments, slack_utils.KEY_CHANNEL: SLACK_STAFF_LEADS_CHANNEL } ) else: slack_utils.send_integration_message(instance.task, message=slack_msg, attachments=attachments)
def log_emails(responses, to, subject=None, cc=None, bcc=None, deal_ids=None): mandrill_client = get_client() print('logging responses: ', responses) if responses: for response in responses: content_id = response.get('_id') print('mandrill response', content_id, response) if response.get('status') == 'sent': tries = 0 while True: try: sent_details = mandrill_client.messages.content( content_id) except mandrill.UnknownMessageError: sent_details = None print('sent_details', sent_details) if sent_details: email_html = sent_details.get('html', '') email_text = sent_details.get('text', '') create_hubspot_engagement( from_email=sent_details.get( 'from_email', DEFAULT_FROM_EMAIL), to_emails=isinstance(to, (str, unicode)) and [to] or to, subject=sent_details.get('subject', subject), body=email_text or convert_to_text(email_html), **dict(cc=cc, bcc=bcc, html=email_html, deal_ids=deal_ids)) break else: # Hacks to wait to Mandrill indicates the message so it can be logged in hubspot tries += 1 if tries >= 60: # Give up after for 15 minutes break else: # Wait for 15 seconds sleep(15)
def render_mail(subject, template_prefix, to_emails, context, bcc=None, cc=None, **kwargs): """ :param subject: :param template_prefix: path to template for email with extension (e.g hello if template name is hello.html) :param to_emails: :param context: variables to be passed into template :param bcc: :param cc: :param kwargs: :return: """ from_email = DEFAULT_FROM_EMAIL if not re.match(r'^\[\s*Tunga', subject): subject = '{} {}'.format(EMAIL_SUBJECT_PREFIX, subject) bodies = {} for ext in ['html', 'txt']: try: template_name = '{0}.{1}'.format(template_prefix, ext) bodies[ext] = render_to_string(template_name, context).strip() except TemplateDoesNotExist: if ext == 'txt': if 'html' in bodies: # Compose text body from html bodies[ext] = convert_to_text(bodies['html']) else: # We need at least one body raise if bodies: msg = EmailMultiAlternatives(subject, bodies['txt'], from_email, to_emails, bcc=bcc, cc=cc) if 'html' in bodies: try: html_body = render_to_string( 'tunga/email/base.html', dict(email_content=bodies['html']) ).strip() except TemplateDoesNotExist: html_body = bodies['html'] msg.attach_alternative(premailer.transform(html_body), 'text/html') else: raise TemplateDoesNotExist return msg
def log_emails(responses, to, subject=None, cc=None, bcc=None, deal_ids=None): mandrill_client = get_client() if responses: for response in responses: content_id = response.get('_id') print('mandrill response', content_id, response) if response.get('status') == 'sent': tries = 0 while True: try: sent_details = mandrill_client.messages.content(content_id) except mandrill.UnknownMessageError: sent_details = None print('sent_details', sent_details) if sent_details: email_html = sent_details.get('html', '') email_text = sent_details.get('text', '') create_hubspot_engagement( from_email=sent_details.get('from_email', DEFAULT_FROM_EMAIL), to_emails=isinstance(to, (str, unicode)) and [to] or to, subject=sent_details.get('subject', subject), body=email_text or convert_to_text(email_html), **dict(cc=cc, bcc=bcc, html=email_html, deal_ids=deal_ids) ) break else: # Hacks to wait to Mandrill indicates the message so it can be logged in hubspot tries += 1 if tries >= 60: # Give up after for 15 minutes break else: # Wait for 15 seconds sleep(15)
def text_body(self): return convert_to_text(convert_slack_to_html(self.body))
def create_progress_report_slack_message(instance, updated=False, to_client=False): is_pm_report = instance.event.type in [LEGACY_PROGRESS_EVENT_TYPE_PM, LEGACY_PROGRESS_EVENT_TYPE_MILESTONE_INTERNAL] is_client_report = instance.event.type in [LEGACY_PROGRESS_EVENT_TYPE_CLIENT, LEGACY_PROGRESS_EVENT_TYPE_CLIENT_MID_SPRINT] is_pm_or_client_report = is_pm_report or is_client_report is_dev_report = not is_pm_or_client_report report_url = '%s/work/%s/event/%s/' % (TUNGA_URL, instance.event.task_id, instance.event_id) slack_msg = "{} {} a {} | {}".format( instance.user.display_name.encode('utf-8'), updated and 'updated' or 'submitted', is_client_report and "Weekly Survey" or "Progress Report", '<{}|View on Tunga>'.format(report_url) ) slack_text_suffix = '' if not is_client_report: slack_text_suffix += '*Status:* {}\n*Percentage completed:* {}{}'.format( instance.get_status_display(), instance.percentage, '%') if not to_client: if instance.last_deadline_met is not None: slack_text_suffix += '\n*Was the last deadline met?:* {}'.format( instance.last_deadline_met and 'Yes' or 'No' ) if instance.next_deadline: slack_text_suffix += '\n*Next deadline:* {}'.format(instance.next_deadline.strftime("%d %b, %Y")) if is_client_report: if instance.deliverable_satisfaction is not None: slack_text_suffix += '\n*Are you satisfied with the deliverables?:* {}'.format( instance.deliverable_satisfaction and 'Yes' or 'No' ) if is_dev_report: if instance.stuck_reason: slack_text_suffix += '\n*Reason for being stuck:*\n {}'.format( convert_to_text(instance.get_stuck_reason_display()) ) attachments = [ { slack_utils.KEY_TITLE: instance.event.task.summary, slack_utils.KEY_TITLE_LINK: report_url, slack_utils.KEY_TEXT: slack_text_suffix, slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_BLUE } ] if not to_client: if instance.deadline_miss_communicated is not None: attachments.append({ slack_utils.KEY_TITLE: '{} promptly about not making the deadline?'.format( is_client_report and 'Did the project manager/ developer(s) inform you' or 'Did you inform the client'), slack_utils.KEY_TEXT: '{}'.format(instance.deadline_miss_communicated and 'Yes' or 'No'), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) if instance.deadline_report: attachments.append({ slack_utils.KEY_TITLE: 'Report about the last deadline:', slack_utils.KEY_TEXT: convert_to_text(instance.deadline_report), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) if is_client_report: if instance.rate_deliverables: attachments.append({ slack_utils.KEY_TITLE: 'How would you rate the deliverables on a scale from 1 to 5?', slack_utils.KEY_TEXT: '{}/5'.format(instance.rate_deliverables), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_BLUE }) if instance.pm_communication: attachments.append({ slack_utils.KEY_TITLE: 'Is the communication between you and the project manager/developer(s) going well?', slack_utils.KEY_TEXT: '{}'.format(instance.pm_communication and 'Yes' or 'No'), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) else: # Status if instance.stuck_details: attachments.append({ slack_utils.KEY_TITLE: 'Explain Further why you are stuck/what should be done:', slack_utils.KEY_TEXT: convert_to_text(instance.stuck_details), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) if instance.started_at and not to_client: attachments.append({ slack_utils.KEY_TITLE: 'When did you start this sprint/task/project?', slack_utils.KEY_TEXT: instance.started_at.strftime("%d %b, %Y"), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_BLUE }) # Last if instance.accomplished: attachments.append({ slack_utils.KEY_TITLE: 'What has been accomplished since last update?', slack_utils.KEY_TEXT: convert_to_text(instance.accomplished), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) if instance.rate_deliverables and not to_client: attachments.append({ slack_utils.KEY_TITLE: 'Rate Deliverables:', slack_utils.KEY_TEXT: '{}/5'.format(instance.rate_deliverables), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) # Current if instance.todo: attachments.append({ slack_utils.KEY_TITLE: is_dev_report and 'What do you intend to achieve/complete today?' or 'What are the next next steps?', slack_utils.KEY_TEXT: convert_to_text(instance.todo), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) if not to_client: # Next if instance.next_deadline: attachments.append({ slack_utils.KEY_TITLE: 'When is the next deadline?', slack_utils.KEY_TEXT: instance.next_deadline.strftime("%d %b, %Y"), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) # Keep information about failures to meet deadlines internal if instance.next_deadline_meet is not None: attachments.append({ slack_utils.KEY_TITLE: 'Do you anticipate to meet this deadline?', slack_utils.KEY_TEXT: '{}'.format(instance.next_deadline_meet and 'Yes' or 'No'), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) if instance.next_deadline_fail_reason: attachments.append({ slack_utils.KEY_TITLE: 'Why will you not be able to make the next deadline?', slack_utils.KEY_TEXT: convert_to_text(instance.next_deadline_fail_reason), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) if instance.obstacles: attachments.append({ slack_utils.KEY_TITLE: 'What obstacles are impeding your progress?', slack_utils.KEY_TEXT: convert_to_text(instance.obstacles), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) if instance.obstacles_prevention: attachments.append({ slack_utils.KEY_TITLE: 'What could have been done to prevent this from happening?', slack_utils.KEY_TEXT: convert_to_text(instance.obstacles_prevention), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) if is_pm_report: if instance.team_appraisal: attachments.append({ slack_utils.KEY_TITLE: 'Team appraisal:', slack_utils.KEY_TEXT: convert_to_text(instance.team_appraisal), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_NEUTRAL }) if instance.remarks: attachments.append({ slack_utils.KEY_TITLE: 'Other remarks or questions', slack_utils.KEY_TEXT: convert_to_text(instance.remarks), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_NEUTRAL }) return slack_msg, attachments
def text_body(self): return convert_to_text(self.body)
def handle(self, *args, **options): """ Fix payment rates based on task status """ # command to run: python manage.py tunga_refactor_html_fields_to_text # Fix profiles profiles = UserProfile.objects.filter(Q(bio__isnull=False) & ~Q(bio='')) for item in profiles: item.bio = convert_to_text(item.bio) item.save() print('profiles', len(profiles)) # Fix messages messages = Message.objects.filter(Q(body__isnull=False) & ~Q(body='')) for item in messages: item.body = convert_to_text(item.body) item.save() print('messages', len(messages)) # Fix comments comments = Comment.objects.filter(Q(body__isnull=False) & ~Q(body='')) for item in comments: item.body = convert_to_text(item.body) item.save() print('comments', len(comments)) # Fix tasks tasks = Task.objects.all() for item in tasks: item.description = convert_to_text(item.description) item.remarks = convert_to_text(item.remarks) item.stack_description = convert_to_text(item.stack_description) item.deliverables = convert_to_text(item.deliverables) item.save() print('tasks', len(tasks)) # Fix applications applications = Application.objects.all() for item in applications: item.pitch = convert_to_text(item.pitch) item.remarks = convert_to_text(item.remarks) item.save() print('applications', len(applications)) # Fix progress events progress_events = ProgressEvent.objects.all() for item in progress_events: item.description = convert_to_text(item.description) item.save() print('progress events', len(progress_events)) # Fix progress events progress_reports = ProgressReport.objects.all() for item in progress_reports: item.accomplished = convert_to_text(item.accomplished) item.todo = convert_to_text(item.todo) item.obstacles = convert_to_text(item.obstacles) item.remarks = convert_to_text(item.remarks) item.save() print('progress reports', len(progress_reports)) # Fix work work = Work.objects.all() for item in work: item.details = convert_to_text(item.details) item.save() print('work', len(work)) # Fix education education = Education.objects.all() for item in education: item.details = convert_to_text(item.details) item.save() print('education', len(education))
def notify_new_progress_report_slack(instance): instance = clean_instance(instance, ProgressReport) if not slack_utils.is_task_notification_enabled(instance.event.task, slugs.EVENT_PROGRESS): return report_url = '%s/work/%s/event/%s/' % (TUNGA_URL, instance.event.task_id, instance.event_id) slack_msg = "%s submitted a Progress Report | %s" % ( instance.user.display_name, '<{}|View details on Tunga>'.format(report_url)) attachments = [{ slack_utils.KEY_TITLE: instance.event.task.summary, slack_utils.KEY_TITLE_LINK: report_url, slack_utils.KEY_TEXT: '*Status:* %s' '\n*Percentage completed:* %s%s' % (instance.get_status_display(), instance.percentage, '%'), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_BLUE }] if instance.accomplished: attachments.append({ slack_utils.KEY_TITLE: 'What has been accomplished since last update?', slack_utils.KEY_TEXT: convert_to_text(instance.accomplished), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_GREEN }) if instance.next_steps: attachments.append({ slack_utils.KEY_TITLE: 'What are the next next steps?', slack_utils.KEY_TEXT: convert_to_text(instance.next_steps), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_BLUE }) if instance.obstacles: attachments.append({ slack_utils.KEY_TITLE: 'What obstacles are impeding your progress?', slack_utils.KEY_TEXT: convert_to_text(instance.obstacles), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_RED }) if instance.remarks: attachments.append({ slack_utils.KEY_TITLE: 'Other remarks or questions', slack_utils.KEY_TEXT: convert_to_text(instance.remarks), slack_utils.KEY_MRKDWN_IN: [slack_utils.KEY_TEXT], slack_utils.KEY_COLOR: SLACK_ATTACHMENT_COLOR_NEUTRAL }) slack_utils.send_integration_message(instance.event.task, message=slack_msg, attachments=attachments)