def project_members(): ''' List all members ''' pid = request.args['pid'] result = [] for team in Team.list_by_pid(pid=pid): data = {} data['name'] = team['name'] data['tid'] = team['tid'] data['chiefs'] = [] for user in User.get_info(uids=team['chiefs']).values(): h = hashlib.md5() h.update(user['oauth']['email'].encode('utf-8')) data['chiefs'].append({ 'name': user['profile']['badge_name'], 'email_hash': h.hexdigest(), }) data['members'] = [] for user in User.get_info( uids=list(set(team['members']) - set(team['chiefs']))).values(): h = hashlib.md5() h.update(user['oauth']['email'].encode('utf-8')) data['members'].append({ 'name': user['profile']['badge_name'], 'email_hash': h.hexdigest(), }) result.append(data) return jsonify({'data': result})
def members(pid, tid): team, project, _redirect = check_the_team_and_project_are_existed(pid=pid, tid=tid) if _redirect: return _redirect is_admin = (g.user['account']['_id'] in team['chiefs'] or \ g.user['account']['_id'] in team['owners'] or \ g.user['account']['_id'] in project['owners']) uids = [] uids.extend(team['chiefs']) uids.extend(team['members']) uids = list(set(uids)) users_info = User.get_info(uids=uids) members = [] for uid in uids: if uid in users_info: user = users_info[uid] user['chat'] = {} mid = MattermostTools.find_possible_mid(uid=uid) if mid: user['chat'] = {'mid': mid, 'name': MattermostTools.find_user_name(mid=mid)} members.append(user) members = sorted(members, key=lambda u: u['profile']['badge_name'].lower()) return render_template('./team_members.html', project=project, team=team, is_admin=is_admin, members=members)
def mail_member_del(sender): ''' mail member del ''' tplenv = Environment(loader=FileSystemLoader('./templates/mail')) template = tplenv.get_template('./base_member_del.html') team_member_change_db = TeamMemberChangedDB() awsses = AWSSES( aws_access_key_id=setting.AWS_ID, aws_secret_access_key=setting.AWS_KEY, source=setting.AWS_SES_FROM) for raw in team_member_change_db.find( {'done.mail': {'$exists': False}, 'case': 'del'}, sort=(('create_at', 1), )): team = Team.get(raw['pid'], raw['tid']) user = User.get_info(uids=(raw['uid'], ))[raw['uid']] body = template.render( name=user['profile']['badge_name'], team_name=team['name'], ) raw_mail = awsses.raw_mail( to_addresses=( dict(name=user['profile']['badge_name'], mail=user['oauth']['email']), ), subject=f"您已被移除 {team['name']} 的組員資格!", body=body, ) resp = mail_member_send.apply_async( kwargs={'raw_mail': raw_mail.as_string(), 'rid': str(raw['_id'])}) logger.info(resp)
def mail_member_welcome(sender, **kwargs): TPLENV = Environment(loader=FileSystemLoader('./templates/mail')) template = TPLENV.get_template('./welcome.html') awsses = AWSSES(aws_access_key_id=setting.AWS_ID, aws_secret_access_key=setting.AWS_KEY, source=setting.AWS_SES_FROM) uids = [] for u in MailLetterDB().need_to_send(code='welcome'): uids.append(u['_id']) if not uids: return service_sync_mattermost_invite.apply_async(kwargs={'uids': uids}) users = User.get_info(uids=uids) for uid in uids: logger.info('uid: %s' % uid) body = template.render(name=users[uid]['profile']['badge_name'], ) raw_mail = awsses.raw_mail( to_addresses=(dict(name=users[uid]['profile']['badge_name'], mail=users[uid]['oauth']['email']), ), subject=u'歡迎使用志工服務系統 - %s' % users[uid]['profile']['badge_name'], body=body, ) resp = awsses.send_raw_email(data=raw_mail) logger.info(resp) if resp['ResponseMetadata']['HTTPStatusCode'] != 200: raise Exception('HTTPStatusCode not `200`, do retry') MailLetterDB().make_sent(uid=uid, code='welcome')
def get_from_user(pid, tids): ''' Get users from userdb by project, team :param str pid: pid :param str tids: team id or ids :return: fields, raws ''' if isinstance(tids, str): tids = (tids, ) team_users = Team.get_users(pid=pid, tids=tids) uids = [] for user_ids in team_users.values(): uids.extend(user_ids) user_infos = User.get_info(uids=uids) datas = [] for uid in user_infos: # append, plus more data here in the future datas.append({ 'name': user_infos[uid]['profile']['badge_name'], 'mail': user_infos[uid]['oauth']['email'], }) raws = [] for data in datas: raw = [] for field in ('name', 'mail'): raw.append(data[field]) raws.append(raw) return (('name', 'mail'), raws)
def service_sync_gsuite_team_members(sender, **kwargs): team = Team.get(pid=kwargs['pid'], tid=kwargs['tid']) if 'to_team' in kwargs: to_team = Team.get(pid=kwargs['to_team'][0], tid=kwargs['to_team'][1]) if 'mailling' not in to_team or not to_team['mailling']: return mailling = to_team['mailling'] else: if 'mailling' not in team or not team['mailling']: return mailling = team['mailling'] uids = [] uids.extend(team['chiefs']) uids.extend(team['members']) users_info = User.get_info(uids=uids) sync_gsuite = SyncGSuite(credentialfile=setting.GSUITE_JSON, with_subject=setting.GSUITE_ADMIN) sync_gsuite.add_users_into_group( group=mailling, users=[u['oauth']['email'] for u in users_info.values()]) logger.info('%s %s', mailling, [u['oauth']['email'] for u in users_info.values()])
def project_form_accommodation(pid): ''' Project form accommodation ''' project = Project.get(pid) if g.user['account']['_id'] not in project['owners']: return redirect( url_for('project.team_page', pid=pid, _scheme='https', _external=True)) if request.method == 'GET': return render_template('./project_form_accommodation.html', project=project) if request.method == 'POST': post_data = request.get_json() if post_data['casename'] == 'get': all_users = {} for team in Team.list_by_pid(pid=pid): for uid in team['chiefs'] + team['members']: all_users[uid] = {'tid': team['tid']} raws = [] for raw in FormAccommodation.get(pid): if raw['uid'] not in all_users: continue raws.append(raw) user_infos = User.get_info(uids=[raw['uid'] for raw in raws], need_sensitive=True) datas = [] for raw in raws: user_info = user_infos[raw['uid']] datas.append({ 'uid': raw['uid'], 'name': user_info['profile']['badge_name'], 'picture': user_info['oauth']['picture'], 'roc_id': user_info['profile_real']['roc_id'], 'tid': all_users[raw['uid']]['tid'], 'room': raw['data'].get('room', ''), 'room_key': raw['data'].get('room_key', ''), 'data': raw['data'], }) return jsonify({'datas': datas}) if post_data['casename'] == 'update': for data in post_data['datas']: logging.info('uid: %s, room: %s', data['uid'].strip(), data['room'].strip()) FormAccommodation.update_room(pid=pid, uid=data['uid'].strip(), room=data['room'].strip()) return jsonify({}) return jsonify({}), 404
def service_sync_mattermost_invite(sender, **kwargs): mmb = MattermostBot(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) users_info = User.get_info(uids=kwargs['uids']) r = mmb.post_invite_by_email( team_id=setting.MATTERMOST_TEAM_ID, emails=[users_info[uid]['oauth']['email'] for uid in users_info]) logger.info(r.json())
def service_sync_mattermost_invite(sender, **kwargs): ''' Sync mattermost invite ''' mmb = MattermostBot(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) users_info = User.get_info(uids=kwargs['uids']) resp = mmb.post_invite_by_email( team_id=setting.MATTERMOST_TEAM_ID, emails=[value['oauth']['email'] for value in users_info.values()]) logger.info(resp.json())
def by_project_index(pid): ''' Project index ''' project = Project.get(pid) if not project: return redirect('/') is_admin = Budget.is_admin(pid=pid, uid=g.user['account']['_id']) if not is_admin: return redirect('/') if request.method == 'GET': return render_template('./expense.html', project=project, is_admin=is_admin) if request.method == 'POST': data = request.get_json() if data['casename'] == 'get': datas = list(Expense.get_all_by_pid(pid=pid)) buids = set() uids = set() for expense in datas: buids.add(expense['request']['buid']) uids.add(expense['create_by']) budgets = {} if buids: for raw in Budget.get(buids=list(buids), pid=pid): budgets[raw['_id']] = raw users = {} if uids: user_datas = User.get_info(uids=list(uids)) for uid, value in user_datas.items(): users[uid] = { 'oauth': value['oauth'], 'profile': {'badge_name': value['profile']['badge_name']}, } return jsonify({'datas': datas, 'budgets': budgets, 'users': users, 'status': Expense.status()}) if data['casename'] == 'update': # update invoices Expense.update_invoices( expense_id=data['data']['_id'], invoices=data['data']['invoices']) Expense.update_enable( expense_id=data['data']['_id'], enable=data['data']['enable']) result = Expense.update_status( expense_id=data['data']['_id'], status=data['data']['status']) return jsonify({'result': result}) return jsonify({}), 404
def mail_member_waiting(sender): ''' mail member waiting ''' template = Environment(loader=FileSystemLoader( './templates/mail')).get_template('./base_member_waiting.html') team_member_change_db = TeamMemberChangedDB() awsses = AWSSES( aws_access_key_id=setting.AWS_ID, aws_secret_access_key=setting.AWS_KEY, source=setting.AWS_SES_FROM) for raw in team_member_change_db.find( {'done.mail': {'$exists': False}, 'case': 'waiting'}, sort=(('create_at', 1), )): team = Team.get(raw['pid'], raw['tid']) uids = [] uids.extend(team['chiefs']) uids.append(raw['uid']) users = User.get_info(uids=uids) mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) for uid in team['chiefs']: body = template.render( name=users[uid]['profile']['badge_name'], uid=raw['uid'], apply_name=users[raw['uid']]['profile']['badge_name'], team_name=team['name'], pid=team['pid'], tid=team['tid'], ) raw_mail = awsses.raw_mail( to_addresses=(dict( name=users[uid]['profile']['badge_name'], mail=users[uid]['oauth']['email']), ), subject=f"申請加入通知信 - {users[raw['uid']]['profile']['badge_name']}", body=body, ) resp = mail_member_send.apply_async( kwargs={'raw_mail': raw_mail.as_string(), 'rid': str(raw['_id'])}) logger.info(resp) mid = mmt.find_possible_mid(uid=uid) if mid: channel_info = mmt.create_a_direct_message( users=(mid, setting.MATTERMOST_BOT_ID)).json() resp = mmt.posts( channel_id=channel_info['id'], message=f"收到 **{users[raw['uid']]['profile']['badge_name']}** 申請加入 **{team['name']}**,前往 [管理組員](https://volunteer.coscup.org/team/{team['pid']}/{team['tid']}/edit_user)", # pylint: disable=line-too-long ) logger.info(resp.json())
def index(pid, tid): ''' Index page ''' team, project, _redirect = check_the_team_and_project_are_existed(pid=pid, tid=tid) if _redirect: return _redirect is_admin = (g.user['account']['_id'] in team['chiefs'] or g.user['account']['_id'] in team['owners'] or g.user['account']['_id'] in project['owners']) if not is_admin: return redirect('/') # ..note:: # 1. create campaign (campaign name) / list campaign # 2. write title, content(jinja2, markdown) # 3. pick up receiver # 4. send / send test if request.method == 'GET': return render_template('./sender.html') if request.method == 'POST': data = request.get_json() if 'casename' in data and data['casename'] == 'get': campaigns = list( SenderCampaign.get_list(pid=team['pid'], tid=team['tid'])) raw_users_info = User.get_info( uids=[c['created']['uid'] for c in campaigns]) users_info = {} for uid, value in raw_users_info.items(): users_info[uid] = { 'uid': uid, 'name': value['profile']['badge_name'] } return jsonify({'campaigns': campaigns, 'users_info': users_info}) if 'casename' in data and data['casename'] == 'create': resp = SenderCampaign.create(name=data['name'], pid=team['pid'], tid=team['tid'], uid=g.user['account']['_id']) return jsonify({'cid': resp['_id']}) return jsonify({})
def project_dietary_habit(pid): ''' Project dietary habit ''' project = Project.get(pid) if g.user['account']['_id'] not in project['owners']: return redirect( url_for('project.team_page', pid=pid, _scheme='https', _external=True)) if request.method == 'GET': return render_template('./project_dietary_habit.html', project=project) if request.method == 'POST': post_data = request.get_json() if post_data['casename'] == 'get': all_users = {} for team in Team.list_by_pid(pid=pid): for uid in team['chiefs'] + team['members']: all_users[uid] = {'tid': team['tid']} user_infos = User.get_info(uids=list(all_users.keys()), need_sensitive=True) datas = [] for uid, value in all_users.items(): user_info = user_infos[uid] data = { 'uid': uid, 'name': user_info['profile']['badge_name'], 'picture': user_info['oauth']['picture'], 'tid': value['tid'], 'dietary_habit': [], } if 'profile_real' in user_info and 'dietary_habit' in user_info[ 'profile_real']: data['dietary_habit'] = user_info['profile_real'][ 'dietary_habit'] datas.append(data) return jsonify({ 'datas': datas, 'dietary_habit': DietaryHabit.ITEMS }) return '', 404
def read(pid, task_id): ''' Read ''' project_info = Project.get(pid=pid) if not project_info: return '404', 404 task = Tasks.get_with_pid(pid=pid, _id=task_id) if not task: return redirect( url_for('tasks.project', pid=pid, _scheme='https', _external=True)) task['starttime'] = arrow.get( task['starttime']).to('Asia/Taipei').format('YYYY-MM-DD HH:mm') if task['endtime']: task['endtime'] = arrow.get( task['endtime']).to('Asia/Taipei').format('YYYY-MM-DD HH:mm') uid = g.get('user', {}).get('account', {}).get('_id') if request.method == 'GET': creator = {} user_info = User.get_info(uids=[ task['created_by'], ]) creator['name'] = user_info[ task['created_by']]['profile']['badge_name'] creator['uid'] = task['created_by'] mid = MattermostTools.find_possible_mid(uid=task['created_by']) if mid: creator['mattermost_uid'] = MattermostTools.find_user_name(mid=mid) return render_template('./tasks_detail.html', task=task, creator=creator, uid=uid) if request.method == 'POST': if not uid: return jsonify({'info': 'Need login'}), 401 post_data = request.get_json() if post_data['casename'] == 'join': Tasks.join(pid=pid, task_id=task['_id'], uid=uid) elif post_data['casename'] == 'cancel': Tasks.cancel(pid=pid, task_id=task['_id'], uid=uid) return jsonify({}) return jsonify({})
def project_contact_book(pid): ''' Project contact book ''' project = Project.get(pid) if g.user['account']['_id'] not in project['owners']: return redirect( url_for('project.team_page', pid=pid, _scheme='https', _external=True)) if request.method == 'GET': return render_template('./project_contact_book.html', project=project) if request.method == 'POST': post_data = request.get_json() if post_data['casename'] == 'get': all_users = {} for team in Team.list_by_pid(pid=pid): for uid in team['chiefs'] + team['members']: all_users[uid] = {'tid': team['tid']} user_infos = User.get_info(uids=list(all_users.keys()), need_sensitive=True) mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) datas = [] for uid, value in all_users.items(): user_info = user_infos[uid] data = { 'uid': uid, 'name': user_info['profile']['badge_name'], 'picture': user_info['oauth']['picture'], 'tid': value['tid'], 'email': user_info['oauth']['email'], } if 'profile_real' in user_info: data['phone'] = user_info['profile_real'].get('phone', '') data['user_name'] = mmt.find_user_name( mmt.find_possible_mid(uid=uid)) datas.append(data) return jsonify({'datas': datas}) return jsonify({}), 404
def get_peoples_info(pid: str, task_id: str) -> Optional[dict[str, Any]]: ''' Get peoples info Args: pid (str): Project id. task_id (str): Task id. Returns: Return the datas. ''' task = TasksDB().find_one({'pid': pid, '_id': task_id}, {'people': 1}) if task: uids = task['people'] return User.get_info(uids=uids) return None
def service_sync_gsuite_team_leader(sender, **kwargs): chiefs = [] # note: sync all, include `disabled` team for team in TeamDB(pid=None, tid=None).find({'pid': kwargs['pid']}): chiefs.extend(team['chiefs']) users_info = User.get_info(uids=chiefs) project = Project.get(pid=kwargs['pid']) sync_gsuite = SyncGSuite(credentialfile=setting.GSUITE_JSON, with_subject=setting.GSUITE_ADMIN) sync_gsuite.add_users_into_group( group=project['mailling_staff'], users=[u['oauth']['email'] for u in users_info.values()]) logger.info('%s %s', project['mailling_staff'], [u['oauth']['email'] for u in users_info.values()])
def expense_create(sender, **kwargs): ''' Expense create ''' pid = kwargs['expense']['pid'] buid = kwargs['expense']['request']['buid'] budget = None for data in Budget.get(buids=[ buid, ], pid=pid): budget = data if not budget: return uids = set() for team in TeamDB(pid=None, tid=None).find({ 'pid': pid, 'tid': 'finance' }): uids.update(team['chiefs']) uids.update(team['members']) uids.update(Project.get(pid=pid)['owners']) uids.add(kwargs['expense']['create_by']) logger.info(uids) users = User.get_info(uids=list(uids)) mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) for uid in uids: mid = mmt.find_possible_mid(uid=uid) if mid: channel_info = mmt.create_a_direct_message( users=(mid, setting.MATTERMOST_BOT_ID)).json() resp = mmt.posts( channel_id=channel_info['id'], message= f"""收到 **{users[kwargs['expense']['create_by']]['profile']['badge_name']}** 申請費用 - **[{kwargs['expense']['code']}] / {budget['name']}**,前往 [管理費用](https://volunteer.coscup.org/expense/{pid})""", ) logger.info(resp.json())
def mail_member_add(sender, **kwargs): TPLENV = Environment(loader=FileSystemLoader('./templates/mail')) template = TPLENV.get_template('./base_member_add.html') team_member_change_db = TeamMemberChangedDB() awsses = AWSSES(aws_access_key_id=setting.AWS_ID, aws_secret_access_key=setting.AWS_KEY, source=setting.AWS_SES_FROM) for raw in team_member_change_db.find( { 'done.mail': { '$exists': False }, 'case': 'add' }, sort=(('create_at', 1), )): team = Team.get(raw['pid'], raw['tid']) user = User.get_info(uids=(raw['uid'], ))[raw['uid']] body = template.render( name=user['profile']['badge_name'], team_name=team['name'], pid=team['pid'], tid=team['tid'], ) raw_mail = awsses.raw_mail( to_addresses=(dict(name=user['profile']['badge_name'], mail=user['oauth']['email']), ), subject=u'申請加入 %s 核准' % team['name'], body=body, ) r = mail_member_send.apply_async(kwargs={ 'raw_mail': raw_mail.as_string(), 'rid': str(raw['_id']) }) service_sync_mattermost_add_channel.apply_async(kwargs={ 'pid': raw['pid'], 'uids': (raw['uid'], ) }) logger.info(r)
def team_edit_user_api(pid, tid): team, project, _redirect = check_the_team_and_project_are_existed(pid=pid, tid=tid) if _redirect: return _redirect is_admin = (g.user['account']['_id'] in team['chiefs'] or \ g.user['account']['_id'] in team['owners'] or \ g.user['account']['_id'] in project['owners']) if not is_admin: return redirect('/') if request.method == 'GET': user = User(uid=request.args['uid']).get() user_waitting = WaitList.list_by_team(pid=pid, tid=tid, uid=user['_id']) if not user_waitting: return jsonify({}) users_info = User.get_info([user['_id'], ]) user_data = { 'badge_name': users_info[user['_id']]['profile']['badge_name'], 'picture': users_info[user['_id']]['oauth']['picture'], 'uid': user['_id'], 'note': user_waitting['note'], 'wid': u'%(_id)s' % user_waitting, } return jsonify(user_data) elif request.method == 'POST': all_members = len(team['members']) + len(team['chiefs']) if 'headcount' in team and team['headcount'] and all_members >= team['headcount']: return jsonify({'status': 'fail', 'message': 'over headcount.'}), 406 data = request.json w = WaitList.make_result(wid=data['wid'], pid=pid, uid=data['uid'], result=data['result']) if w and 'result' in w: if w['result'] == 'approval': Team.update_members(pid=pid, tid=tid, add_uids=[data['uid'], ]) elif w['result'] == 'deny': TeamMemberChangedDB().make_record(pid=pid, tid=tid, deny_uids=(data['uid'], )) return jsonify({'status': 'ok'})
def get_by_tags(pid: str, tid: str, tags: list[str]) -> tuple[tuple[str, str], list[tuple[str, str]]]: ''' Get users by tags Returns: Return a tuple with `('name', 'mail')` at first. The second is the all datas. ''' uids = Team.get_members_uid_by_tags(pid=pid, tid=tid, tags=tags) user_infos = User.get_info(uids=uids) raws = [] for value in user_infos.values(): raws.append(( value['profile']['badge_name'], value['oauth']['email'], )) return (('name', 'mail'), raws)
def replace(pid: str, cid: str, datas: list[dict[str, Any]]) -> None: ''' Replace Args: pid (str): Project id. cid (str): Campaign id. datas (list): List of receiver datas. `name`, `mail` are required or include `uid` for auto replace the `name`, `mail` value. ''' sender_receiver_db = SenderReceiverDB() sender_receiver_db.remove_past(pid=pid, cid=cid) uids = [] for data in datas: if 'uid' in data and data['uid']: uids.append(data['uid']) user_infos = User.get_info(uids=uids) user_info_uids = {} for uid, data in user_infos.items(): user_info_uids[uid] = { 'name': data['profile']['badge_name'], 'mail': data['oauth']['email'], } save_datas = [] for data in datas: if 'uid' in data and data['uid'] and data['uid'] in user_info_uids: _data = SenderReceiverDB.new(pid=pid, cid=cid, name=user_info_uids[data['uid'] ]['name'], mail=user_info_uids[data['uid'] ]['mail'], ) else: _data = SenderReceiverDB.new( pid=pid, cid=cid, name=data['name'], mail=data['mail']) _data['data'].update(data) save_datas.append(_data) sender_receiver_db.update_data(pid=pid, cid=cid, datas=save_datas)
def get_from_user(pid: str, tids: Union[str, list[str]]) -> tuple[tuple[str, str], list[list[str]]]: ''' Get users from userdb by project, team Args: pid (str): Project id. tids (list): List of `tid`. Returns: Return a tuple with `('name', 'mail')` at first. The second is the all datas. ''' _tids: list[str] if isinstance(tids, str): _tids = [tids, ] else: _tids = tids team_users = Team.get_users(pid=pid, tids=_tids) uids = [] for user_ids in team_users.values(): uids.extend(user_ids) user_infos = User.get_info(uids=uids) datas = [] for value in user_infos.values(): # append, plus more data here in the future datas.append({ 'name': value['profile']['badge_name'], 'mail': value['oauth']['email'], }) raws = [] for data in datas: raw = [] for field in ('name', 'mail'): raw.append(data[field]) raws.append(raw) return (('name', 'mail'), raws)
def get_all_users() -> tuple[tuple[str, str], list[tuple[str, str]]]: ''' Get all users Returns: Return a tuple with `('name', 'mail')` at first. The second is the all datas. ''' uids = [] for user in User.get_all_users(): uids.append(user['_id']) user_infos = User.get_info(uids=uids) raws = [] for value in user_infos.values(): raws.append(( value['profile']['badge_name'], value['oauth']['email'], )) return (('name', 'mail'), raws)
def mail_tasks_star(sender, **kwargs): ''' mail tasks star ''' pid = kwargs['pid'] task_id = kwargs['task_id'] task = Tasks.get_with_pid(pid=pid, _id=task_id) uids = [] for user in TasksStar.get(pid=pid): uids.append(user['uid']) logger.info(uids) users = User.get_info(uids=uids) for user_info in users.items(): user = {} user['name'] = user_info['profile']['badge_name'] user['mail'] = user_info['oauth']['email'] mail_tasks_star_one.apply_async(kwargs={ 'pid': pid, 'task_id': task_id, 'user': user, 'task': task})
def team_page(pid): ''' Team page ''' teams = [] project = Project.get(pid) if not project: return 'no data', 404 data = list(Team.list_by_pid(project['_id'])) uids = [] for team in data: uids.extend(team['chiefs']) total = 0 user_info = User.get_info(uids) for team in data: team['chiefs_name'] = [] for uid in team['chiefs']: team['chiefs_name'].append( f'''<a href="/user/{uid}">{user_info[uid]['profile']['badge_name']}</a>''' ) team['count'] = len(set(team['chiefs'] + team['members'])) total += team['count'] # ----- group for layout ----- # per = 3 for i in range(int(math.ceil(len(data) / float(per)))): teams.append(data[per * i:min([per * (i + 1), len(data)])]) editable = g.user['account']['_id'] in project['owners'] return render_template( './project_teams_index.html', teams=teams, project=project, editable=editable, total=total, )
def team_edit_user(pid, tid): team, project, _redirect = check_the_team_and_project_are_existed(pid=pid, tid=tid) if _redirect: return _redirect is_admin = (g.user['account']['_id'] in team['chiefs'] or \ g.user['account']['_id'] in team['owners'] or \ g.user['account']['_id'] in project['owners']) if not is_admin: return redirect('/') if request.method == 'GET': waitting_list = list(WaitList.list_by_team(pid=pid, tid=tid)) uids = [u['uid'] for u in waitting_list] users_info = User.get_info(uids) for u in waitting_list: u['_info'] = users_info[u['uid']] u['_history'] = [] for w in WaitList.find_history(pid=pid, uid=u['uid']): if 'result' not in w: w['result'] = 'waitting' u['_history'].append(w) u['_mail'] = User(uid=u['uid']).get()['mail'] members = [] if team['members'] or team['chiefs']: _all_uids = set(team['chiefs']) | set(team['members']) users_info = User.get_info(list(_all_uids)) for uid in _all_uids: members.append(users_info[uid]) for u in members: u['chat'] = {} mid = MattermostTools.find_possible_mid(uid=u['_id']) if mid: u['chat'] = {'mid': mid, 'name': MattermostTools.find_user_name(mid=mid)} u['phone'] = {'country_code': '', 'phone': ''} if 'phone' in u['profile_real'] and u['profile_real']['phone']: phone = phonenumbers.parse(u['profile_real']['phone']) u['phone']['country_code'] = phonenumbers.COUNTRY_CODE_TO_REGION_CODE[phone.country_code][0] u['phone']['phone'] = phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.NATIONAL) members = sorted(members, key=lambda u: u['profile']['badge_name']) return render_template('./team_edit_user.html', project=project, team=team, waitting_list=waitting_list, members=members) elif request.method == 'POST': data = request.json if data['case'] == 'deluser': Team.update_members(pid=pid, tid=tid, del_uids=[data['uid'], ]) elif data['case'] == 'history': history = [] for raw in WaitList.find_history_in_team(uid=data['uid'], pid=pid, tid=tid): raw['_id'] = str(raw['_id']) history.append(raw) return jsonify({'history': history}) return jsonify(data)
def team_form_accommodation(pid, tid): team, project, _redirect = check_the_team_and_project_are_existed(pid=pid, tid=tid) if _redirect: return _redirect if not (g.user['account']['_id'] in team['members'] or \ g.user['account']['_id'] in team['chiefs']): return redirect('/') is_ok_submit = False user = g.user['account'] if 'profile_real' in user and 'name' in user['profile_real'] and 'roc_id' in user['profile_real'] and 'phone' in user['profile_real']: if user['profile_real']['name'] and user['profile_real']['roc_id'] and user['profile_real']['phone']: is_ok_submit = True if request.method == 'GET': return render_template('./form_accommodation.html', project=project, team=team, is_ok_submit=is_ok_submit) elif request.method == 'POST': if not is_ok_submit: return u'', 406 post_data = request.get_json() if post_data['casename'] == 'get': raw = {'selected': 'no'} room = {} form_data = Form.get_accommodation(pid=pid, uid=g.user['account']['_id']) if form_data: raw['selected'] = form_data['data']['key'] if 'room' in form_data['data'] and form_data['data']['room']: room['no'] = form_data['data']['room'] room['key'] = form_data['data']['room_key'] room['exkey'] = form_data['data'].get('room_exkey', '') room['mate'] = {} _user_room, mate_room = FormAccommodation.get_room_mate(pid=pid, uid=g.user['account']['_id']) if mate_room: user_info = User.get_info(uids=[mate_room['uid'], ])[mate_room['uid']] room['mate'] = { 'uid': mate_room['uid'], 'name': user_info['profile']['badge_name'], 'tid': '', 'picture': user_info['oauth']['picture'], } return jsonify({'data': raw, 'room': room}) elif post_data['casename'] == 'update': if post_data['selected'] not in ('no', 'yes', 'yes-longtraffic'): return u'', 406 data = { 'status': True if post_data['selected'] in ('yes', 'yes-longtraffic') else False, 'key': post_data['selected'], } Form.update_accommodation(pid=pid, uid=g.user['account']['_id'], data=data) return jsonify({'data': {'selected': post_data['selected']}}) elif post_data['casename'] == 'makechange': msg = FormAccommodation.make_exchange(pid=pid, uid=g.user['account']['_id'], exkey=post_data['key'].strip()) return jsonify({'data': post_data, 'msg': msg})
def make_exchange(cls, pid: str, uid: str, exkey: str) -> str: ''' make exchange Args: pid (str): Project id. uid (str): User id. exkey (str): Exchange key. ''' data = FormDB().find_one_and_update( { 'case': 'accommodation', 'pid': pid, 'uid': uid }, {'$set': { 'data.room_exkey': exkey }}, return_document=ReturnDocument.AFTER, ) ex_mate = FormDB().find_one({ 'case': 'accommodation', 'pid': pid, 'data.room_exkey': data['data']['room_key'] }) if not ex_mate: logging.info('等待交換中 `%s`', exkey) return '等待交換中' # do exchange new_room = 'R-' + f'{uuid4().fields[0]:04x}' FormDB().update_many( { 'case': 'accommodation', 'pid': pid, 'uid': { '$in': (uid, ex_mate['uid']) } }, { '$set': { 'data.room': new_room }, '$unset': { 'data.room_exkey': 1 } }, ) cls.update_room_key(pid=pid, uids=(uid, ex_mate['uid'])) logging.info('已交換 %s %s %s', new_room, uid, ex_mate['uid']) old_mates = list(FormDB().find({ 'case': 'accommodation', 'pid': pid, 'data.room': { '$in': (data['data']['room'], ex_mate['data']['room']) } })) logging.info('old_mates: %s', ', '.join([mate['uid'] for mate in old_mates])) if len(old_mates) < 2: return '交換完畢' uids = [mate['uid'] for mate in old_mates] user_infos = User.get_info(uids=uids, need_sensitive=True) if user_infos[uids[0]]['profile_real']['roc_id'][1] != user_infos[ uids[1]]['profile_real']['roc_id'][1]: logging.info('old_mates 性別不同,不交換。') return '交換完畢' new_room = 'R-' + f'{uuid4().fields[0]:04x}' FormDB().update_many( { 'case': 'accommodation', 'pid': pid, 'uid': { '$in': uids } }, { '$set': { 'data.room': new_room }, '$unset': { 'data.room_exkey': 1 } }, ) cls.update_room_key(pid=pid, uids=uids) logging.info('old_mates new rooms: %s, %s', new_room, ', '.join(uids)) return '交換完畢'
def project(pid): ''' Project ''' # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements uid = g.get('user', {}).get('account', {}).get('_id') project_info = Project.get(pid=pid) if not project_info: return '404', 404 is_in_project = False if uid: is_in_project = bool(Team.participate_in(uid, pid)) if request.method == 'GET': return render_template('./tasks_project.html', project=project_info) if request.method == 'POST': post_data = request.get_json() def page_args(data, uid): data['_uid'] = uid data['_joined'] = False data['_login'] = False data['_is_in_project'] = is_in_project if uid: data['_login'] = True if uid in data['people']: data['_joined'] = True if post_data['casename'] == 'get': datas = [] for data in Tasks.get_by_pid(pid=pid): page_args(data=data, uid=uid) datas.append(data) is_star = False if uid: is_star = TasksStar.status(pid, uid)['add'] return jsonify({ 'datas': datas, 'is_in_project': is_in_project, 'is_star': is_star }) if post_data['casename'] == 'star': if not uid: return jsonify({'info': 'Need login'}), 401 result = TasksStar.toggle(pid=pid, uid=uid) return jsonify({'is_star': result['add']}) if post_data['casename'] == 'join': if not uid: return jsonify({'info': 'Need login'}), 401 data = Tasks.join(pid=pid, task_id=post_data['task_id'], uid=uid) page_args(data=data, uid=uid) return jsonify({'data': data}) if post_data['casename'] == 'cancel': if not uid: return jsonify({'info': 'Need login'}), 401 data = Tasks.cancel(pid=pid, task_id=post_data['task_id'], uid=uid) page_args(data=data, uid=uid) return jsonify({'data': data}) if post_data['casename'] == 'cancel_user': if not uid: return jsonify({'info': 'Need login'}), 401 if not is_in_project: return jsonify({'info': 'Need as staff'}), 401 data = Tasks.cancel(pid=pid, task_id=post_data['task_id'], uid=post_data['uid']) page_args(data=data, uid=uid) return jsonify({'data': data}) if post_data['casename'] == 'peoples': task_data = Tasks.get_with_pid(pid=pid, _id=post_data['task_id']) if not task_data: return jsonify({}), 404 creator = {} if task_data: user_info = User.get_info(uids=[ task_data['created_by'], ]) creator['name'] = user_info[ task_data['created_by']]['profile']['badge_name'] creator['uid'] = task_data['created_by'] mid = MattermostTools.find_possible_mid( uid=task_data['created_by']) if mid: creator['mattermost_uid'] = MattermostTools.find_user_name( mid=mid) if not is_in_project: return jsonify({'peoples': {}, 'creator': creator}) users_info = Tasks.get_peoples_info(pid=pid, task_id=post_data['task_id']) peoples = {} for uid, user in users_info.items(): peoples[uid] = { 'name': user['profile']['badge_name'], 'mail': user['oauth']['email'], 'picture': user['oauth']['picture'], 'mattermost_uid': None, } mid = MattermostTools.find_possible_mid(uid=uid) if mid: peoples[uid][ 'mattermost_uid'] = MattermostTools.find_user_name( mid=mid) return jsonify({'peoples': peoples, 'creator': creator}) return jsonify({}), 404