Example #1
0
def project_form_traffic_mapping(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':
        return render_template('./project_form_traffic_mapping.html',
                               project=project)

    elif request.method == 'POST':
        data = request.get_json()
        if 'casename' in data and data['casename'] == 'init':
            return jsonify({
                'base': {
                    'loaction': '',
                    'fee': 0
                },
                'data': (FormTrafficFeeMapping.get(pid=pid)
                         or {}).get('data', []),
            })

        if 'casename' in data and data['casename'] == 'save':
            feemapping = {}
            for raw in data['data']:
                if raw['location'].strip():
                    feemapping[raw['location'].strip()] = raw['fee']

            result = FormTrafficFeeMapping.save(pid=pid, data=feemapping)
            return jsonify({'data': result['data']})
Example #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
Example #3
0
def by_project_dl(pid):
    ''' Project download '''
    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':
        raws = Expense.dl_format(pid=pid)

        if not raws:
            return '', 204

        with io.StringIO() as files:
            csv_writer = csv.DictWriter(files, fieldnames=list(
                raws[0].keys()), quoting=csv.QUOTE_MINIMAL)
            csv_writer.writeheader()
            csv_writer.writerows(raws)

            filename = f"coscup_expense_{pid}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"

            return Response(
                files.getvalue(),
                mimetype='text/csv',
                headers={'Content-disposition': f'attachment; filename={filename}',
                         'x-filename': filename,
                         })

    return '', 204
Example #4
0
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
Example #5
0
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,
    )
Example #6
0
def project_form(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':
        return render_template('./project_form.html', project=project)
Example #7
0
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
Example #8
0
def project_edit(pid):
    ''' Project edit '''
    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':
        if 'volunteer_certificate_hours' not in project:
            project['volunteer_certificate_hours'] = 0

        if 'parking_card' in project:
            project['parking_card'] = ', '.join(project['parking_card'])

        return render_template('./project_edit.html', project=project)

    if request.method == 'POST':
        data = {
            'desc':
            request.form['desc'].strip(),
            'name':
            request.form['name'].strip(),
            'volunteer_certificate_hours':
            max([0, int(request.form['volunteer_certificate_hours'])]),
            'calendar':
            request.form['calendar'].strip(),
            'mailling_staff':
            request.form['mailling_staff'].strip(),
            'mailling_leader':
            request.form['mailling_leader'].strip(),
            'shared_drive':
            request.form['shared_drive'].strip(),
            'mattermost_ch_id':
            request.form['mattermost_ch_id'].strip(),
            'traffic_fee_doc':
            request.form['traffic_fee_doc'].strip(),
            'gitlab_project_id':
            request.form['gitlab_project_id'].strip(),
            'parking_card':
            list(
                map(str.strip,
                    request.form['parking_card'].strip().split(','))),
        }
        Project.update(pid, data)
        return redirect(
            url_for('project.project_edit',
                    pid=pid,
                    _scheme='https',
                    _external=True))

    return '', 404
Example #9
0
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 service_sync_mattermost_add_channel(sender, **kwargs):
    project = Project.get(pid=kwargs['pid'])
    if not ('mattermost_ch_id' in project and project['mattermost_ch_id']):
        return

    mmt = MattermostTools(token=setting.MATTERMOST_BOT_TOKEN,
                          base_url=setting.MATTERMOST_BASEURL)
    for uid in kwargs['uids']:
        mid = mmt.find_possible_mid(uid=uid)
        if mid:
            r = mmt.post_user_to_channel(
                channel_id=project['mattermost_ch_id'], uid=mid)
            logger.info(r.json())
Example #11
0
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
Example #12
0
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({})
Example #13
0
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_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()])
Example #15
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
Example #16
0
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())
Example #17
0
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_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
                }})
Example #19
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
Example #20
0
def project_form_api(pid):
    ''' Project form API '''
    # pylint: disable=too-many-return-statements,too-many-branches,too-many-statements
    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 == 'POST':
        data = request.get_json()
        if 'case' not in data:
            return redirect(
                url_for('project.team_page',
                        pid=pid,
                        _scheme='https',
                        _external=True))

        if data['case'] == 'volunteer_certificate':
            fieldnames = ('uid', 'picture', 'value', 'name', 'roc_id',
                          'birthday', 'company')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_volunteer_certificate(pid):
                    user_info = UsersDB().find_one({'_id': raw['uid']})
                    oauth = OAuthDB().find_one({'owner': raw['uid']},
                                               {'data.picture': 1})

                    data = {
                        'uid': raw['uid'],
                        'picture': oauth['data']['picture'],
                        'value': raw['data']['value'],
                        'name': user_info['profile_real']['name'],
                        'roc_id': user_info['profile_real']['roc_id'],
                        'birthday': user_info['profile_real']['birthday'],
                        'company': user_info['profile_real']['company'],
                    }

                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

        elif data['case'] == 'traffic_fee':
            fieldnames = ('uid', 'picture', 'name', 'apply', 'fee',
                          'fromwhere', 'howto')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_traffic_fee(pid):
                    user_info = User.get_info(uids=[
                        raw['uid'],
                    ])[raw['uid']]

                    data = {
                        'uid': raw['uid'],
                        'picture': user_info['oauth']['picture'],
                        'name': user_info['profile']['badge_name'],
                        'apply': raw['data']['apply'],
                        'fee': raw['data']['fee'],
                        'fromwhere': raw['data']['fromwhere'],
                        'howto': raw['data']['howto'],
                    }

                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

        elif data['case'] == 'accommodation':
            fieldnames = ('uid', 'picture', 'name', 'key', 'status')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_accommodation(pid):
                    user_info = User.get_info(uids=[
                        raw['uid'],
                    ])[raw['uid']]

                    data = {
                        'uid': raw['uid'],
                        'picture': user_info['oauth']['picture'],
                        'name': user_info['profile']['badge_name'],
                        'key': raw['data']['key'],
                        'status': raw['data']['status'],
                    }

                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

        elif data['case'] == 'appreciation':
            fieldnames = ('uid', 'picture', 'name', 'available', 'key',
                          'value')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_appreciation(pid):
                    if not raw['data']['available']:
                        continue

                    user_info = User.get_info(uids=[
                        raw['uid'],
                    ])[raw['uid']]

                    data = {
                        'uid': raw['uid'],
                        'picture': user_info['oauth']['picture'],
                        'name': user_info['profile']['badge_name'],
                        'available': raw['data']['available'],
                        'key': raw['data']['key'],
                        'value': raw['data']['value'],
                    }
                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

        elif data['case'] == 'clothes':
            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_info = User.get_info(uids=list(all_users.keys()))

            fieldnames = ('uid', 'picture', 'name', '_has_data', 'tid',
                          'clothes', 'htg')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_clothes(pid):
                    if raw['uid'] not in all_users:
                        continue

                    all_users[raw['uid']]['clothes'] = raw['data']['clothes']

                    if 'htg' in raw['data']:
                        all_users[raw['uid']]['htg'] = raw['data']['htg']

                for uid, value in all_users.items():
                    data = {
                        'uid': uid,
                        'picture': user_info[uid]['oauth']['picture'],
                        'name': user_info[uid]['profile']['badge_name'],
                        '_has_data': bool(value.get('clothes', False)),
                        'tid': value['tid'],
                        'clothes': value.get('clothes'),
                        'htg': value.get('htg'),
                    }
                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

        elif data['case'] == 'parking_card':
            fieldnames = ('uid', 'picture', 'name', 'carno', 'dates')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_parking_card(pid):
                    if not raw['data']['dates']:
                        continue

                    user_info = User.get_info(uids=[
                        raw['uid'],
                    ])[raw['uid']]

                    data = {
                        'uid': raw['uid'],
                        'picture': user_info['oauth']['picture'],
                        'name': user_info['profile']['badge_name'],
                        'carno': raw['data']['carno'],
                        'dates': ', '.join(raw['data']['dates']),
                    }
                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

        elif data['case'] == 'drink':
            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_info = User.get_info(uids=list(all_users.keys()))

            fieldnames = ('uid', 'picture', 'name', '_has_data', 'tid', 'y18')
            with io.StringIO() as str_io:
                csv_writer = csv.DictWriter(str_io, fieldnames=fieldnames)
                csv_writer.writeheader()

                for raw in Form.all_drink(pid):
                    if raw['uid'] not in all_users:
                        continue

                    all_users[raw['uid']]['y18'] = raw['data']['y18']

                for uid, value in all_users.items():
                    data = {
                        'uid': uid,
                        'picture': user_info[uid]['oauth']['picture'],
                        'name': user_info[uid]['profile']['badge_name'],
                        '_has_data': bool(value.get('y18')),
                        'tid': value['tid'],
                        'y18': value.get('y18'),
                    }
                    csv_writer.writerow(data)

                result = []
                for raw in csv.reader(io.StringIO(str_io.getvalue())):
                    result.append(raw)

                return jsonify({'result': result})

    return jsonify({}), 404
Example #21
0
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
Example #22
0
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({})
Example #23
0
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({})
Example #24
0
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({})