async def get_features(request): skip = int(request.args.get('skip', 0)) limit = int(request.args.get('limit', 10)) filter_ = {} product = request.args.get('product') if product: filter_['product'] = ObjectId(product) status = request.args.get('status') if status: filter_['status'] = {'$in': status.split(',')} components = { c['_id']: c async for c in Component.find( {}, ['_id', 'name', 'description', 'type', 'repo', 'docker_repo'])} features = [] async for f in Feature.find(filter_, sort=[('update_time', -1)], skip=skip, limit=limit): c_ids = f['components'] f['components'] = [] for c_id in c_ids: component_detail = components[c_id] f['components'].append(component_detail) features.append(f) return json(jsonify({ 'total': await Feature.count_documents(filter_), 'features': features}))
async def get_components(request): q_ = request.args.get('q') if q_: f_ = {'name': {'$regex': '(?i)' + q_}} else: f_ = {} return json(jsonify([c async for c in Component.find(f_)]))
async def regedit(request): """注册""" user_name = request.json.get('username') psd = request.json.get('password') phone = request.json.get('phone') sex = request.json.get('sex') try: result = await AllUser.find_one({'user_name': user_name}) if not result: # 对密码进行加密处理 secret = hash_psd(psd) # 数据存储 user = AllUser() user.user_name = user_name user.password = secret user.phone = phone user.sex = sex role = await Permission.find_one({'order': 0}) user.user_label = role['_id'] await user.save() logging.info(result) return json(jsonify({'success': '注册成功'})) else: raise InvalidUsage('用户已存在') except Exception as e: logging.info(e) raise InvalidUsage('系统错误')
async def get_release_detail(request, release_id): release = await Release.find_one({'_id': ObjectId(release_id)}) or {} if not release: return json({}) product = await Product.find_one({'_id': release['product']}, ['name', 'components', 'export_script']) if product: release['product_name'] = product['name'] release['product_export_script'] = product.get('export_script', '') release['merge_requests'] = [mr async for mr in MergeRequest.find({ 'component': {'$in': product['components']}, 'source_branch': release['branch'], 'target_branch': 'master'})] release['features'] = [ f async for f in Feature.find( {'_id': {'$in': release['features']}}, ['name', 'status', 'components', 'create_time'])] components = {c['_id']: c async for c in Component.find( {}, ['name', 'repo', 'docker_repo', 'type'])} for feature in release['features']: feature['components'] = [ components[c_id] for c_id in feature['components']] return json(jsonify(release))
async def reserve_environment(request): assign_type = request.args.get('assign_type', 'ci') assign_id = request.args.get('assign_id', request.remote_addr) product_id = request.args.get('product_id', 'ci') duration = float(request.args.get('duration', 0)) if duration <= 0: raise InvalidUsage('duration should be > 0') env = await Environment.find_one_and_update( {'$or': [ {'status': Environment.IDLE}, {'assign_to.id': assign_id, 'assign_to.type': assign_type}]}, {'$set': { 'status': Environment.BUSY, 'assign_to': { 'type': assign_type, 'product': product_id, 'id': assign_id, 'expire_in': duration + get_timestamp()}, 'update_time': get_timestamp()}}, return_document=ReturnDocument.AFTER) if not env: raise NotFound('no idle environment') return json(jsonify({'_id': env['_id'], 'name': env['name'], 'ip': env['ip']}))
async def get_roles(request): roles = [record async for record in Permission.find({})] for record in roles: per_text = [per_dict[i] for i in record['permission']] record['permission'] = per_text return json(jsonify({ 'total': await Permission.count_documents({}), 'roles': roles}))
async def get_all_order(request): """获取用户所有订单""" user_id = request.json.get('id') orders = [record async for record in Order.find({})] return json( jsonify({ 'products': orders, 'total': await Product.count_documents({}) }))
async def post_order(request, user_id): """提交商品订单""" if not request.json: raise InvalidUsage('not json request!') product = request.json.get('product') num = request.json.get('num') user_id = user_id order = await Order.create(product, user_id, num) return json(jsonify({'id': order.inserted_id}))
async def update_product(request): """商品上下架""" if not request.json: raise InvalidUsage('not json request!') flag = request.json.get('flag') name = request.json.get('name') logging.info(flag) result = await Product.update_one({'name': name}, {'$set': {'flag': flag}}) logging.info(result) return json(jsonify({'_id': flag}))
async def post_product(request): """商品录入""" if not request.json: raise InvalidUsage('not json request!') name = request.json.get('name') stock = request.json.get('stock') price = request.json.get('price') label = request.json.get('label') product = await Product.create(name, stock, price, label) return json(jsonify({'id': product.inserted_id}))
async def new_task(request): if not request.json: raise InvalidUsage('not json request!') task_name = request.json.get('name') task_args = request.json.get('args') if not task_name: raise InvalidUsage('no name found!') trigger_by = request['session']['user']['username'] task = await Task.create(task_name, task_args, trigger_by) return json(jsonify({'id': task.inserted_id}))
async def add_label(request): """添加商品类型""" name = request.json.get('name') # await Label.delete_many({'name': name}) result = await Label.find_one({'name': name}) logging.info(result) logging.info(not result) if not result: await Label.create(name) return json(jsonify({'result': 'success'})) raise InvalidUsage('分类已存在')
async def get_all_products(request): """获取所有商品列表""" products = [record async for record in Product.find({})] for i in products: label = await Label.find_one({'_id': ObjectId(i.get('label', None))}) i.update({'label': label['name']}) return json( jsonify({ 'products': products, 'total': await Product.count_documents({}) }))
async def update_role(request): role = request.json.get('role') permission = request.json.get('permission') logging.info(f'----{role}更新权限:{permission}-------') try: result = await Permission.find_one_and_update({'role': role}, {'$set': {'permission': permission}}) return json(jsonify({'success': 1})) except Exception as e: logging.info(f'----{e}-----') raise ServerError('系统错误')
async def get_feature_detail(request, feature_id): feature = await Feature.find_one({'_id': ObjectId(feature_id)}) or {} if not feature: return json({}) product = await Product.find_one({'_id': feature['product']}, ['name', 'components']) if product: feature['product_name'] = product['name'] feature['components'] = [c async for c in Component.find( {'_id': {'$in': feature['components']}}, ['_id', 'name', 'repo', 'docker_repo'])] return json(jsonify(feature))
async def get_environments(request): filter_ = {} product = request.args.get('product') if product: filter_['assign_to.product'] = ObjectId(product) q_ = request.args.get('q') if q_: filter_['$or'] = [ {'name': {'$regex': '(?i)' + q_}}, {'ip': {'$regex': q_}}, {'label': {'$regex': '(?i)' + q_}}] if request.args.get('status'): filter_['status'] = {'$in': request.args.get('status').split(',')} return json(jsonify([e async for e in Environment.find(filter_)]))
async def get_products(request): async def _read_product_components(p): return [c async for c in Component.find( {'_id': {'$in': p['components']}})] async def _read_product_features(p): return { 'total': await Feature.count_documents( {'product': p['_id'], 'status': Feature.DONE})} async def _read_product_releases(p): last_release = await Release.find_one( {'product': p['_id'], 'status': Release.RELEASED}, sort=[('update_time', -1)]) if last_release: last_release['features'] = [ f async for f in Feature.find( {'_id': {'$in': last_release['features']}}, ['name'])] return { 'total': await Release.count_documents( {'product': p['_id'], 'status': Release.RELEASED}), 'last': last_release} async def _read_product_environments(p): return { 'total': await Environment.count_documents( {'assign_to.product': p['_id'], 'status': Environment.BUSY})} products = [] id_ = request.args.get('id') format_ = request.args.get('format') if id_: filter_ = {'_id': ObjectId(id_)} else: filter_ = {} q_ = request.args.get('q') if q_: filter_['name'] = {'$regex': '(?i)' + q_} async for p in Product.find(filter_): if format_ != 'simple': p['components'] = await _read_product_components(p) p['features'] = await _read_product_features(p) p['releases'] = await _read_product_releases(p) p['environments'] = await _read_product_environments(p) products.append(p) return json(jsonify(products))
async def new_product(request): name = request.json.get('name', '').strip() description = request.json.get('description', '').strip() components = [ObjectId(c) for c in request.json.get('components', [])] export_script = request.json.get('export_script', '').strip() deploy_script = request.json.get('deploy_script', '').strip() if not name: raise InvalidUsage('Product名称不能为空!') try: p = await Product.create(name, description, components, export_script, deploy_script) except DuplicateKeyError: raise InvalidUsage('同名Product已存在!') return json(jsonify({'id': p.inserted_id}))
async def new_feature(request): name = request.json.get('name', '').strip() description = request.json.get('description', '').strip() branch = request.json.get('branch', '').strip() product = ObjectId(request.json.get('product', '')) base_version = request.json.get('base_version') components = [ObjectId(c) for c in request.json.get('components', [])] if not name or not branch or not product or not components: raise InvalidUsage('参数错误!') try: f = await Feature.create(name, branch, product, base_version, components, [], description) except DuplicateKeyError: raise InvalidUsage('同名Feature已存在!') return json(jsonify({'id': f.inserted_id}))
async def new_component(request): name = request.json.get('name', '').strip() branch = request.json.get('master_name', '').strip() gitlab_project_id = request.json.get('gitlab_project_id') repo = request.json.get('repo', '').strip() type_ = request.json.get('type', Component.TYPE_APP) dependencies = [ObjectId(c) for c in request.json.get('dependencies', [])] _3rd = request.json.get('third_parties', []) if not name or not gitlab_project_id: raise InvalidUsage('模块名称和Project ID不能为空!') try: c = await Component.create(name, branch, gitlab_project_id, repo, type_, dependencies, _3rd) except DuplicateKeyError: raise InvalidUsage('同名模块已存在!') return json(jsonify({'id': c.inserted_id}))
async def update_product(request): """商品更新""" if not request.json: raise InvalidUsage('not json request!') name = request.json.get('name') stock = request.json.get('stock') price = request.json.get('price') label = request.json.get('label') product = await Product.update_one({'_id': id}, { '$set': { 'name': name, 'stock': stock, 'price': price, 'label': label } }) return json(jsonify({'id': product.inserted_id}))
async def get_user(request): result = [user async for user in AllUser.find({})] users = [] for record in result: role_id = record.get('user_label', 0) role = await Permission.find_one({'_id': role_id}) role_sum = reduce(lambda x, y: x + y, role['permission']) if role_sum == 3: user = { '_id': record.get('_id', None), 'username': record.get('user_name', '未命名'), 'phone': record.get('phone', ''), 'role': role.get('role', ''), 'sex': record.get('sex', 1) } users.append(user) return json(jsonify({'users': users, 'total': len(users)}))
async def add_role(request): """添加会员等级""" role = request.json.get('role') des = request.json.get('description') level = request.json.get('level') permission = request.json.get('permission', []) logging.info(f'------{role}的功能权限列表:{permission}------') result = await Permission.find_one({'role': role}) if not result: per = Permission() per.role = role per.description = des per.permission = permission per.order = 1 per.level = level await per.save() return json(jsonify({'success': 1})) return InvalidUsage('会员等级已存在')
async def get_tasks(request): skip = int(request.args.get('skip', 0)) limit = int(request.args.get('limit', 10)) q_ = request.args.get('q') if q_: f_ = {'$or': [ {'trigger_by': {'$regex': '(?i)' + q_}}, {'name': {'$regex': '(?i)' + q_}}, ]} total = await Task.count_documents(f_) else: f_ = {} total = await Task.estimated_document_count() tasks = [ task async for task in Task.find( f_, ['name', 'status', 'trigger_by', 'create_time', 'update_time'], sort=[('create_time', -1)], skip=skip, limit=limit)] return json(jsonify({'total': total, 'tasks': tasks}))
async def new_environment(request): name = request.json.get('name', '').strip() label = request.json.get('label', []) ip = request.json.get('ip', '').strip() user = request.json.get('user', '').strip() or SSH_USER password = request.json.get('password', '').strip() or SSH_PASSWORD description = request.json.get('description', '') assign_to = request.json.get('assign_to', {}) settings = request.json.get('settings', {}) if not name or not ip: raise InvalidUsage('name和ip必须设置!') try: e = await Environment.create( name, label, ip, user, password, description, assign_to, settings) except DuplicateKeyError: raise InvalidUsage('相同名字或IP的环境已存在!') return json(jsonify({'id': e.inserted_id}))
async def login(request): """登录""" user_name = request.json.get('username') psd = request.json.get('password') result = await AllUser.find_one({'user_name': user_name}) # 密码加密 if result: secret = hash_psd(psd) user_label = result.get('user_label', 0xff) role = await Permission.find_one({'_id': user_label}) if result['password'] == secret: logging.info(role.get('permission', 0xff)) return json( jsonify({ 'username': user_name, 'role': reduce(lambda x, y: x + y, role.get('permission', 0xff)) })) else: raise InvalidUsage('密码或用户名错误') raise InvalidUsage('用户不存在')
async def add_user(request): """管理员添加用户""" user_name = request.json.get('username') psd = request.json.get('phoneNum') sex = request.json.get('sex') role = request.json.get('role') try: result = await AllUser.find_one({'user_name': user_name}) if not result: secret = hash_psd(psd) logging.info(secret) user = AllUser() user.user_name = user_name user.phone = psd user.password = secret, user.sex = sex result = await user.save() logging.info(result) return json(jsonify({'success': '注册成功'})) else: raise InvalidUsage('用户已存在') except Exception as e: logging.info(e)
async def change_user(request): result = AllUser.find_one({}) return json(jsonify({'success': '成功'}))
async def logout(request): return json(jsonify({'statute': '成功登出'}))
async def get_releases(request): skip = int(request.args.get('skip', 0)) limit = int(request.args.get('limit', 3)) filter_ = {} product = request.args.get('product') if product: filter_['product'] = ObjectId(product) status = request.args.get('status') if status: filter_['status'] = {'$in': status.split(',')} ref = request.args.get('ref') if ref: filter_['$or'] = [{'branch': ref}, {'name': ref}] if request.args.get('format') == 'simple': # simple format return json(jsonify({ 'total': await Release.count_documents(filter_), 'releases': [ rel async for rel in Release.find( filter_, ['name', 'status', 'publish'], sort=[('update_time', -1)], skip=skip, limit=limit)]})) products = {p['_id']: p async for p in Product.find({}, ['name', 'components'])} features = {f['_id']: f async for f in Feature.find( {}, ['name', 'components'])} components = {c['_id']: c async for c in Component.find( {}, ['name', 'master_name', 'repository', 'repo', 'docker_repo', 'type', 'tags'])} def _get_release_product(rel): p_id = rel['product'] return { '_id': p_id, 'name': products[p_id]['name'], 'components': [components[c_id] for c_id in products[p_id]['components']] } def _get_release_features(rel): return [{ '_id': f_id, 'name': features[f_id]['name'], 'components': [components[c_id] for c_id in features[f_id]['components']] } for f_id in rel['features']] async def _get_release_merge_requests(rel): components = itertools.chain.from_iterable([f['components'] for f in rel['features']]) return [mr async for mr in MergeRequest.find({ 'component': {'$in': [c['_id'] for c in components]}, 'source_branch': rel['branch'], 'state': {'$ne': 'closed'}})] releases = [] async for rel in Release.find(filter_, sort=[('update_time', -1)], skip=skip, limit=limit): rel['features'] = _get_release_features(rel) rel['product'] = _get_release_product(rel) rel['merge_requests'] = await _get_release_merge_requests(rel) releases.append(rel) return json(jsonify({ 'total': await Release.count_documents(filter_), 'releases': releases}))