Skip to content

Commit 1cf7e67

Browse files
committed
Struct teams
Signed-off-by: Toomore Chiang <[email protected]>
1 parent fd3b25b commit 1cf7e67

21 files changed

+656
-359
lines changed

Dockerfile-app-dev

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ ADD ./view/utils.py ./view/utils.py
103103

104104
ADD ./structs/__init__.py ./structs/__init__.py
105105
ADD ./structs/projects.py ./structs/projects.py
106+
ADD ./structs/teams.py ./structs/teams.py
106107
ADD ./structs/users.py ./structs/users.py
107108

108109
ADD ./api/__init__.py ./api/__init__.py

api/apistructs/teams.py

+14
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,17 @@ class TeamItemUpdateOutput(TeamItemUpdateInput):
3131
class TeamAddressBookOutput(BaseModel):
3232
''' Team address book output '''
3333
datas: list[UserItem] = Field(description='list of users info')
34+
35+
36+
class TeamCreateInput(BaseModel):
37+
''' Team create input '''
38+
id: str = Field(description='team id')
39+
name: str = Field(description='team name')
40+
41+
class Config: # pylint: disable=too-few-public-methods
42+
''' Config '''
43+
anystr_strip_whitespace = True
44+
45+
46+
class TeamCreateOutput(TeamCreateInput):
47+
''' TeamCreateOutput '''

api/routers/members.py

+40-22
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,43 @@ async def members_past(
3232
'''
3333
result = MembersOut()
3434
for team in Team.list_by_pid(pid=pid):
35-
data = {}
36-
data['name'] = team['name']
37-
data['tid'] = team['tid']
35+
if not team.chiefs:
36+
continue
3837

39-
data['chiefs'] = []
40-
chiefs_infos = User.get_info(uids=team['chiefs'])
41-
for uid in team['chiefs']:
38+
data_chiefs: list[MembersInfo] = []
39+
chiefs_infos = User.get_info(uids=team.chiefs)
40+
for uid in team.chiefs:
4241
if uid not in chiefs_infos:
4342
continue
4443

4544
_user = chiefs_infos[uid]
4645
h_msg = hashlib.md5()
4746
h_msg.update(_user['oauth']['email'].encode('utf-8'))
48-
data['chiefs'].append(MembersInfo.parse_obj({
47+
data_chiefs.append(MembersInfo.parse_obj({
4948
'name': _user['profile']['badge_name'],
5049
'email_hash': h_msg.hexdigest(),
5150
}))
5251

53-
data['members'] = []
54-
for _user in User.get_info(uids=list(set(team['members']) - set(team['chiefs']))).values():
52+
data_members: list[MembersInfo] = []
53+
54+
uids = set()
55+
if team.members:
56+
uids.update(team.members)
57+
if team.chiefs:
58+
uids.update(team.chiefs)
59+
60+
for _user in User.get_info(uids=list(uids)).values():
5561
h_msg = hashlib.md5()
5662
h_msg.update(_user['oauth']['email'].encode('utf-8'))
57-
data['members'].append(MembersInfo.parse_obj({
63+
data_members.append(MembersInfo.parse_obj({
5864
'name': _user['profile']['badge_name'],
5965
'email_hash': h_msg.hexdigest(),
6066
}))
6167

62-
result.data.append(MembersTeams.parse_obj(data))
68+
result.data.append(MembersTeams.parse_obj(
69+
{'name': team.name, 'tid': team.id,
70+
'chiefs': data_chiefs, 'members': data_members}
71+
))
6372

6473
if result.data:
6574
return result
@@ -82,34 +91,43 @@ async def members(
8291
'''
8392
result = MembersOut()
8493
for team in Team.list_by_pid(pid=pid):
85-
data = {}
86-
data['name'] = team['name']
87-
data['tid'] = team['tid']
94+
if not team.chiefs:
95+
continue
8896

89-
data['chiefs'] = []
90-
chiefs_infos = User.get_info(uids=team['chiefs'])
91-
for uid in team['chiefs']:
97+
data_chiefs: list[MembersInfo] = []
98+
chiefs_infos = User.get_info(uids=team.chiefs)
99+
for uid in team.chiefs:
92100
if uid not in chiefs_infos:
93101
continue
94102

95103
user = chiefs_infos[uid]
96104
h_msg = hashlib.md5()
97105
h_msg.update(user['oauth']['email'].encode('utf-8'))
98-
data['chiefs'].append(MembersInfo.parse_obj({
106+
data_chiefs.append(MembersInfo.parse_obj({
99107
'name': user['profile']['badge_name'],
100108
'email_hash': h_msg.hexdigest(),
101109
}))
102110

103-
data['members'] = []
104-
for user in User.get_info(uids=list(set(team['members']) - set(team['chiefs']))).values():
111+
data_members: list[MembersInfo] = []
112+
113+
uids = set()
114+
if team.members:
115+
uids.update(team.members)
116+
if team.chiefs:
117+
uids.update(team.chiefs)
118+
119+
for user in User.get_info(uids=list(uids)).values():
105120
h_msg = hashlib.md5()
106121
h_msg.update(user['oauth']['email'].encode('utf-8'))
107-
data['members'].append(MembersInfo.parse_obj({
122+
data_members.append(MembersInfo.parse_obj({
108123
'name': user['profile']['badge_name'],
109124
'email_hash': h_msg.hexdigest(),
110125
}))
111126

112-
result.data.append(MembersTeams.parse_obj(data))
127+
result.data.append(MembersTeams.parse_obj(
128+
{'name': team.name, 'tid': team.id,
129+
'chiefs': data_chiefs, 'members': data_members}
130+
))
113131

114132
if result.data:
115133
return result

api/routers/projects.py

+36-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
ProjectItemUpdateOutput,
1111
ProjectTeamDietaryHabitOutput,
1212
ProjectTeamsOutput)
13+
from api.apistructs.teams import TeamCreateInput, TeamCreateOutput
1314
from api.dependencies import get_current_user
1415
from module.dietary_habit import DietaryHabitItemsName, DietaryHabitItemsValue
1516
from module.project import Project
@@ -126,6 +127,34 @@ async def projects_teams(
126127
return ProjectTeamsOutput.parse_obj({'teams': teams})
127128

128129

130+
@router.post('/{pid}/teams',
131+
summary='Create a new team in project.',
132+
response_model=TeamCreateOutput,
133+
responses={
134+
status.HTTP_404_NOT_FOUND: {'description': 'Project not found'}},
135+
response_model_by_alias=False,
136+
response_model_exclude_none=True,
137+
)
138+
async def projects_teams_create(
139+
create_date: TeamCreateInput,
140+
pid: str = Path(..., description='project id'),
141+
current_user: dict[str, Any] = Depends( # pylint: disable=unused-argument
142+
get_current_user),
143+
) -> TeamCreateOutput | None:
144+
''' Create a new team in project '''
145+
project = Project.get(pid=pid)
146+
if not project:
147+
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
148+
149+
if current_user['uid'] not in project.owners:
150+
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
151+
152+
result = Team.create(
153+
pid=pid, tid=create_date.id, name=create_date.name, owners=project.owners)
154+
155+
return TeamCreateOutput.parse_obj(result)
156+
157+
129158
@router.get('/{pid}/teams/dietary_habit',
130159
summary='Lists of dietary habit statistics in project.',
131160
response_model=list[ProjectTeamDietaryHabitOutput],
@@ -141,8 +170,13 @@ async def projects_teams_dietary_habit(
141170
''' Lists of dietary habit statistics in project '''
142171
all_users = {}
143172
for team in Team.list_by_pid(pid=pid):
144-
for uid in team['chiefs']+team['members']:
145-
all_users[uid] = {'tid': team['tid']}
173+
if team.chiefs:
174+
for uid in team.chiefs:
175+
all_users[uid] = {'tid': team.id}
176+
177+
if team.members:
178+
for uid in team.members:
179+
all_users[uid] = {'tid': team.id}
146180

147181
user_infos = User.get_info(
148182
uids=list(all_users.keys()), need_sensitive=True)

api/routers/sender.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from api.dependencies import get_current_user
1212
from module.sender import SenderCampaign, SenderReceiver
1313
from module.team import Team
14+
from structs.teams import TeamUsers
1415

1516
router = APIRouter(
1617
prefix='/sender',
@@ -36,7 +37,8 @@ async def sender_all(
3637
if not team:
3738
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
3839

39-
if current_user['uid'] not in (team['owners'] + team['chiefs'] + team['members']):
40+
teamusers = TeamUsers.parse_obj(team)
41+
if current_user['uid'] not in (teamusers.owners + teamusers.chiefs + teamusers.members):
4042
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
4143

4244
campaigns = []
@@ -96,7 +98,8 @@ async def sender_upload_receiver_lists_replace(
9698
if not team:
9799
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
98100

99-
if current_user['uid'] not in (team['owners'] + team['chiefs'] + team['members']):
101+
teamusers = TeamUsers.parse_obj(team)
102+
if current_user['uid'] not in (teamusers.owners + teamusers.chiefs + teamusers.members):
100103
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
101104

102105
csv_rows = await sender_upload_receiver(pid=pid, tid=tid, cid=cid,
@@ -125,7 +128,8 @@ async def sender_upload_receiver_lists_update(
125128
if not team:
126129
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
127130

128-
if current_user['uid'] not in (team['owners'] + team['chiefs'] + team['members']):
131+
teamusers = TeamUsers.parse_obj(team)
132+
if current_user['uid'] not in (teamusers.owners + teamusers.chiefs + teamusers.members):
129133
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
130134

131135
csv_rows = await sender_upload_receiver(pid=pid, tid=tid, cid=cid,
@@ -152,7 +156,8 @@ async def sender_upload_receiver_lists_delete(
152156
if not team:
153157
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
154158

155-
if current_user['uid'] not in (team['owners'] + team['chiefs'] + team['members']):
159+
teamusers = TeamUsers.parse_obj(team)
160+
if current_user['uid'] not in (teamusers.owners + teamusers.chiefs + teamusers.members):
156161
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
157162

158163
return UploadReceiverOutput.parse_obj({

api/routers/teams.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from module.mattermost_bot import MattermostTools
1111
from module.team import Team
1212
from module.users import User
13+
from structs.teams import TeamUsers
1314

1415
router = APIRouter(
1516
prefix='/teams',
@@ -71,14 +72,15 @@ async def teams_one_update(
7172
if not team:
7273
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
7374

75+
teamusers = TeamUsers.parse_obj(team)
7476
include: set[str] | None
75-
if current_user['uid'] in team['owners']:
77+
if current_user['uid'] in teamusers.owners:
7678
include = None
7779

78-
elif current_user['uid'] in team['chiefs']:
80+
elif current_user['uid'] in teamusers.chiefs:
7981
include = {'name', 'desc'}
8082

81-
if current_user['uid'] in team['owners'] or include is not None:
83+
if current_user['uid'] in teamusers.owners or include is not None:
8284
updated = Team.update_setting(
8385
pid=pid, tid=tid, data=update_data.dict(include=include))
8486

@@ -108,12 +110,13 @@ async def teams_one_address_book(
108110
if not team:
109111
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
110112

111-
if current_user['uid'] not in (team['owners'] + team['chiefs'] + team['members']):
113+
teamusers = TeamUsers.parse_obj(team)
114+
if current_user['uid'] not in (teamusers.owners + teamusers.chiefs + teamusers.members):
112115
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
113116

114117
uids = set()
115-
uids.update(team['chiefs'])
116-
uids.update(team['members'])
118+
uids.update(teamusers.chiefs)
119+
uids.update(teamusers.members)
117120
users_info = User.get_info(uids=list(uids))
118121

119122
datas = []
@@ -128,7 +131,7 @@ async def teams_one_address_book(
128131
{'id': uid,
129132
'badge_name': users_info[uid]['profile']['badge_name'],
130133
'avatar': users_info[uid]['oauth']['picture'],
131-
'is_chief': uid in team['chiefs'],
134+
'is_chief': uid in teamusers.chiefs,
132135
'chat': chat,
133136
}))
134137

0 commit comments

Comments
 (0)