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.

324 lines
15 KiB

4 years ago
  1. from datetime import date, timedelta
  2. import sys
  3. from django.core.management.base import BaseCommand, CommandError
  4. from django.template.loader import get_template
  5. from django.core.mail import send_mail, BadHeaderError, EmailMessage
  6. from django.core.mail import EmailMultiAlternatives
  7. from django.conf import settings
  8. from input.models import Project, Library, HonoraryCertificate, Travel, Email,\
  9. BusinessCard, List, IFG, Literature
  10. from input.settings import IF_EMAIL, SURVEYPREFIX, SURVEY_EMAIL
  11. class Command(BaseCommand):
  12. ''' mails will be send here:
  13. - two weeks after confirmation of support for volunteer (/extern) send link
  14. with surveylink
  15. - same for HonoraryCertificate (/intern)
  16. - travel: mail 3 weeks after end of project.
  17. - assumed end of project (/project) reached: mail to IF, link to project-editpage
  18. - 4 weeks after end of project reached: mail with surveylink
  19. '''
  20. help = '''This command sends mail with some links to the database or to the survey
  21. after some amount of time.'''
  22. def survey_link(self, email, type, pid, name, realname):
  23. context = {'realname': realname,
  24. 'type': type,
  25. 'name': name,
  26. 'pid': pid,
  27. 'SURVEYPREFIX': SURVEYPREFIX, }
  28. txt_mail_template = get_template('input/survey_mail.txt')
  29. html_mail_template = get_template('input/survey_mail.html')
  30. try:
  31. subject, from_email, to = 'Dein Feedback zur Förderung durch Wikimedia Deutschland', IF_EMAIL, email
  32. text_content = txt_mail_template.render(context)
  33. html_content = html_mail_template.render(context)
  34. msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[SURVEY_EMAIL])
  35. msg.attach_alternative(html_content, "text/html")
  36. msg.send()
  37. #print('survey mail would have been send')
  38. #survey_mail = EmailMessage('Dein Feedback zur Förderung durch Wikimedia Deutschland',
  39. # mail_template.render(context),
  40. # IF_EMAIL,
  41. # [email],
  42. # bcc=[SURVEY_EMAIL])
  43. #survey_mail.send(fail_silently=False)
  44. except BadHeaderError:
  45. return HttpResponse('Invalid header found.')
  46. print(f'send surveylinkemail to {email}...')
  47. ''' the db entry mail_state was added. Useful when migrating databases. first delete the entry, then makemigrations
  48. then migrate.. after that, recreate the entry with default END, after that makemigrations and migrate.
  49. now all entries have the value END. after that rewrite the default to NONE in models.py, then makemigrations
  50. and migrate again, to have NONE as default for all new queries. '''
  51. def end_of_projects_reached(self):
  52. ''' end of project reached '''
  53. # get all projects which ended
  54. old = Project.objects.filter(end__lt = date.today())\
  55. .exclude(end_mail_send = False)\
  56. .filter(mail_state = 'NONE')
  57. txt_mail_template = get_template('input/if_end_of_project.txt')
  58. html_mail_template = get_template('input/if_end_of_project.html')
  59. for project in old:
  60. context = {'project': project}
  61. context['URLPREFIX'] = settings.URLPREFIX
  62. try:
  63. subject, from_email, to = 'Projektende erreicht', IF_EMAIL, IF_EMAIL
  64. text_content = txt_mail_template.render(context)
  65. html_content = html_mail_template.render(context)
  66. msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
  67. msg.attach_alternative(html_content, "text/html")
  68. msg.send()
  69. #print('end of project mail would have been sent')
  70. #send_mail('Projektende erreicht',
  71. # mail_template.render(context),
  72. # IF_EMAIL,
  73. # [IF_EMAIL],
  74. # fail_silently=False)
  75. project.end_mail_send = False
  76. project.mail_state = 'INF'
  77. try:
  78. project.save()
  79. except:
  80. print( 'For project', project, 'there is possibly no project.start (', project.start, ') class')
  81. except BadHeaderError:
  82. self.stdout.write(self.style.ERROR('Invalid header found.'))
  83. self.stdout.write(self.style.SUCCESS('end_of_projects_reached() executed.'))
  84. def end_of_projects_approved(self):
  85. ''' end of project approved '''
  86. # get all projects where end was reached already, and send mails for the ones already set to status "ended" by the admins
  87. approved_end = Project.objects.filter(status = 'END')\
  88. .exclude(end_mail_send = True)\
  89. .filter(mail_state = 'INF')
  90. txt_mail_template = get_template('input/if_end_of_project_approved.txt')
  91. html_mail_template = get_template('input/if_end_of_project_approved.html')
  92. txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt')
  93. html_informMail_template = get_template('input/if_end_of_project_orginformed.html')
  94. # send the mail to project.email, which would be the mail of the volunteer filling out the form
  95. for project in approved_end:
  96. context = {'project': project}
  97. context['URLPREFIX'] = settings.URLPREFIX
  98. try:
  99. subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email
  100. text_content = txt_mail_template.render(context)
  101. html_content = html_mail_template.render(context)
  102. msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
  103. msg.attach_alternative(html_content, "text/html")
  104. msg.send()
  105. #print('if and of project approved mail would have been sent')
  106. inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL
  107. inform_text_content = txt_informMail_template.render(context)
  108. inform_html_content = html_informMail_template.render(context)
  109. inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to])
  110. inform_msg.attach_alternative(html_content, "text/html")
  111. inform_msg.send()
  112. #print('if end of project orginformed mail would have been sent')
  113. #send_mail('Projektende erreicht',
  114. # mail_template.render(context),
  115. # IF_EMAIL,
  116. # [project.email],
  117. # fail_silently=False)
  118. #send_mail('Projektorganisator*in wurde informiert',
  119. # informMail_template.render(context),
  120. # IF_EMAIL,
  121. # [IF_EMAIL],
  122. # fail_silently=False)
  123. project.mail_state = 'END'
  124. try:
  125. project.save()
  126. except:
  127. print( 'For project', project, 'there is possibly no project.start (', project.start, ') class')
  128. except BadHeaderError:
  129. self.stdout.write(self.style.ERROR('Invalid header found.'))
  130. self.stdout.write(self.style.SUCCESS('end_of_projects_approved() executed.'))
  131. def notHappened_of_projects_approved(self):
  132. ''' notHappened of project approved '''
  133. # get all projects where end was reached already, and send mails for the ones where status was put to NOT by admins
  134. approved_notHappened = Project.objects.filter(status = 'NOT')\
  135. .exclude(end_mail_send = True)\
  136. .filter(mail_state = 'INF')
  137. html_mail_template = get_template('input/if_not_of_project_approved.html')
  138. txt_mail_template = get_template('input/if_not_of_project_approved.txt')
  139. txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt')
  140. html_informMail_template = get_template('input/if_end_of_project_orginformed.html')
  141. # send the mail to project.email, which would be the mail of the volunteer that filled out the form
  142. for project in approved_notHappened:
  143. context = {'project': project}
  144. context['URLPREFIX'] = settings.URLPREFIX
  145. try:
  146. subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email
  147. text_content = txt_mail_template.render(context)
  148. html_content = html_mail_template.render(context)
  149. msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
  150. msg.attach_alternative(html_content, "text/html")
  151. msg.send()
  152. #print('if not of project approved end mail would have been sent')
  153. #send_mail('Projektende erreicht',
  154. # mail_template.render(context),
  155. # IF_EMAIL,
  156. # [project.email],
  157. # fail_silently=False)
  158. inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL
  159. inform_text_content = txt_informMail_template.render(context)
  160. inform_html_content = html_informMail_template.render(context)
  161. inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to])
  162. inform_msg.attach_alternative(html_content, "text/html")
  163. inform_msg.send()
  164. #print('if not of project approved end mail orginformed would have been sent')
  165. #send_mail('Projektorganisator*in wurde informiert',
  166. # informMail_template.render(context),
  167. # IF_EMAIL,
  168. # [IF_EMAIL],
  169. # fail_silently=False)
  170. project.mail_state = 'END'
  171. project.save()
  172. except BadHeaderError:
  173. self.stdout.write(self.style.ERROR('Invalid header found.'))
  174. self.stdout.write(self.style.SUCCESS('notHappened_of_projects_approved() executed.'))
  175. def surveymails_to_object(self, supported, name='', type='LIB'):
  176. mytype=type
  177. myname = name
  178. for item in supported:
  179. if type == 'LIB':
  180. mytype = item.type
  181. elif type not in ('MAIL','VIS','LIST'):
  182. myname = getattr(item, name, 'ERROR: NONAME')
  183. print(f'name gefunden: {myname}')
  184. self.survey_link(email=item.email,
  185. type=mytype,
  186. pid=f'{mytype}{item.pk}',
  187. name=myname,
  188. realname=item.realname)
  189. item.survey_mail_send = True
  190. item.survey_mail_date = date.today()
  191. item.save()
  192. self.stdout.write(self.style.SUCCESS(f'surveymails for object type {type} sent'))
  193. ''' TODO: there could be some more removing of duplicated code in the following functions '''
  194. def surveymails_to_lib(self):
  195. '''get all library objects which where granted two weeks ago'''
  196. supported = Library.objects.filter(granted=True)\
  197. .filter(granted_date__lt = date.today() - timedelta(days=14))\
  198. .exclude(survey_mail_send=True)\
  199. .exclude(mail_state = 'END')
  200. self.surveymails_to_object(supported,name='library')
  201. def surveymails_to_hon(self):
  202. '''get all HonoraryCertificate objects which where granted two weeks ago'''
  203. supported = HonoraryCertificate.objects.filter(granted=True)\
  204. .filter(granted_date__lt = date.today() - timedelta(days=14))\
  205. .exclude(survey_mail_send=True)\
  206. .exclude(mail_state = 'END')
  207. self.surveymails_to_object(supported, type='HON', name='project')
  208. def surveymails_to_ifg(self):
  209. '''get all IFG objects which where granted two weeks ago'''
  210. supported = IFG.objects.filter(granted=True)\
  211. .filter(granted_date__lt = date.today() - timedelta(days=14))\
  212. .exclude(survey_mail_send=True)\
  213. .exclude(mail_state = 'END')
  214. self.surveymails_to_object(supported, type='IFG', name='url')
  215. def surveymails_to_lit(self):
  216. '''get all Litearure objects which where granted two weeks ago'''
  217. supported = Literature.objects.filter(granted=True)\
  218. .filter(granted_date__lt = date.today() - timedelta(days=14))\
  219. .exclude(survey_mail_send=True)\
  220. .exclude(mail_state = 'END')
  221. self.surveymails_to_object(supported, type='LIT', name='info')
  222. def surveymails_to_project(self):
  223. '''send survey link 4 weeks after end of project reached'''
  224. supported = Project.objects.filter(granted=True)\
  225. .filter(end__lt = date.today() - timedelta(days=28))\
  226. .exclude(survey_mail_send=True)\
  227. .exclude(mail_state = 'END')
  228. self.surveymails_to_object(supported, type='PRO', name='name')
  229. def surveymails_to_travel(self):
  230. '''send survey link 3 weeks after end of project reached'''
  231. supported = Travel.objects.filter(project__granted=True)\
  232. .filter(project__end__lt = date.today() - timedelta(days=21))\
  233. .exclude(survey_mail_send=True)\
  234. .exclude(mail_state = 'END')
  235. self.surveymails_to_object(supported, type='TRAV', name='project')
  236. def surveymails_to_mail_vis_lis(self):
  237. '''send survey link 2 weeks after mailadresss, mailinglist or businesscards are granted'''
  238. lastdate = date.today() - timedelta(days=14)
  239. typefield = ('MAIL','VIS','LIST')
  240. count = 0
  241. for c in ('Email', 'BusinessCard', 'List'):
  242. # get class via string
  243. supported = getattr(sys.modules[__name__], c).objects.filter(granted=True)\
  244. .filter(granted_date__lt = lastdate)\
  245. .exclude(survey_mail_send=True)\
  246. .exclude(mail_state = 'END')
  247. self.surveymails_to_object(supported, type=typefield[count])
  248. count += 1
  249. def handle(self, *args, **options):
  250. '''the main function which is called by the custom command'''
  251. self.end_of_projects_reached()
  252. self.end_of_projects_approved()
  253. self.notHappened_of_projects_approved()
  254. self.surveymails_to_lib()
  255. self.surveymails_to_hon()
  256. self.surveymails_to_ifg()
  257. self.surveymails_to_lit()
  258. self.surveymails_to_project()
  259. self.surveymails_to_travel()
  260. self.surveymails_to_mail_vis_lis()
  261. self.stdout.write(self.style.SUCCESS('sendmails custom command executed'))