teams.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. # Copyright 2013 The Distro Tracker Developers
  2. # See the COPYRIGHT file at the top-level directory of this distribution and
  3. # at http://deb.li/DTAuthors
  4. #
  5. # This file is part of Distro Tracker. It is subject to the license terms
  6. # in the LICENSE file found in the top-level directory of this
  7. # distribution and at http://deb.li/DTLicense. No part of Distro Tracker,
  8. # including this file, may be copied, modified, propagated, or distributed
  9. # except according to the terms contained in the LICENSE file.
  10. """
  11. Implements all commands which deal with teams.
  12. """
  13. from __future__ import unicode_literals
  14. from distro_tracker.mail.control.commands.base import Command
  15. from distro_tracker.mail.control.commands.confirmation import needs_confirmation
  16. from distro_tracker.core.models import Team
  17. from distro_tracker.core.models import UserEmail
  18. from distro_tracker.core.utils import get_or_none
  19. @needs_confirmation
  20. class JoinTeam(Command):
  21. """
  22. Command which lets users join an existing public team.
  23. """
  24. META = {
  25. 'description': """join-team <team-slug> [<email>]
  26. Adds <email> to team with the slug given by <team-slug>. If
  27. <email> is not given, it adds the From address email to the team.
  28. If the team is not public or it does not exist, a warning is
  29. returned.""",
  30. 'name': 'join-team',
  31. }
  32. REGEX_LIST = (
  33. r'\s+(?P<team_slug>\S+)(?:\s+(?P<email>\S+))?$',
  34. )
  35. def __init__(self, team_slug, email):
  36. super(JoinTeam, self).__init__()
  37. self.user_email = email
  38. self.team_slug = team_slug
  39. def get_team_and_user(self):
  40. team = get_or_none(Team, slug=self.team_slug)
  41. if not team:
  42. self.error('Team with the slug "{}" does not exist.'.format(
  43. self.team_slug))
  44. return
  45. if not team.public:
  46. self.error(
  47. "The given team is not public. "
  48. "Please contact {} if you wish to join".format(
  49. team.owner.main_email))
  50. return
  51. user_email, _ = UserEmail.objects.get_or_create(email=self.user_email)
  52. if user_email in team.members.all():
  53. self.warn("You are already a member of the team.")
  54. return
  55. return team, user_email
  56. def pre_confirm(self):
  57. packed = self.get_team_and_user()
  58. if packed is None:
  59. return False
  60. self.reply('A confirmation mail has been sent to ' + self.user_email)
  61. return True
  62. def get_command_text(self):
  63. return super(JoinTeam, self).get_command_text(
  64. self.team_slug, self.user_email)
  65. def handle(self):
  66. packed = self.get_team_and_user()
  67. if packed is None:
  68. return
  69. team, user_email = packed
  70. team.add_members([user_email])
  71. self.reply('You have successfully joined the team "{}"'.format(team))
  72. @needs_confirmation
  73. class LeaveTeam(Command):
  74. """
  75. Command which lets users leave a team they are already a member of.
  76. """
  77. META = {
  78. 'description': """leave-team <team-slug> [<email>]
  79. Removes <email> from the team with the slug given by <team-slug>. If
  80. <email> is not given, it uses the From address email.
  81. If the user is not a member of the team, a warning is returned.""",
  82. 'name': 'leave-team',
  83. }
  84. REGEX_LIST = (
  85. r'\s+(?P<team_slug>\S+)(?:\s+(?P<email>\S+))?$',
  86. )
  87. def __init__(self, team_slug, email):
  88. super(LeaveTeam, self).__init__()
  89. self.user_email = email
  90. self.team_slug = team_slug
  91. def get_team_and_user(self):
  92. team = get_or_none(Team, slug=self.team_slug)
  93. if not team:
  94. self.error('Team with the slug "{}" does not exist.'.format(
  95. self.team_slug))
  96. return
  97. user_email, _ = UserEmail.objects.get_or_create(email=self.user_email)
  98. if user_email not in team.members.all():
  99. self.warn("You are not a member of the team.")
  100. return
  101. return team, user_email
  102. def pre_confirm(self):
  103. packed = self.get_team_and_user()
  104. if packed is None:
  105. return False
  106. self.reply('A confirmation mail has been sent to ' + self.user_email)
  107. return True
  108. def get_command_text(self):
  109. return super(LeaveTeam, self).get_command_text(
  110. self.team_slug, self.user_email)
  111. def handle(self):
  112. packed = self.get_team_and_user()
  113. if packed is None:
  114. return
  115. team, user_email = packed
  116. team.remove_members([user_email])
  117. self.reply('You have successfully left the team "{}" (slug: {})'.format(
  118. team, team.slug))
  119. class ListTeamPackages(Command):
  120. """
  121. Lists all the packages of a particular team, provided that the team is
  122. public or the email doing the query is a member of the team.
  123. """
  124. META = {
  125. 'description': """list-team-packages <team-slug>
  126. Lists all packages of the team with the slug given by <team-slug>.
  127. If the team is private, the packages are returned only if the From email
  128. is a member of the team.""",
  129. 'name': 'list-team-packages',
  130. }
  131. REGEX_LIST = (
  132. r'\s+(?P<team_slug>\S+)$',
  133. )
  134. def __init__(self, team_slug):
  135. super(ListTeamPackages, self).__init__()
  136. self.team_slug = team_slug
  137. @property
  138. def user_email(self):
  139. return self.context['email']
  140. def get_team(self):
  141. team = get_or_none(Team, slug=self.team_slug)
  142. if not team:
  143. self.error('Team with the slug "{}" does not exist.'.format(
  144. self.team_slug))
  145. return
  146. return team
  147. def get_user_email(self):
  148. user_email, _ = UserEmail.objects.get_or_create(email=self.user_email)
  149. return user_email
  150. def get_command_text(self):
  151. return super(ListTeamPackages, self).get_command_text(
  152. self.team_slug)
  153. def handle(self):
  154. team = self.get_team()
  155. if not team:
  156. return
  157. if not team.public:
  158. user_email = self.get_user_email()
  159. if user_email not in team.members.all():
  160. self.error(
  161. "The team is private. "
  162. "Only team members can see its packages.")
  163. return
  164. self.reply("Packages found in team {}:".format(team))
  165. self.list_reply(package for package in
  166. team.packages.all().order_by('name'))
  167. class WhichTeams(Command):
  168. """
  169. Returns a list of teams that the given email is a member of.
  170. """
  171. META = {
  172. 'description': """which-teams [<email>]
  173. Lists all teams that <email> is a member of. If <email> is not given, the
  174. sender's email is used.""",
  175. 'name': 'which-teams',
  176. }
  177. REGEX_LIST = (
  178. r'(?:\s+(?P<email>\S+))?$',
  179. )
  180. def __init__(self, email):
  181. super(WhichTeams, self).__init__()
  182. self.user_email = email
  183. def get_user_email(self):
  184. user_email, _ = UserEmail.objects.get_or_create(email=self.user_email)
  185. return user_email
  186. def handle(self):
  187. user_email = self.get_user_email()
  188. if user_email.teams.count() == 0:
  189. self.warn("{} is not a member of any team.".format(self.user_email))
  190. else:
  191. self.reply("Teams that {} is a member of:".format(self.user_email))
  192. self.list_reply(
  193. team.slug
  194. for team in user_email.teams.all().order_by('name'))