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()])
예제 #2
0
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
예제 #3
0
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)
예제 #4
0
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())
예제 #5
0
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
예제 #6
0
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
                }})
예제 #8
0
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})
예제 #9
0
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
예제 #10
0
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