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 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 team_edit(pid, tid): ''' Team edit ''' 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': return render_template('./team_edit_setting.html', project=project, team=team) if request.method == 'POST': data = { 'name': request.form['name'].strip(), 'public_desc': request.form['public_desc'].strip(), 'desc': request.form['desc'].strip(), } Team.update_setting(pid=team['pid'], tid=team['tid'], data=data) return redirect( url_for('team.team_edit', pid=team['pid'], tid=team['tid'], _scheme='https', _external=True)) return '', 404
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 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 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 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 user_page(uid, nickname=None): user = User(uid=uid).get() if not user: return u'', 200 oauth = OAuth(user['mail']).get() if 'profile' in user and 'badge_name' in user['profile']: _nickname = user['profile']['badge_name'] else: _nickname = oauth['data']['name'] _nickname = quote_plus(_nickname) if nickname is None or nickname != _nickname: return redirect(url_for('user.user_page', uid=uid, nickname=_nickname)) if 'profile' not in user: badge_name = '' intro = '' else: badge_name = user['profile']['badge_name'] intro = re.sub('<a href="javascript:.*"', '<a href="/"', markdown(html.escape(user['profile']['intro']))) participate_in = [] for p in Team.participate_in(uid): p['_project'] = Project.get(p['pid']) p['_title'] = '???' if uid in p['chiefs']: p['_title'] = 'chief' elif uid in p['members']: p['_title'] = 'member' p['_action_date'] = arrow.get( p['_project']['action_date']).format('YYYY/MM') participate_in.append(p) participate_in = sorted(participate_in, key=lambda p: p['_project']['action_date'], reverse=True) mattermost_data = {} mid = MattermostTools.find_possible_mid(uid=uid) if mid: mattermost_data['mid'] = mid mattermost_data['username'] = MattermostTools.find_user_name(mid=mid) return render_template( './user.html', badge_name=badge_name, intro=intro, oauth=oauth, user=user, mattermost_data=mattermost_data, participate_in=participate_in, )
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 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 team_expense_index(pid, tid): ''' Team expense index ''' 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('/') if request.method == 'POST': data = request.get_json() if data['casename'] == 'get': teams = [] for _team in Team.list_by_pid(pid=project['_id']): teams.append({'name': _team['name'], 'tid': _team['tid']}) select_team = data['select_team'] if select_team == '': select_team = team['tid'] items = [] for item in Budget.get_by_tid(pid=pid, tid=select_team, only_enable=True): items.append(item) bank = User.get_bank(uid=g.user['account']['_id']) return jsonify({ 'teams': teams, 'items': items, 'select_team': select_team, 'bank': bank }) if data['casename'] == 'add_expense': # create expense and send notification. expense = Expense.process_and_add(pid=project['_id'], tid=team['tid'], uid=g.user['account']['_id'], data=data) expense_create.apply_async(kwargs={'expense': expense}) return jsonify(data) if data['casename'] == 'get_has_sent': data = Expense.get_has_sent(pid=project['_id'], budget_id=data['buid']) return jsonify({'data': list(data)}) return jsonify({}), 404
def project_edit_create_team(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)) teams = Team.list_by_pid(project['_id'], show_all=True) return render_template('./project_edit_create_team.html', project=project, teams=teams)
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 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 service_sync_mattermost_users_position(sender, **kwargs): ''' Sync mattermost users position ''' # pylint: disable=too-many-locals,too-many-branches pids = [] for project in Project.all(): if project['action_date'] >= time(): pids.append(project['_id']) if not pids: return for pid in pids: users = {} for team in Team.list_by_pid(pid=pid): team_name = team['name'].split('-')[0].strip() for chief in team['chiefs']: if chief not in users: users[chief] = [] if team['tid'] == 'coordinator': users[chief].append('ЪїЪуИйтЈг') else: users[chief].append(f'РГљ№ИЈухёжЋи@{team_name}') team['members'] = set(team['members']) - set(team['chiefs']) for member in team['members']: if member not in users: users[member] = [] users[member].append(f'{team_name}(ухётЊА)') mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) mmb = MattermostBot(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) for uid, value in users.items(): mid = mmt.find_possible_mid(uid=uid) if not mid: continue position = [ pid, ] position.extend(value) position.append(f'[{uid}]') mmb.put_users_patch(uid=mid, position=' '.join(position))
def service_sync_mattermost_users_position(sender, **kwargs): pids = [] for project in Project.all(): if project['action_date'] >= time(): pids.append(project['_id']) if not pids: return for pid in pids: users = {} for team in Team.list_by_pid(pid=pid): team_name = team['name'].split('-')[0].strip() for chief in team['chiefs']: if chief not in users: users[chief] = [] if team['tid'] == 'coordinator': users[chief].append('ЪїЪуИйтЈг') else: users[chief].append('РГљ№ИЈухёжЋи@%s' % team_name) team['members'] = set(team['members']) - set(team['chiefs']) for member in team['members']: if member not in users: users[member] = [] users[member].append('%s(ухётЊА)' % team_name) mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) mmb = MattermostBot(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) for uid in users: mid = mmt.find_possible_mid(uid=uid) if not mid: continue position = [ pid, ] position.extend(users[uid]) position.append('[%s]' % uid) mmb.put_users_patch(uid=mid, position=' '.join(position))
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 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 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 index(): if 'user' not in g: return render_template('index.html') check = { 'profile': False, 'participate_in': False, 'mattermost': False, } if 'profile' in g.user['account'] and 'intro' in g.user['account'][ 'profile']: if len(g.user['account']['profile']['intro']) > 100: check['profile'] = True if list(Team.participate_in(uid=g.user['account']['_id'])): check['participate_in'] = True if MattermostTools.find_possible_mid(uid=g.user['account']['_id']): check['mattermost'] = True return render_template('index_guide.html', check=check)
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 service_sync_mattermost_projectuserin_channel(sender, **kwargs): pids = {} for project in Project.all(): if project['action_date'] >= time( ) and 'mattermost_ch_id' in project and project['mattermost_ch_id']: pids[project['_id']] = project['mattermost_ch_id'] if not pids: return mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN, base_url=setting.MATTERMOST_BASEURL) for pid in pids: uids = set() for team in Team.list_by_pid(pid=pid): uids.update(team['chiefs']) uids.update(team['members']) for uid in uids: mid = mmt.find_possible_mid(uid=uid) if mid: r = mmt.post_user_to_channel(channel_id=pids[pid], uid=mid) logger.info(r.json())
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
def add(pid, task_id=None): ''' Add ''' # pylint: disable=too-many-return-statements,too-many-branches uid = g.get('user', {}).get('account', {}).get('_id') if not uid: return jsonify({'info': 'Need login'}), 401 is_in_project = bool(Team.participate_in(uid, pid)) if not is_in_project: return jsonify({'info': 'Not in project'}), 401 project_info = Project.get(pid=pid) if not project_info: return '404', 404 if request.method == 'GET': catelist = Tasks.get_cate(pid=pid) return render_template('./tasks_add.html', project=project_info, catelist=catelist, task_id=task_id) if request.method == 'POST': post_data = request.get_json() if post_data['casename'] == 'add': data = post_data['data'] starttime = arrow.get(f"{data['date']} {data['starttime']}", tzinfo='Asia/Taipei').datetime endtime = None task_id = None if 'endtime' in data and data['endtime']: endtime = arrow.get(f"{data['date']} {data['endtime']}", tzinfo='Asia/Taipei').datetime if 'task_id' in post_data: task_id = post_data['task_id'] send_star = False if 'task_id' in post_data and not post_data['task_id']: send_star = True raw = Tasks.add(pid=pid, body={ 'title': data['title'].strip(), 'cate': data['cate'].strip(), 'desc': data['desc'], 'limit': max((1, int(data['limit']))), 'starttime': starttime, 'created_by': uid }, endtime=endtime, task_id=task_id) if send_star: mail_tasks_star.apply_async(kwargs={ 'pid': pid, 'task_id': raw['_id'] }) return jsonify({'data': raw}) if post_data['casename'] == 'del': data = Tasks.get_with_pid(pid=pid, _id=post_data['task_id']) if not data: return jsonify({}), 404 if data['created_by'] == g.user['account']['_id']: Tasks.delete(pid=pid, _id=data['_id']) if post_data['casename'] == 'get': data = Tasks.get_with_pid(pid=pid, _id=task_id) if not data: return jsonify({}), 404 starttime = arrow.get(data['starttime']).to('Asia/Taipei') data['date'] = starttime.format('YYYY-MM-DD') data['starttime'] = starttime.format('HH:mm') if data['endtime']: endtime = arrow.get(data['endtime']).to('Asia/Taipei') data['endtime'] = endtime.format('HH:mm') data['_is_creator'] = g.user['account']['_id'] == data[ 'created_by'] return jsonify({'data': data}) return jsonify({}) return jsonify({})
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 by_project_index(pid): ''' index ''' # pylint: disable=too-many-return-statements,too-many-branches 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('./budget.html', project=project, is_admin=is_admin) if request.method == 'POST': data = request.get_json() if data['casename'] == 'get': teams = [] for team in Team.list_by_pid(pid=project['_id']): teams.append({'name': team['name'], 'tid': team['tid']}) default_budget = { 'bid': '', 'uid': '', 'name': '', 'total': 0, 'paydate': '', 'desc': '', 'estimate': '', 'tid': '', 'currency': 'TWD', } items = [] for item in Budget.get_by_pid(pid=pid): if item['enabled']: item['enabled'] = 'true' else: item['enabled'] = 'false' items.append(item) return jsonify({ 'teams': teams, 'default_budget': default_budget, 'items': items }) if data['casename'] == 'check_bid': return jsonify( {'existed': bool(Budget.get_by_bid(pid=pid, bid=data['bid']))}) if data['casename'] == 'add': item = Budget.add(pid=pid, tid=data['data']['tid'], data=data['data']) return jsonify({'data': item}) if data['casename'] == 'edit': if data['data']['enabled'] == 'true': data['data']['enabled'] = True else: data['data']['enabled'] = False item = Budget.edit(pid=pid, data=data['data']) if item['enabled']: item['enabled'] = 'true' else: item['enabled'] = 'false' return jsonify({'data': item}) return jsonify({})
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 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 batch(pid): ''' batch upload ''' 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('./budget_batch.html', project=project, is_admin=is_admin) if request.method == 'POST': if request.is_json: data = request.get_json() if data and data.get('casename') == 'get': teams = [{ 'name': team['name'], 'tid': team['tid'] } for team in Team.list_by_pid(pid=project['_id'])] return jsonify({'teams': teams}) if request.files and 'file' in request.files: csv_file = list( csv.DictReader( io.StringIO('\n'.join(request.files['file'].read().decode( 'utf8').split('\n')[1:])))) result, error_result = Budget.verify_batch_items(items=csv_file) dedup_result = [] dup_bids = [] # Pylint unnecessary-lambda-assignment / C3001 # Lambda expression assigned to a variable. # Define a function using the "def" keyword instead. def has_bid_in_budget(bid): return Budget.get_by_bid(pid=pid, bid=bid) def has_added(item): return item['action'] == 'add' and has_bid_in_budget( item['bid']) def did_update_nonexisted_entry(item): return \ item['action'] == 'update' and not has_bid_in_budget( item['bid']) for item in result: if has_added(item) or did_update_nonexisted_entry(item): dup_bids.append(item['bid']) else: dedup_result.append(item) if request.form['casename'] == 'verify': return jsonify({ 'file': csv_file, 'confirmed': dedup_result, 'error_items': error_result, 'dup_bids': dup_bids, }) if request.form['casename'] == 'save': for item in dedup_result: if item['action'] == 'add': Budget.add(pid=pid, tid=item['tid'], data=item) elif item['action'] == 'update': budget_id = Budget.get_by_bid(pid=pid, bid=item['bid']) if budget_id: item['_id'] = budget_id Budget.edit(pid=pid, data=item) return jsonify({})