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_edit_create_team_api(pid): 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': _team = Team.get(pid, request.args['tid'].strip()) team = {} for k in ('name', 'chiefs', 'members', 'owners', 'tid', 'headcount', 'mailling', 'disabled'): if k in _team: team[k] = _team[k] if 'headcount' not in team: team['headcount'] = 0 else: team['headcount'] = max([0, int(team['headcount'])]) return jsonify(team) elif request.method == 'POST': data = request.json if data['submittype'] == 'update': Team.update_setting(pid=pid, tid=data['tid'], data=data) return u'%s' % data elif data['submittype'] == 'create': Team.create(pid=pid, tid=data['tid'], name=data['name'], owners=project['owners']) return u'%s' % data
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_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 check_the_team_and_project_are_existed(pid, tid): ''' Base check the team and profect are existed :param str pid: project id :param str tid: team id :rtype: tuple :return: team, project, redirect ''' team = Team.get(pid, tid) if not team: return None, None, redirect('/') project = Project.get(pid) if not project: return None, None, redirect('/') return team, project, None
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 service_sync_gsuite_memberchange(sender, **kwargs): team_member_change_db = TeamMemberChangedDB() sync_gsuite = None for raw in team_member_change_db.find( { 'done.gsuite_team': { '$exists': False }, 'case': { '$in': ('add', 'del') } }, sort=(('create_at', 1), )): team = Team.get(raw['pid'], raw['tid']) if 'mailling' not in team or not team['mailling']: team_member_change_db.find_one_and_update( {'_id': raw['_id']}, {'$set': { 'done.gsuite_team': True }}) continue if sync_gsuite is None: sync_gsuite = SyncGSuite(credentialfile=setting.GSUITE_JSON, with_subject=setting.GSUITE_ADMIN) user = User(uid=raw['uid']).get() if raw['case'] == 'add': sync_gsuite.add_users_into_group(group=team['mailling'], users=(user['mail'], )) team_member_change_db.find_one_and_update( {'_id': raw['_id']}, {'$set': { 'done.gsuite_team': True }}) elif raw['case'] == 'del': sync_gsuite.del_users_from_group(group=team['mailling'], users=(user['mail'], )) team_member_change_db.find_one_and_update( {'_id': raw['_id']}, {'$set': { 'done.gsuite_team': True }}) for raw in team_member_change_db.find( { 'done.gsuite_staff': { '$exists': False }, 'case': { '$in': ('add', 'del') } }, sort=(('create_at', 1), )): project = Project.get(raw['pid']) if 'mailling_staff' not in project or not project['mailling_staff']: team_member_change_db.find_one_and_update( {'_id': raw['_id']}, {'$set': { 'done.gsuite_staff': True }}) continue if sync_gsuite is None: sync_gsuite = SyncGSuite(credentialfile=setting.GSUITE_JSON, with_subject=setting.GSUITE_ADMIN) user = User(uid=raw['uid']).get() if raw['case'] == 'add': sync_gsuite.add_users_into_group(group=project['mailling_staff'], users=(user['mail'], )) team_member_change_db.find_one_and_update( {'_id': raw['_id']}, {'$set': { 'done.gsuite_staff': True }}) elif raw['case'] == 'del': sync_gsuite.del_users_from_group(group=project['mailling_staff'], users=(user['mail'], )) team_member_change_db.find_one_and_update( {'_id': raw['_id']}, {'$set': { 'done.gsuite_staff': True }})
def team_plan_edit(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 request.method == 'GET': return render_template('./team_plan_edit.html', project=project, team=team, is_admin=is_admin) elif request.method == 'POST': data = request.get_json() today = arrow.now().format('YYYY-MM-DD') default = {'title': '', 'desc': '', 'start': today, 'end': '', 'tid': tid, 'team_name': team['name'], 'start_timestamp': 0} team_plan_db = TeamPlanDB() if 'case' in data and data['case'] == 'get': plan_data = team_plan_db.find_one({'pid': pid, 'tid': tid}) if not plan_data: plan_data = {'data': [default, ]} if not plan_data['data']: plan_data['data'] = [default, ] for raw in plan_data['data']: raw['tid'] = tid raw['team_name'] = team['name'] others = [] if 'import_others' in data and data['import_others']: for team_plan in team_plan_db.find({'pid': pid, 'tid': {'$nin': [tid, ]}}): team_info = Team.get(pid=pid, tid=team_plan['tid']) for raw in team_plan['data']: raw['tid'] = tid raw['team_name'] = team_info['name'] others.append(raw) return jsonify({'data': plan_data['data'], 'default': default, 'others': others}) elif 'case' in data and data['case'] == 'get_schedular': query = {'pid': pid} if not data['import_others']: query['tid'] = tid dates = {} team_plan = list(team_plan_db.find(query)) for raw in team_plan: for plan in raw['data']: if not plan['end']: if plan['start'] not in dates: dates[plan['start']] = [] dates[plan['start']].append(plan) else: for d in arrow.Arrow.range('day', arrow.get(plan['start']), arrow.get(plan['end'])): d_format = d.format('YYYY-MM-DD') if d_format not in dates: dates[d_format] = [] dates[d_format].append(plan) return jsonify({'data': list(dates.items())}) elif 'case' in data and data['case'] == 'post': if 'data' in data: _data = [] for raw in data['data']: if raw['title'] and raw['start']: try: arrow.get(raw['start']) _raw = {} for k in ('title', 'start', 'end', 'desc'): _raw[k] = raw[k] _data.append(_raw) except arrow.parser.ParserError: continue _data = sorted(_data, key=lambda d: arrow.get(d['start'])) result = team_plan_db.save(pid=pid, tid=tid, data=_data) for raw in result['data']: raw['tid'] = tid raw['team_name'] = team['name'] raw['start_timestamp'] = arrow.get(raw['start']).timestamp if not result['data']: result['data'] = [default, ] others = [] if 'import_others' in data and data['import_others']: for team_plan in team_plan_db.find({'pid': pid, 'tid': {'$nin': [tid, ]}}): team_info = Team.get(pid=pid, tid=team_plan['tid']) for raw in team_plan['data']: raw['tid'] = tid raw['team_name'] = team_info['name'] raw['start_timestamp'] = arrow.get(raw['start']).timestamp others.append(raw) return jsonify({'data': result['data'], 'default': default, 'others': others}) return jsonify({'data': [], 'default': default})
def project_edit_create_team_api(pid): ''' Project edit create team API ''' 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': _team = Team.get(pid, request.args['tid'].strip()) team = {} for k in ('name', 'chiefs', 'members', 'owners', 'tid', 'headcount', 'mailling', 'disabled'): if k in _team: team[k] = _team[k] if 'headcount' not in team: team['headcount'] = 0 else: team['headcount'] = max([0, int(team['headcount'])]) return jsonify(team) if request.method == 'POST': data = request.json if data['submittype'] == 'update': chiefs = data['chiefs'] members = data['members'] if isinstance(data['chiefs'], str): chiefs = [ _uid.strip() for _uid in data['chiefs'].split(',') if _uid.strip() ] if isinstance(data['members'], str): members = [ _uid.strip() for _uid in data['members'].split(',') if _uid.strip() ] new_members = set(chiefs + members) old_members = set( Team.get_users(pid=pid, tids=(data['tid'], ))[data['tid']]) TeamMemberChangedDB().make_record(pid=pid, tid=data['tid'], action={ 'add': new_members - old_members, 'del': old_members - new_members }) Team.update_setting(pid=pid, tid=data['tid'], data=data) service_sync_mattermost_add_channel.apply_async( kwargs={ 'pid': pid, 'uids': list(new_members) }) return f'{data}' if data['submittype'] == 'create': Team.create(pid=pid, tid=data['tid'], name=data['name'], owners=project['owners']) return f'{data}' return '', 404
def members(pid, tid): ''' members ''' # pylint: disable=too-many-locals 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 request.method == 'GET': return render_template('./team_members.html', project=project, team=team, is_admin=is_admin) if request.method == 'POST': post_data = request.get_json() if post_data['casename'] == 'get': list_teams = [] if 'tid' in post_data and post_data['tid'] != tid: team = Team.get(pid=pid, tid=post_data['tid']) else: for lteam in Team.list_by_pid(pid=pid): list_teams.append({ '_id': lteam['tid'], 'name': lteam['name'] }) uids = [] uids.extend(team['chiefs']) uids.extend(team['members']) uids = list(set(uids)) users_info = User.get_info(uids=uids) result_members = [] for uid in uids: if uid in users_info: user = { '_id': uid, 'profile': { 'badge_name': users_info[uid]['profile']['badge_name'] }, 'oauth': { 'picture': users_info[uid]['oauth']['picture'] } } user['is_chief'] = False if uid in team['chiefs']: user['is_chief'] = True user['chat'] = {} mid = MattermostTools.find_possible_mid(uid=uid) if mid: user['chat'] = { 'mid': mid, 'name': MattermostTools.find_user_name(mid=mid) } result_members.append(user) result_members = sorted( result_members, key=lambda u: u['profile']['badge_name'].lower()) tags = [] if 'tag_members' in team and team['tag_members']: tags = team['tag_members'] members_tags = Team.get_members_tags(pid=team['pid'], tid=team['tid']) return jsonify({ 'members': result_members, 'teams': list_teams, 'tags': tags, 'members_tags': members_tags }) return jsonify({}), 404