def form_valid(self, form): self._users_accepted = [] self._users_declined = [] self._users_waitlisted = [] for application_form in form: application_before = CosinnusConferenceApplication.objects.get( id=application_form.instance.id) application_form.save() if application_before.status != application_form.instance.status: self._handle_application_changed_for_status( application_form.instance) self._set_workshop_assignments() if len(self._users_accepted) > 0: messages.success( self.request, _('The following users were accepted and added as members: %s') % ', '.join(full_name(user) for user in self._users_accepted)) if len(self._users_waitlisted) > 0: messages.success( self.request, _('The following users were put on the wait list: %s') % ', '.join(full_name(user) for user in self._users_waitlisted)) if len(self._users_declined) > 0: messages.success( self.request, _('The following users were declined: %s') % ', '.join(full_name(user) for user in self._users_declined)) messages.success(self.request, _('Your changes were saved.')) return HttpResponseRedirect(self.get_success_url())
def userprofile_created_sub(sender, profile, **kwargs): user = profile.user logger.debug("Userprofile created, adding user [%s] to nextcloud ", full_name(user)) submit_with_retry( nextcloud.create_user, f"wechange-{user.id}", full_name(user), user.email, [f"wechange-{group.name}" for group in CosinnusGroup.objects.get_for_user(user)] )
def __init__(self, obj=None, is_emphasized=False, user=None): if obj: from cosinnus.templatetags.cosinnus_tags import full_name if is_emphasized: self['is_emphasized'] = is_emphasized # smart conversion by known models if type(obj) is get_cosinnus_group_model() or issubclass(obj.__class__, get_cosinnus_group_model()): self['icon'] = obj.get_icon() self['text'] = escape(obj.name) self['url'] = obj.get_absolute_url() elif type(obj) is CosinnusIdea: self['icon'] = obj.get_icon() self['text'] = escape(obj.title) self['url'] = obj.get_absolute_url() elif type(obj) is CosinnusOrganization: self['icon'] = 'fa-building' self['text'] = escape(obj.name) self['url'] = obj.get_absolute_url() elif isinstance(obj, NextcloudFileProxy): self['icon'] = 'fa-cloud' self['text'] = obj.name self['url'] = obj.url self['subtext'] = obj.excerpt elif obj._meta.model.__name__ == 'Message' and not settings.COSINNUS_ROCKET_ENABLED and not 'cosinnus_message' in settings.COSINNUS_DISABLED_COSINNUS_APPS: self['icon'] = 'fa-envelope' self['text'] = escape(obj.subject) self['url'] = reverse('postman:view_conversation', kwargs={'thread_id': obj.thread_id}) if obj.thread_id else obj.get_absolute_url() self['subtext'] = escape(', '.join([full_name(participant) for participant in obj.other_participants(user)])) elif issubclass(obj.__class__, BaseUserProfile): self['icon'] = obj.get_icon() self['text'] = escape(full_name(obj.user)) self['url'] = obj.get_absolute_url() elif BaseTaggableObjectModel in inspect.getmro(obj.__class__): self['icon'] = 'fa-question' self['text'] = escape(obj.get_readable_title()) self['url'] = obj.get_absolute_url() self['subtext'] = escape(obj.group.name) if hasattr(obj, 'get_icon'): self['icon'] = obj.get_icon() if obj.group.slug in get_default_user_group_slugs(): self['group'] = escape(CosinnusPortal.get_current().name) else: self['group'] = escape(obj.group.name) self['group_icon'] = obj.group.get_icon() if obj.__class__.__name__ == 'Event': if obj.state != 2: self['subtext'] = {'is_date': True, 'date': django_date_filter(obj.from_date, 'Y-m-d')}
def __init__(self, alert, action_user=None, action_user_profile=None): from cosinnus.templatetags.cosinnus_tags import full_name if not action_user: logger.warn( '>>>>>>>> No action_user supplied for `SerializedNotificationAlert`, retrieving with singular query!' ) action_user = alert.action_user if not action_user_profile: logger.warn( '>>>>>>>> No action_user_profile supplied for `SerializedNotificationAlert`, retrieving with singular query!' ) action_user_profile = action_user.cosinnus_profile # translate the label using current variables string_variables = { 'sender_name': "<b>%s</b>" % escape(full_name(action_user)), 'team_name': "<b>%s</b>" % (escape(alert.group.name) if alert.group else '*unknowngroup*'), 'portal_name': escape(_(settings.COSINNUS_BASE_PAGE_TITLE_TRANS)), 'object_name': "<b>%s</b>" % escape(alert.target_title), 'count': alert.counter, 'count_minus_one': max(alert.counter - 1, 0), } # generate and translate the label text only now! alert.generate_label() self['text'] = alert.label % string_variables # add a period for the alert_text sentence here self['text'] += '.' self['id'] = alert.id self['url'] = alert.target_url self['item_icon_or_image_url'] = alert.icon_or_image_url # profile might be None for deleted users self['user_icon_or_image_url'] = action_user_profile.get_avatar_thumbnail_url() if \ action_user_profile else static('images/jane-doe-small.png') self['group'] = alert.subtitle self['group_icon'] = alert.subtitle_icon self['action_datetime'] = date( alert.last_event_at, 'c') # moment-compatible datetime string self['is_emphasized'] = not alert.seen self['alert_reason'] = alert.get_alert_reason() sub_items = [] if alert.type == NotificationAlert.TYPE_MULTI_USER_ALERT: sub_items = [BundleItem(obj) for obj in alert.multi_user_list] elif alert.type == NotificationAlert.TYPE_BUNDLE_ALERT: sub_items = [BundleItem(obj) for obj in alert.bundle_list] self['sub_items'] = sub_items self[ 'is_multi_user_alert'] = alert.type == NotificationAlert.TYPE_MULTI_USER_ALERT self[ 'is_bundle_alert'] = alert.type == NotificationAlert.TYPE_BUNDLE_ALERT
def get_user_select2_pills(users, text_only=False): from cosinnus.templatetags.cosinnus_tags import full_name return [( "user:" + six.text_type(user.id), render_to_string('cosinnus/common/user_select2_pill.html', { 'user': user }).replace('\n', '').replace('\r', '') if not text_only else escape( full_name(user)), ) for user in users]
def get_join_url(self, user): """ Returns the actual BBB-Server URL with tokens for a given user to join this room """ password = self.get_password_for_user(user) username = full_name(user) if self.meeting_id and password: extra_join_parameters = self.build_extra_join_parameters() return self.bbb_api.join_url(self.meeting_id, username, password, extra_parameter_dict=extra_join_parameters) return ''
def add_new_multi_action_user(self, new_action_user): """ Adds a new action_user to the multi_user_list """ from cosinnus.templatetags.cosinnus_tags import full_name profile = new_action_user.cosinnus_profile user_item = { 'user_id': new_action_user.id, 'title': full_name(new_action_user), 'url': profile.get_absolute_url(), 'icon_or_image_url': profile.get_avatar_thumbnail_url(), } self.multi_user_list = [user_item] + self.multi_user_list
def _notify_users_for_reported_objects(report_obj, request=None): template = 'cosinnus/mail/reported_object_submitted.html' subj_template = 'cosinnus/mail/reported_object_submitted_subj.txt' if request: context = get_common_mail_context(request, user=report_obj.creator) context.update(cosinnus_context(request)) else: context = {} target_obj = report_obj.target_object title = getattr(target_obj, 'title', getattr(target_obj, 'name', force_text(target_obj))) report_url = reverse('admin:cosinnus_cosinnusreportedobject_change', args=(report_obj.id, )) portal = None if issubclass(target_obj.__class__, BaseTaggableObjectModel): portal = target_obj.group.portal elif issubclass(target_obj.__class__, CosinnusGroup): portal = target_obj.portal else: portal = CosinnusPortal.get_current() portal_admins = get_user_model().objects.all().exclude( is_active=False).exclude(last_login__exact=None).filter( id__in=portal.admins) for receiver in portal_admins: context.update({ 'receiver': receiver, 'receiver_name': full_name(receiver), 'sender': report_obj.creator, 'sender_name': full_name(report_obj.creator), 'object': report_obj, 'object_name': title, 'report_admin_url': report_url, 'report_text': report_obj.text, 'object_url': report_obj.get_absolute_url(), }) subject = render_to_string(subj_template, context) send_mail_or_fail(receiver.email, subject, template, context)
def render_html_with_variables(user, html, variables=None): """ Renders any raw HTML with some request context variables """ from cosinnus.templatetags.cosinnus_tags import full_name if variables is None: variables = {} variables.update({ 'user_first_name': user.first_name, 'user_last_name': user.last_name, 'user_full_name': full_name(user), }) for variable_name, variable_value in variables.items(): html = html.replace('[[%s]]' % variable_name, str(variable_value)) return mark_safe(html)
def send_html_mail_threaded(to_user, subject, html_content): """ Sends out a pretty html to an email-address. The given `html_content` will be placed inside the notification html template, and the style will be a "from-portal" style (instead of a "from-group" style. """ from cosinnus.templatetags.cosinnus_tags import full_name template = '/cosinnus/html_mail/notification.html' portal = CosinnusPortal.get_current() domain = portal.get_domain() portal_image_url = '%s%s' % (domain, static('img/logo-icon.png')) data = { 'site': portal.site, 'site_name': portal.site.name, 'domain_url': domain, 'portal_url': domain, 'portal_image_url': portal_image_url, 'portal_name': portal.name, 'receiver': to_user, 'addressee': mark_safe(strip_tags(full_name(to_user))), 'topic': subject, 'prefs_url': None, 'notification_reason': None, 'origin_name': portal.name, 'origin_url': domain, 'origin_image_url': portal_image_url, 'notification_body': None, # this is a body text that can be used for group description or similar 'notification_item_html': mark_safe(html_content), } send_mail_or_fail_threaded(to_user.email, subject, template, data, is_html=True)
def user_left_group_receiver_sub(sender, user, group, **kwargs): """ Triggers when a user left a group """ logger.debug('User [%s] left group [%s], removing him from Nextcloud', full_name(user), group.name) submit_with_retry(nextcloud.remove_user_from_group, f"wechange-{user.id}", f"wechange-{group.name}")
def user_joined_group_receiver_sub(sender, user, group, **kwargs): """ Triggers when a user properly joined (not only requested to join) a group """ logger.debug('User [%s] joined group [%s], adding him/her to Nextcloud', full_name(user), group.name) submit_with_retry(nextcloud.add_user_to_group, f"wechange-{user.id}", f"wechange-{group.name}")
def __init__(self, obj=None, is_emphasized=False, user=None): if obj: if is_emphasized: self['is_emphasized'] = is_emphasized # smart conversion by known models if type(obj) is get_cosinnus_group_model() or issubclass( obj.__class__, get_cosinnus_group_model()): self[ 'icon'] = 'fa-sitemap' if obj.type == CosinnusGroup.TYPE_SOCIETY else 'fa-group' self['text'] = escape(obj.name) self['url'] = obj.get_absolute_url() elif type(obj) is CosinnusIdea: self['icon'] = 'fa-lightbulb-o' self['text'] = escape(obj.title) self['url'] = obj.get_absolute_url() elif obj._meta.model.__name__ == 'Message' and not settings.COSINNUS_ROCKET_ENABLED: self['icon'] = 'fa-envelope' self['text'] = escape(obj.subject) self['url'] = reverse( 'postman:view_conversation', kwargs={'thread_id': obj.thread_id }) if obj.thread_id else obj.get_absolute_url() self['subtext'] = escape(', '.join([ full_name(participant) for participant in obj.other_participants(user) ])) elif issubclass(obj.__class__, BaseUserProfile): self['icon'] = 'fa-user' self['text'] = escape(full_name(obj.user)) self['url'] = obj.get_absolute_url() elif BaseTaggableObjectModel in inspect.getmro(obj.__class__): self['icon'] = 'fa-question' self['text'] = escape(obj.title) self['url'] = obj.get_absolute_url() self['subtext'] = escape(obj.group.name) if obj.group.slug in get_default_user_group_slugs(): self['group'] = escape(CosinnusPortal.get_current().name) else: self['group'] = escape(obj.group.name) self[ 'group_icon'] = 'fa-group' if obj.group.type == CosinnusGroup.TYPE_PROJECT else 'fa-sitemap' if obj.__class__.__name__ == 'Event': if obj.state == 2: self['icon'] = 'fa-calendar-check-o' else: self['subtext'] = { 'is_date': True, 'date': django_date_filter(obj.from_date, 'Y-m-d') } self['icon'] = 'fa-calendar' if obj.__class__.__name__ == 'Etherpad': self['icon'] = 'fa-file-text' if obj.__class__.__name__ == 'Ethercalc': self['icon'] = 'fa-table' if obj.__class__.__name__ == 'FileEntry': self['icon'] = 'fa-file' if obj.__class__.__name__ == 'Message': self['icon'] = 'fa-envelope' if obj.__class__.__name__ == 'TodoEntry': self['icon'] = 'fa-tasks' if obj.__class__.__name__ == 'Poll': self['icon'] = 'fa-bar-chart' if obj.__class__.__name__ == 'Offer': self['icon'] = 'fa-exchange-alt'
def send_payment_event_payment_email(payment, event): """ Sends an email to a user for an event such ass success/errors in payments, or updates to subscriptions. Mail type depends on the given event. @param payment: Always supply a payment for this function, the subscription will be taken from its `subscription` relation. If all you have is a subscription, supply the `subscription.last_payment`. @param event: one of the values of `PAYMENT_EVENTS`. @return: True if the mail was successfully relayed, False or raises otherwise. """ cur_language = translation.get_language() try: if not payment.user: logger.warning( 'Sending payment status message was ignored because no user was attached to the payment', extra={'payment': payment.id}) return if not event in PAYMENT_EVENTS: logger.error( 'Could not send out a payment event email because the event type was unknown.', extra={'payment': payment.id}) return user = payment.user email = user.email template = 'wechange_payments/mail/mail_base.html' subject_template = 'wechange_payments/mail/subject_base.txt' portal = CosinnusPortal.get_current() # switch language to user's preference language translation.activate( getattr(user.cosinnus_profile, 'language', settings.LANGUAGES[0][0])) link_html = '[' + str(pgettext_lazy( '(URL-LABEL)', 'Link')) + '](' + portal.get_domain() + '%s)' mail_html = '[%s](mailto:%s)' # prepare all possible variables sepa_mandate = None iban = None if payment.type == PAYMENT_TYPE_DIRECT_DEBIT: reference_payment = payment.subscription.reference_payment sepa_mandate = reference_payment.extra_data.get( 'sepa_mandate_token', None) iban = reference_payment.extra_data.get('iban', None) variables = { 'payment': payment, 'link_payment_info': link_html % reverse('wechange_payments:payment-infos'), 'link_invoices': link_html % reverse('wechange_payments:invoices'), 'link_new_payment': link_html % reverse('wechange_payments:payment'), 'link_payment_issues': link_html % reverse('wechange_payments:suspended-subscription'), 'portal_name': portal.name, 'username': full_name(payment.user), 'payment_amount': str(int(payment.amount)), 'vat_amount': str(int(settings.PAYMENTS_INVOICE_PROVIDER_TAX_RATE_PERCENT)), 'subscription_amount': str(int(payment.subscription.amount)), 'next_debit_date': localize(payment.subscription.get_next_payment_date()), 'payment_method': payment.get_type_string(), 'support_email': mail_html % (portal.support_email, portal.support_email), 'sepa_mandate': sepa_mandate, 'iban': iban, 'sepa_creditor': settings.PAYMENTS_SEPA_CREDITOR_ID, } # compose email parts data = { 'mail_pre': MAIL_PRE % variables, 'mail_links': MAIL_LINKS % variables, 'mail_post': MAIL_POST % variables, 'mail_body': MAIL_BODY.get(event) % variables, 'mail_subject': MAIL_SUBJECT.get(event) % variables, } # add SEPA mandate info to mail body for successful SEPA payment email if payment.type == PAYMENT_TYPE_DIRECT_DEBIT and event == PAYMENT_EVENT_SUCCESSFUL_PAYMENT: sepa_variables = { 'payment': payment.subscription.reference_payment, 'SETTINGS': settings, } data['mail_body'] += '\n\n-\n\n' + render_to_string( 'wechange_payments/mail/sepa_mandate_partial.html', sepa_variables) # send mail if settings.PAYMENTS_USE_HOOK_INSTEAD_OF_SEND_MAIL == True: signals.success_email_sender.send( sender=payment, to_user=user, template=template, subject_template=subject_template, data=data) else: subject = render_to_string(subject_template, data) message = render_to_string(template, data) mail_func = resolve_class(settings.PAYMENTS_SEND_MAIL_FUNCTION) mail_func(subject, message, settings.DEFAULT_FROM_EMAIL, [email]) return True except Exception as e: logger.warning( 'Payments: Sending a payment status email to the user failed!', extra={ 'internal_transaction_id': payment.internal_transaction_id, 'vendor_transaction_id': payment.vendor_transaction_id, 'exception': e }) if settings.DEBUG: raise return False # switch language back to previous translation.activate(cur_language)