A webapp/form for people to join pEp coop. Fork of Cultural Commons Collecting Society (C3S) SCE
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

invite_members.py 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # -*- coding: utf-8 -*-
  2. """
  3. This module has functionality to invite members to C3S events like the General
  4. Assembly and BarCamp.
  5. - Email templates (en/de)
  6. - Check and send email (view)
  7. - Batch invite n members (view)
  8. The first use was for the C3S HQ inauguration party in February 2014.
  9. It was then reused for:
  10. - BarCamp and General Assembly 2014
  11. - BarCamp and General Assembly 2015
  12. - BarCamp and General Assembly 2016
  13. - BarCamp and General Assembly 2017
  14. - BarCamp and General Assembly 2018
  15. How it works
  16. ------------
  17. We send an email to the members from our membership database -- this app. The
  18. templates for those emails (english/german depending on members locale) can be
  19. prepared here.
  20. For convenience, staff can invite n members at the same time.
  21. Combination with c3sPartyTicketing
  22. ----------------------------------
  23. Invitation emails are usually prepped with links to the C3S ticketing system
  24. (*c3sPartyTicketing*). That other webapp can be configured to fetch information
  25. about the relevant C3S member from this app via API call, see the relevant
  26. module.
  27. """
  28. from datetime import datetime
  29. import logging
  30. from types import NoneType
  31. from pyramid.httpexceptions import HTTPFound
  32. from pyramid.view import view_config
  33. from pyramid_mailer.message import Message
  34. from c3smembership.invite_members_texts import make_bcga18_invitation_email
  35. from c3smembership.mail_utils import send_message
  36. from c3smembership.membership_certificate import make_random_token
  37. from c3smembership.models import C3sMember
  38. from c3smembership.presentation.views.membership_listing import (
  39. get_memberhip_listing_redirect
  40. )
  41. DEBUG = False
  42. LOG = logging.getLogger(__name__)
  43. URL_PATTERN = '{ticketing_url}/lu/{token}/{email}'
  44. @view_config(permission='manage',
  45. route_name='invite_member')
  46. def invite_member_bcgv(request):
  47. """
  48. Send email to member with link to ticketing.
  49. === ====================================
  50. URL http://app:port/invite_member/{m_id}
  51. === ====================================
  52. """
  53. member_id = request.matchdict['m_id']
  54. member = C3sMember.get_by_id(member_id)
  55. if isinstance(member, NoneType):
  56. request.session.flash(
  57. 'id not found. no mail sent.',
  58. 'messages')
  59. return get_memberhip_listing_redirect(request)
  60. if not member.is_member():
  61. request.session.flash(
  62. 'Invitations can only be sent to members.',
  63. 'messages')
  64. return get_memberhip_listing_redirect(request, member_id)
  65. # prepare a random token iff none is set
  66. if member.email_invite_token_bcgv18 is None:
  67. member.email_invite_token_bcgv18 = make_random_token()
  68. url = URL_PATTERN.format(
  69. ticketing_url=request.registry.settings['ticketing.url'],
  70. token=member.email_invite_token_bcgv18,
  71. email=member.email)
  72. LOG.info("mailing event invitation to to member id %s", member.id)
  73. email_subject, email_body = make_bcga18_invitation_email(member, url)
  74. message = Message(
  75. subject=email_subject,
  76. sender='yes@c3s.cc',
  77. recipients=[member.email],
  78. body=email_body,
  79. extra_headers={
  80. 'Reply-To': 'office@c3s.cc',
  81. }
  82. )
  83. send_message(request, message)
  84. # member._token = _looong_token
  85. member.email_invite_flag_bcgv18 = True
  86. member.email_invite_date_bcgv18 = datetime.now()
  87. return get_memberhip_listing_redirect(request, member.id)
  88. @view_config(
  89. route_name="invite_batch",
  90. permission='manage')
  91. def batch_invite(request):
  92. """
  93. Batch invite n members at the same time.
  94. The number (n) is configurable, defaults to 5.
  95. The number can either be supplied in the URL
  96. or by posting a form with 'number' and 'submit to this view.
  97. === =====================================
  98. URL http://app:port/invite_batch/{number}
  99. === =====================================
  100. """
  101. try: # how many to process?
  102. batch_count = int(request.matchdict['number'])
  103. except (ValueError, KeyError):
  104. batch_count = 5
  105. if 'submit' in request.POST:
  106. try:
  107. batch_count = int(request.POST['number'])
  108. except ValueError:
  109. batch_count = 5
  110. invitees = C3sMember.get_invitees(batch_count)
  111. if len(invitees) == 0:
  112. request.session.flash('no invitees left. all done!',
  113. 'message_to_staff')
  114. return HTTPFound(request.route_url('toolbox'))
  115. num_sent = 0
  116. ids_sent = []
  117. for member in invitees:
  118. # prepare a random token iff none is set
  119. if member.email_invite_token_bcgv18 is None:
  120. member.email_invite_token_bcgv18 = make_random_token()
  121. url = URL_PATTERN.format(
  122. ticketing_url=request.registry.settings['ticketing.url'],
  123. token=member.email_invite_token_bcgv18,
  124. email=member.email)
  125. LOG.info("mailing event invitation to to member id %s", member.id)
  126. email_subject, email_body = make_bcga18_invitation_email(member, url)
  127. message = Message(
  128. subject=email_subject,
  129. sender='yes@c3s.cc',
  130. recipients=[member.email],
  131. body=email_body,
  132. extra_headers={
  133. 'Reply-To': 'office@c3s.cc',
  134. }
  135. )
  136. send_message(request, message)
  137. member.email_invite_flag_bcgv18 = True
  138. member.email_invite_date_bcgv18 = datetime.now()
  139. num_sent += 1
  140. ids_sent.append(member.id)
  141. request.session.flash(
  142. "sent out {} mails (to members with ids {})".format(
  143. num_sent, ids_sent),
  144. 'message_to_staff')
  145. return HTTPFound(request.route_url('toolbox'))