Пример #1
0
def server_index():
    req = request.values
    kw = req.get("kw", "").strip()
    page = int(req.get("p", 1))

    query = JobServer.query
    if kw:
        query = query.filter(JobServer.name.ilike('%{}%'.format(kw)))

    page_params = {
        "total": query.count(),
        "page_size": CommonConstant.PAGE_SIZE,
        "page": page,
        "display": CommonConstant.PAGE_DISPLAY
    }

    pages = UtilHelper.iPagination(page_params)
    offset = (page - 1) * CommonConstant.PAGE_SIZE
    limit = CommonConstant.PAGE_SIZE * page
    list = query.order_by(JobServer.id.desc())[offset:limit]

    data = []
    server_env_map = CommonConstant.server_env_map
    if list:
        for item in list:
            tmp_data = ModelHelper.model2Dict(item)
            tmp_env_ids = (item.env).strip(
                CommonConstant.special_strike).split(
                    CommonConstant.special_strike)
            tmp_env_list = []
            for _env_id in tmp_env_ids:
                if int(_env_id) not in server_env_map.keys():
                    continue
                tmp_env_list.append(server_env_map.get(int(_env_id)))

            tmp_data['env'] = ",".join(tmp_env_list)
            data.append(tmp_data)

    sc = {'kw': kw}

    set_flag = RBACService.checkPageRelatePrivilege("set")
    ops_flag = RBACService.checkPageRelatePrivilege("ops")

    return UtilHelper.renderView(
        "home/job/server/index.html", {
            "list": data,
            "pages": pages,
            "server_env_map": CommonConstant.server_env_map,
            "sc": sc,
            "set_flag": set_flag,
            "ops_flag": ops_flag
        })
Пример #2
0
def tools_alert():
    req = request.values
    page = int(req.get("p", 1))
    date_from = req.get("date_from", DateHelper.getCurrentTime(fmt="%Y-%m-%d"))
    date_to = req.get("date_to", DateHelper.getCurrentTime(fmt="%Y-%m-%d"))
    status = int(req.get("status", CommonConstant.default_status_neg_99))

    query = JobAlertList.query.filter(
        JobAlertList.created_time.between(date_from, date_to + " 23:59:59"))
    if status > CommonConstant.default_status_neg_99:
        query = query.filter_by(status=status)

    page_params = {
        "total": query.count(),
        "page_size": CommonConstant.PAGE_SIZE,
        "page": page,
        "display": CommonConstant.PAGE_DISPLAY,
    }

    pages = UtilHelper.iPagination(page_params)
    offset = (page - 1) * CommonConstant.PAGE_SIZE
    limit = CommonConstant.PAGE_SIZE * page
    list = query.order_by(JobAlertList.id.desc())[offset:limit]
    data = []
    if list:
        job_ids = ModelHelper.getFieldList(list, "job_id")
        job_map = ModelHelper.getDictFilterField(JobList,
                                                 select_field=JobList.id,
                                                 id_list=job_ids.sort())
        for item in list:
            tmp_data = ModelHelper.model2Dict(item)
            tmp_job_info = ModelHelper.model2Dict(
                job_map.get(tmp_data['job_id']))
            tmp_data['status_desc'] = CommonConstant.common_status_map4[
                tmp_data['status']]
            tmp_data['job_name'] = tmp_job_info['name']

            data.append(tmp_data)

    sc = {'date_from': date_from, 'date_to': date_to, 'status': status}

    return UtilHelper.renderView(
        "home/job/tools/alert.html", {
            "list": data,
            "pages": pages,
            "sc": sc,
            "status_map": CommonConstant.common_status_map4,
            "current": "alert"
        })
Пример #3
0
def news_ops():
    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    if not id:
        return UtilHelper.renderErrJSON( CommonConstant.SYSTEM_DEFAULT_ERROR )


    info = UserNews.query.filter_by( id = id,uid = CurrentUserService.getUid() ).first()
    if not info:
        return UtilHelper.renderErrJSON( "指定站内信不存在" )

    info.status = CommonConstant.default_status_true
    db.session.add( info )
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #4
0
def home_release():
    release_list = [
        {
            "title": "V1.3 上线",
            "date": "2020-11-01",
            "content": "监控常驻job内存消耗<br/>强制杀死job"
        },
        {
            "title": "V1.2 上线",
            "date": "2020-10-20",
            "content": "增加常驻Job<br/>核心调度Job日志使用logrotate管理"
        },
        {
            "title": "V1.1 上线",
            "date": "2020-10-14",
            "content": "增加Job分类管理,每个Job需要所属组<br/>增加钉钉和企业微信报警配置"
        },
        {
            "title": "V1.0 上线",
            "date": "2020-10-03",
            "content": "Job管理调度平台 正式上线<br/>服务器管理、Job管理、Job工具、异常监控"
        },
        {
            "title": "V0.1",
            "date": "2020-09-22",
            "content": "基础功能(员工管理、RBAC、日志管理、站内信、网址之家等)基于个人开源Python3 CMS,<a target='_blank' href='http://dcenter.jixuejima.cn/#/flask/v2/readme'>详情点击了解</a>"
        }
    ]
    return UtilHelper.renderView("home/index/release.html",{
        "list" : release_list,
        "count" : len( release_list )
    })
Пример #5
0
def dept_index():
    dept_list = Role.query.order_by(Role.pid.asc()).all()
    list = []
    if dept_list:
        dept_data = {}
        for item in dept_list:
            if not item.pid and item.id not in dept_data:
                dept_data[item.id] = {
                    "self": item,
                    "sub": []
                }

            if item.pid:
                dept_data[item.pid]['sub'].append( item )

        for item in dept_data.values():
            list.append( item['self'] )
            list.extend( item['sub'])

    set_flag = RBACService.checkPageRelatePrivilege("set")
    ops_flag = RBACService.checkPageRelatePrivilege("ops")

    return UtilHelper.renderView("home/rbac/dept/index.html", {
        "list": list,
        "set_flag": set_flag,
        "ops_flag": ops_flag,
    }  )
Пример #6
0
def home_index():
    date = DateHelper.getCurrentTime(fmt="%Y-%m-%d")
    job_count = JobList.query.filter_by(is_del=CommonConstant.default_status_false).count()
    server_count = JobServer.query.filter_by(status=CommonConstant.default_status_true).count()
    alert_count = JobAlertList.query.filter(JobAlertList.created_time.between(date, date + " 23:59:59")).count()

    cate_map = ModelHelper.getDictFilterField( JobCategory )
    cat_job_map = {}
    cat_job_list = JobList.query.with_entities(JobList.cate_id ,func.count( JobList.id) )\
        .filter_by(is_del=CommonConstant.default_status_false)\
        .group_by(JobList.cate_id).all()
    if cat_job_list:
        for _item in cat_job_list:
            cat_job_map[ _item[0] ] = _item[1]

    type_job_map = {}
    job_type_map = CommonConstant.job_type_map
    type_job_list = JobList.query.with_entities(JobList.job_type, func.count(JobList.id)) \
        .filter_by(is_del=CommonConstant.default_status_false) \
        .group_by(JobList.job_type).all()
    if type_job_list:
        for _item in type_job_list:
            type_job_map[ _item[0] ] = _item[1]

    return UtilHelper.renderView("home/index/index.html", {
        "job_count": job_count,
        "server_count": server_count,
        "alert_count": alert_count,
        'cate_map' : cate_map,
        'cat_job_map' : cat_job_map,
        'job_type_map' : job_type_map,
        'type_job_map' : type_job_map,
    })
Пример #7
0
def tools_index():
    list = JobList.query.filter_by(
        run_status=CommonConstant.default_status_pos_2).order_by(
            JobList.id.desc()).all()
    return UtilHelper.renderView("home/job/tools/index.html", {
        "list": list,
        "current": "index"
    })
Пример #8
0
def job_info():
    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    info = JobList.query.filter_by(id=id).first()
    if not info:
        return redirect(GlobalUrlService.buildHomeUrl("/job/index/index"))

    info = ModelHelper.model2Dict(info)

    server_info = JobServer.query.filter_by(id=info['server_id']).first()
    cate_info = JobCategory.query.filter_by(id=info['cate_id']).first()
    server_env_map = CommonConstant.server_env_map
    run_status_map = CommonConstant.run_status_map

    info['next_run_time'] = DateHelper.getDateOnTimestamps(
        info['next_run_time'], '%Y-%m-%d %H:%M')
    info['env_name'] = server_env_map.get(info['env_id'])
    info['run_status_desc'] = run_status_map.get(info['run_status'])
    info['job_status_desc'] = job_status_map.get(info['status'])
    info['server_name'] = server_info.name
    info['cate_name'] = cate_info.name if cate_info else ''
    info['run_interval_desc'] = DateHelper.formatBeautyTime(
        info['run_interval'] * 60)

    user_map = ModelHelper.getDictFilterField(
        User,
        select_field=User.id,
        id_list=[info['owner_uid'], info['relate_uid']])

    ##获取最近5天运行记录
    log_list = JobRunLog.query.filter_by(job_id=id).order_by(
        JobRunLog.id.desc())[0:5]
    log_data = []
    if log_list:
        for item in log_list:
            tmp_data = ModelHelper.model2Dict(item)
            tmp_data['status_desc'] = CommonConstant.job_log_status_map[
                tmp_data['status']]
            tmp_data['duration'] = ""
            if DateHelper.getCurrentTime(date=tmp_data['end_time']
                                         ) == CommonConstant.DEFAULT_DATETIME:
                tmp_data['end_time'] = "未知"
                tmp_data['duration'] = time.time() - time.mktime(
                    tmp_data['start_time'].timetuple())
            else:
                tmp_data['duration'] = tmp_data['end_time'].timestamp(
                ) - tmp_data['start_time'].timestamp()
            tmp_data['duration'] = DateHelper.formatBeautyTime(
                tmp_data['duration'])
            log_data.append(tmp_data)

    return UtilHelper.renderView(
        "home/job/index/info.html", {
            "info": info,
            "log_list": log_data,
            "user_map": user_map,
            "job_level_map": CommonConstant.job_level_map,
        })
Пример #9
0
def staff_set():
    if UtilHelper.isGet() :
        req = request.values
        id = int( req['id'] ) if ( 'id' in req and req['id'] )else 0
        info = None
        if id > 0:
            info = User.query.filter_by( id=id ).first()

        ##部门
        dept_list = Role.query.order_by( Role.pid.asc() ).all()
        dept_data = {}
        if dept_list:
            for item in dept_list:
                if not item.pid  and item.id not in dept_data:
                    dept_data[ item.id ] = {
                        "name": item.name,
                        "sub" : []
                    }

                if item.pid:
                    dept_data[item.pid]['sub'].append( { "id":item.id,"name": item.name } )


        return UtilHelper.renderPopView( "home/rbac/staff/set.html",{ "info":info,"dept_list":dept_data }  )

    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    name = req.get("name","").strip()
    email = req.get("email","").strip()
    role_id = int( req.get("role_id",0 ) )


    if not ValidateHelper.validLength( name,1,10 ):
        return UtilHelper.renderErrJSON("请输入符合规范的姓名~~")

    if not ValidateHelper.validEMail( email ):
        return UtilHelper.renderErrJSON("请输入符合规范的邮箱~~")

    if role_id < 1:
        return UtilHelper.renderErrJSON("请选择部门(顶级部门不可选择)~~")

    has_in = User.query.filter(User.email == email, User.id != id).first()
    if has_in:
        return UtilHelper.renderErrJSON("该邮箱已存在,请换一个再试~~")

    info = User.query.filter_by(id=id).first()
    if info:
        model_user = info
    else:
        model_user = User()

    if not model_user.salt:
        model_user.salt = CurrentUserService.geneSalt()

    model_user.name = name
    model_user.email = email
    model_user.role_id = role_id
    db.session.add( model_user )
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #10
0
def set_info():
    if UtilHelper.isGet():
        return UtilHelper.renderPopView("home/user/profile/set_info.html", {"info": CurrentUserService.getInfo() })
    req = request.values
    name = req.get("name", "").strip()
    email = req.get("email", "").strip()
    if not ValidateHelper.validLength(name, 1, 10):
        return UtilHelper.renderErrJSON("请输入符合规范的姓名~~")

    if not ValidateHelper.validEMail(email):
        return UtilHelper.renderErrJSON("请输入符合规范的邮箱~~")

    info = CurrentUserService.getInfo()
    if not info:
        return UtilHelper.renderErrJSON( CommonConstant.SYSTEM_DEFAULT_ERROR )

    has_in = User.query.filter(User.email == email, User.id != info.id ).first()
    if has_in:
        return UtilHelper.renderErrJSON("该邮箱已存在,请换一个再试~~")

    info.name = name
    info.email = email
    db.session.add(info)
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #11
0
def home_news():
    query = UserNews.query.filter_by(uid=CurrentUserService.getUid(), status=CommonConstant.default_status_false)
    total = query.count()
    list = query.order_by(UserNews.id.desc()).all()
    data = []
    if list:
        for item in list:
            tmp_content = "<h5 class='text-danger'>标题:%s</h5><br/>%s<br/>时间:%s" % (
            item.title, item.content, item.created_time)
            tmp_data = {
                "id": item.id,
                "title": item.title,
                "content": tmp_content,
                "created_time": DateHelper.getFormatDate(DateHelper.str2Date(item.created_time), format="%m-%d %H:%M"),
            }
            data.append(tmp_data)
    content = UtilHelper.renderView("home/index/news.html", {"list": data, "total": total})
    return UtilHelper.renderSucJSON({"total": total, "content": content})
Пример #12
0
def Login():
    if request.method == "GET":
        if g.current_user:
            return redirect(GlobalUrlService.buildHomeUrl("/"))
        return UtilHelper.renderView("home/user/login_2.html")

    resp = {'code': 200, 'msg': '操作成功~~', 'data': {}}
    req = request.values
    email = req['email'] if 'email' in req else ''
    pwd = req['pwd'] if 'pwd' in req else ''

    if email is None or len(email) < 1:
        resp['code'] = -1
        resp['msg'] = "请输入正确的邮箱~~"
        return jsonify(resp)

    if pwd is None or len(pwd) < 1:
        resp['code'] = -1
        resp['msg'] = "请输入正确的邮箱密码~~"
        return jsonify(resp)

    user_info = User.query.filter_by(
        email=email, status=CommonConstant.default_status_true).first()
    if not user_info:
        resp['code'] = -1
        resp['msg'] = "你好,未注册的邮箱,请找系统管理员先注册用户~~"
        return jsonify(resp)

    try:
        at_idx = email.index("@")
        smtp_obj = smtplib.SMTP_SSL("smtp." + email[(at_idx + 1):], 465)
        smtp_obj.set_debuglevel(1)
        smtp_obj.login(email, pwd)
        smtp_obj.close()
    except Exception:
        resp['code'] = -1
        resp['msg'] = "登录失败,请核对邮箱和密码是否对应~~"
        return jsonify(resp)
    next_url = GlobalUrlService.buildHomeUrl("/")

    response = make_response(
        json.dumps({
            'code': 200,
            'msg': '登录成功~~',
            'data': {
                "next_url": next_url
            }
        }))
    response.set_cookie(
        CommonConstant.AUTH_COOKIE_NAME,
        '%s#%s' % (CurrentUserService.userAuthToken(user_info), user_info.id),
        60 * 60 * 24 * 120)  # 保存120天
    return response
Пример #13
0
def dept_set():
    if UtilHelper.isGet() :
        req = request.values
        id = int( req['id'] ) if ( 'id' in req and req['id'] )else 0
        info = None
        query_role_list = Role.query.filter_by( pid = CommonConstant.default_status_false )
        if id > 0:
            info = Role.query.filter_by( id=id ).first()
            query_role_list = query_role_list.filter( Role.id != id )

        role_list = query_role_list.order_by( Role.id.desc() ).all()

        return UtilHelper.renderPopView( "home/rbac/dept/set.html",{ "info":info ,"role_list": role_list}  )

    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    name = req.get("name","").strip()
    pid = int( req.get("pid","0").strip() )


    if not ValidateHelper.validLength( name,1,10 ):
        return UtilHelper.renderErrJSON("请输入符合规范的姓名~~")

    info = Role.query.filter_by(id=id).first()
    if info:
        model_role = info
        #还不能选择自己的子节点

        if id == pid:
            return UtilHelper.renderErrJSON("不能勾选自己为所属部门哦~~")
    else:
        model_role = Role()

    model_role.name = name
    model_role.pid = pid
    db.session.add( model_role )
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #14
0
def grant_ops():
    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    act = req.get("act", "").strip()
    allow_act = ['del', 'recovery']
    if not id:
        return UtilHelper.renderErrJSON(CommonConstant.SYSTEM_DEFAULT_ERROR)

    if act not in allow_act:
        return UtilHelper.renderErrJSON(CommonConstant.SYSTEM_DEFAULT_ERROR)

    info = Action.query.filter_by(id=id).first()
    if not info:
        return UtilHelper.renderErrJSON("指定权限不存在")

    if act == "del":
        info.status = CommonConstant.default_status_false
    elif act == "recovery":
        info.status = CommonConstant.default_status_true

    db.session.add(info)
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #15
0
def staff_index():
    req = request.values
    kw = req.get("kw", "").strip()
    page = int(req.get("p", 1))

    query = User.query
    if kw:
        query = query.filter( or_( User.name.ilike( '%{}%'.format(kw) ) ,User.email.ilike( '%{}%'.format(kw) ) ))

    page_params = {
        "total": query.count(),
        "page_size": CommonConstant.PAGE_SIZE,
        "page": page,
        "display": CommonConstant.PAGE_DISPLAY,
    }

    pages = UtilHelper.iPagination(page_params)
    offset = (page - 1) * CommonConstant.PAGE_SIZE
    limit = CommonConstant.PAGE_SIZE * page
    list = query.order_by( User.id.desc() )[offset:limit]

    dept_map = ModelHelper.getDictFilterField( Role )
    sc = {
        'kw': kw
    }

    set_flag = RBACService.checkPageRelatePrivilege("set")
    ops_flag = RBACService.checkPageRelatePrivilege("ops")

    return UtilHelper.renderView( "home/rbac/staff/index.html",   {
        "list": list,
        "pages": pages,
        "dept_map" : dept_map,
        "sc": sc,
        "set_flag": set_flag,
        "ops_flag": ops_flag,
    })
Пример #16
0
def before_request():
    ignore_urls = app.config['IGNORE_URLS_HOME']
    ignore_check_login_urls = app.config['IGNORE_CHECK_LOGIN_URLS']
    path = request.path
    #如果是静态文件就不要查询用户信息了
    pattern = re.compile('%s' % "|".join(ignore_check_login_urls))
    if pattern.match(path) or "/home" not in path:
        return

    # 多查询一次数据也没有什么问题
    user_info = check_login()
    g.current_user = None
    if user_info:
        g.current_user = user_info

    #将忽略数组换成字符串
    pattern = re.compile('%s' % "|".join(ignore_urls))
    if pattern.match(path):
        return

    if not user_info:
        response = make_response(
            redirect(GlobalUrlService.buildHomeUrl("/user/logout")))
        return response

    #判断RBAC的权限
    if not RBACService.checkPrivilege(path):
        if UtilHelper.isAjax():
            return UtilHelper.renderErrJSON("无权限,请联系管理员")
        response = make_response(
            redirect(GlobalUrlService.buildHomeUrl("/error/ban",
                                                   {"msg": path})))
        return response

    g.menus = MenuServiceService.getMenu()
    AppLogService.addAccessLog(user_info)
    return
Пример #17
0
def grant_set():
    if UtilHelper.isGet():
        req = request.values
        id = int(req['id']) if ('id' in req and req['id']) else 0
        act = req.get("act", "").strip()
        info = None
        if id > 0:
            info = Action.query.filter_by(id=id).first()

        weight_list = [1]
        weight_list.extend(range(5, 80, 5))

        if act == "copy" and info:
            info.id = 0
        return UtilHelper.renderPopView("home/rbac/grant/set.html", {
            "info": info,
            "weight_list": weight_list,
        })

    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    level1_name = req.get("level1_name", "").strip()
    level2_name = req.get("level2_name", "").strip()
    name = req.get("name", "").strip()
    url = req.get("url", "").strip()
    level1_weight = int(req.get("level1_weight", "1").strip())
    level2_weight = int(req.get("level2_weight", "1").strip())
    weight = int(req.get("weight", "1").strip())

    if not ValidateHelper.validLength(level1_name, 1, 20):
        return UtilHelper.renderErrJSON("请输入符合规范的一级菜单名称~~")

    if not ValidateHelper.validLength(level2_name, 1, 20):
        return UtilHelper.renderErrJSON("请输入符合规范的二级菜单名称~~")

    if not ValidateHelper.validLength(name, 1, 20):
        return UtilHelper.renderErrJSON("请输入符合规范的权限名称~~")

    info = Action.query.filter_by(id=id).first()
    if info:
        model_action = info
    else:
        model_action = Action()

    model_action.level1_name = level1_name
    model_action.level2_name = level2_name
    model_action.name = name
    model_action.url = url.replace("\r\n", ",")
    model_action.level1_weight = level1_weight
    model_action.level2_weight = level2_weight
    model_action.weight = weight

    db.session.add(model_action)
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #18
0
    def residentProcess(self, item_model):
        if item_model['job_type'] != CommonConstant.default_status_pos_2:
            return False

        job_id = item_model['id']
        pid_file = self.getPidPath('job_%s.pid' % job_id)
        pid = 0
        if self.checkPidExist(pid_file):
            pid = self.findPidByKw(job_id)

        info = JobRunLog.query.filter_by( job_id = job_id ,status = CommonConstant.default_status_neg_1 )\
            .order_by( JobRunLog.id.desc() ).limit(1).first()
        if info:
            job_used_mem = UtilHelper.getUsedMemory(pid)
            info.max_mem = job_used_mem
            db.session.add(info)
            db.session.commit()

        return True
Пример #19
0
def link_set():
    if UtilHelper.isGet():
        req = request.values
        id = int(req['id']) if ('id' in req and req['id']) else 0
        info = None
        if id > 0:
            info = Link.query.filter_by(id=id).first()
        return UtilHelper.renderPopView(
            "home/link/set.html", {
                "info": info,
                "type_map": CommonConstant.link_type_map
            })

    req = request.values
    id = int(req['id']) if ('id' in req and req['id']) else 0
    type = int(req.get("type", 0).strip())
    title = req.get("title", "").strip()
    url = req.get("url", "").strip()
    weight = int(req.get("weight", 1).strip())

    if type < 1:
        return UtilHelper.renderErrJSON("请选择分类~~")

    if not ValidateHelper.validLength(title, 1, 30):
        return UtilHelper.renderErrJSON("请输入符合规范的标题~~")

    if not ValidateHelper.validUrl(url):
        return UtilHelper.renderErrJSON("请输入符合规范的网址~~")

    info = Link.query.filter_by(id=id).first()
    if info:
        model_link = info
    else:
        model_link = Link()

    model_link.type = type
    model_link.title = title
    model_link.url = url
    model_link.weight = weight
    db.session.add(model_link)
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #20
0
def home_index():
    return UtilHelper.renderView("home/index/index.html")
Пример #21
0
def grant_assign():
    if UtilHelper.isGet():
        req = request.values
        role_id = int(req.get("role_id", 0))
        role_pid = int(req.get("role_pid", 0))
        '''
        取出来所有的一级部门
        '''
        p_role_list = Role.query.filter_by(pid=CommonConstant.default_status_false)\
            .order_by( Role.id.asc() ).all()

        if not role_pid and p_role_list:  #如果没有父部门,那就选择一个
            role_pid = p_role_list[0].id

        sub_role_list = Role.query.filter_by( pid = role_pid)\
            .order_by( Role.id.asc() ).all()

        if not role_id and sub_role_list:
            role_id = sub_role_list[0].id

        user_list = User.query.filter_by(
            status=CommonConstant.default_status_true, role_id=role_id).all()

        action_list = Action.query.filter_by( status = CommonConstant.default_status_true )\
            .order_by( Action.level1_weight.desc(),Action.level2_weight.desc(),Action.weight.desc() ).all()

        action_data = {}
        if action_list:
            for item in action_list:
                tmp_level1_key = item.level1_name
                tmp_level2_key = item.level2_name
                if tmp_level1_key not in action_data:
                    action_data[tmp_level1_key] = {
                        "name": tmp_level1_key,
                        "counter": 0,
                        "sub": {}
                    }

                if tmp_level2_key not in action_data[tmp_level1_key]['sub']:
                    action_data[tmp_level1_key]['sub'][tmp_level2_key] = {
                        "name": tmp_level2_key,
                        "counter": 0,
                        "act_list": []
                    }

                action_data[tmp_level1_key]['counter'] += 1
                action_data[tmp_level1_key]['sub'][tmp_level2_key][
                    'counter'] += 1

                tmp_data = {
                    "id": item.id,
                    "name": item.name,
                    "is_important": item.is_important
                }
                action_data[tmp_level1_key]['sub'][tmp_level2_key][
                    'act_list'].append(tmp_data)

        owned_act = RoleAction.query.filter_by(
            role_id=role_id, status=CommonConstant.default_status_true).all()
        owned_act_ids = ModelHelper.getFieldList(owned_act, 'action_id')

        sc = {
            "role_id": role_id,
            "role_pid": role_pid,
        }

        return UtilHelper.renderView(
            "home/rbac/grant/assign.html", {
                "list": action_data,
                "p_role_list": p_role_list,
                "sub_role_list": sub_role_list,
                "user_list": user_list,
                "owned_act_ids": owned_act_ids,
                "sc": sc
            })

    req = request.values
    role_id = int(req.get("role_id", 0))
    action_ids = request.form.getlist("action_ids[]")
    action_ids = list(map(int, action_ids))
    if not role_id or role_id < 1:
        return UtilHelper.renderErrJSON("请选择部门在分配权限~~")

    info = Role.query.filter_by(id=role_id).first()
    if not info:
        return UtilHelper.renderErrJSON("请选择部门在分配权限 -2~~")
    ###分配权限逻辑还是挺复杂的
    ## 已有的权限
    owned_act = RoleAction.query.filter_by(role_id=role_id).all()
    owned_act_ids = ModelHelper.getFieldList(owned_act, 'action_id')
    '''
    找出删除的权限(生产环境数据库没有删除权限)
    假如已有的权限集合是A,界面传递过得权限集合是B
    权限集合A当中的某个权限不在权限集合B当中,就应该删除
    计算差集
    '''
    delete_act_ids = list(set(owned_act_ids) - set(action_ids))
    if delete_act_ids:
        RoleAction.query.filter( RoleAction.role_id == role_id,RoleAction.action_id.in_( delete_act_ids ) )\
            .update({ "status":CommonConstant.default_status_false },synchronize_session = False)
        db.session.commit()
    '''
    找出添加的权限
    假如已有的权限集合是A,界面传递过得权限集合是B
    权限集合B当中的某个权限不在权限集合A当中,就应该添加
    计算差集
    '''
    add_act_ids = list(set(action_ids) - set(owned_act_ids))
    if add_act_ids:
        for _action_id in add_act_ids:
            _model_role_action = RoleAction()
            _model_role_action.role_id = role_id
            _model_role_action.action_id = _action_id
            db.session.add(_model_role_action)
        db.session.commit()
    '''
    找出需要更新的权限(生产环境数据库没有删除权限)
    假如已有的权限集合是A,界面传递过得权限集合是B
    权限集合B当中的某个权限也在在权限集合A当中,就应该更新
    计算补集
    '''
    update_act_ids = list(set(owned_act_ids).intersection(set(action_ids)))
    if update_act_ids:
        RoleAction.query.filter(RoleAction.role_id == role_id, RoleAction.action_id.in_(update_act_ids)) \
            .update({"status": CommonConstant.default_status_true}, synchronize_session=False)
        db.session.commit()

    return UtilHelper.renderSucJSON({}, "权限分配成功~~")
Пример #22
0
def news_batch_ops():
    UserNews.query.filter_by( uid = CurrentUserService.getUid() ).update({"status": CommonConstant.default_status_true })
    db.session.commit()
    return UtilHelper.renderSucJSON()
Пример #23
0
    def run(self, params):
        pid_path = self.getPidPath('dispatch.pid')
        if self.checkPidExist(pid_path):
            app.logger.info("[core] dispatch is running")
            return False

        pid = str(os.getpid())
        if not self.setPidFile(pid_path, pid):
            err_msg = self.getErrMsg()
            app.logger.info("Cann't get a lock file,err msg : " + err_msg)
            return False


        params = self.getEnvFile()
        server_id = params['id']
        host = params['name']
        list = JobList.query.filter_by( server_id = server_id,status = CommonConstant.default_status_true,
                                        run_status = CommonConstant.default_status_true,is_del = CommonConstant.default_status_false ).all()

        if not list:
            app.logger.info("没有数据需要调度~~")
            return True

        for t in list:

            ##调度时间是否到了,应该加入到SQL查询中查询
            if t.next_run_time >= time.time():
                app.logger.info( "job_id:%s,运行时间未到"%( t.id ) )
                continue

            # 启子进程中运行
            app.logger.info( "get a task: job_id:%s,运行时间:%s" % (t.id,DateHelper.getCurrentTime()) )
            '''
            子进程复制一份父进程内存给自己,两个进程之间的执行是相互独立的,其执行顺序可以是不确定的、随机的、不可预测的
            多进程(os.fork())下,子进程会继承父进程的连接,所以会有问题.先销毁已有的engine,确保父进程没有数据库连接
            相关错误:Mysql server has gone away
            '''
            self.closePoolDB()

            pid = os.fork()
            if pid == 0: #子进程,这里是一个独立进程(在复制出来的那一刻 所有变量都会共享到子进程),所以写代码 就要感觉在一个独立方法中
                self.closePoolDB()
                job_id = t.id
                job_pid_file = self.getPidPath( 'job_%s.pid' % job_id )
                if self.checkPidExist(job_pid_file):
                    app.logger.info("job_id:%s is running on  %s" % (job_id, host))
                    return 0

                ## 建立具体job的pid 文件,防止重复运行,这个进程id其实记录的是不对的,应该使用下面的
                tmp_pid = str(os.getpid())
                if not self.setPidFile(job_pid_file, tmp_pid):
                    app.logger.info("job_id:%s 不能建立pid,path:%s,msg:%s" % (job_id, job_pid_file, self.getErrMsg()))
                    return True

                app.logger.info("job_id:%s 建立pid,子进程pid:%s" % (job_id, tmp_pid))


                ## 更新job为运行中
                try:
                    tmp_affect_rows = JobList.query.filter_by( id = job_id,run_status = CommonConstant.default_status_true )\
                        .update( dict( run_status = CommonConstant.default_status_pos_2 ) )
                    db.session.commit()
                    if tmp_affect_rows < 1:
                        app.logger.info("job_id:%s不能得到lock,任务已经运行中" % job_id)
                        return False
                except:
                    app.logger.info( "job_id:%s不能得到锁状态,err:%s" % (job_id,str( sys.exc_info() ) ) )

                ##写入一条调度日志
                tmp_log_id = 0
                try:
                    tmp_log_params = {
                        "job_id":job_id,
                        "server_id":server_id,
                        "server_name":host,
                        "status": CommonConstant.default_status_neg_1,
                        "start_time":DateHelper.getCurrentTime()
                    }
                    tmp_log_id = JobService.addRunLog( tmp_log_params )
                except :
                    pass

                self.closePoolDB()

                tmp_job_run_start_time = time.time()  # job开始运行的时间
                # t.command无法获取job内部输出的内容,我们需要按行读取或者按buffer读取的
                # status = os.system(t.command)>>8#status, output = commands.getstatusoutput(t.command)
                # 可以加 bufsize = -1 表示使用系统默认缓存
                # 命令前面加一下前缀,方便搜索关键词查找
                # 创建子进程后子进程不结束 https://bbs.csdn.net/topics/390596479?_=1515055076
                tmp_command = t.command
                tmp_command = "tmp_job_%s='%s' && %s"%( job_id,DateHelper.getCurrentTime(),tmp_command)
                #如果想要达到2>&1 可以设置为stdout=subprocess.PIPE,stderr=subprocess.STDOUT
                sp = subprocess.Popen(tmp_command, bufsize = -1, shell = True, close_fds=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT)

                tmp_run_job_pid = sp.pid

                #上面存的关于job的进程id 是不对的,这里在覆盖一次
                self.coverPidFile(job_pid_file,tmp_run_job_pid)
                '''
                    如果是包裹了一层runshell的需要找到进程的子进程pid,然后在查看内存
                    tmp_pid 是目前子进程的进程号
                    tmp_run_job_pid 是目前 subprocess启动的进程好
                    真真运行的进程号,需要通过关键词查询,所以在命令前面加了特别东西
                '''
                app.logger.info( "job_id:%s 启动Job脚本,pid:%s" % (job_id, tmp_run_job_pid))

                ##统计内存占用量
                tmp_max_job_used_mem = tmp_job_used_mem = UtilHelper.getUsedMemory( tmp_run_job_pid )
                app.logger.info("job_id:%s 日志start-------" %job_id )
                '''
                sp.poll() 返回值
                0 正常结束
                1 sleep
                2 子进程不存在
                -15 kill
                None 在运行
                判断进程状态
                '''
                while sp.poll() is None:
                    ##统计内存占用量
                    tmp_job_used_mem = UtilHelper.getUsedMemory( tmp_run_job_pid )
                    if tmp_job_used_mem > tmp_max_job_used_mem:
                        tmp_max_job_used_mem = tmp_job_used_mem

                    tmp_line_output = sp.stdout.readline()
                    tmp_line_output = tmp_line_output.strip()
                    #返回的是bytes
                    tmp_line_output = str(tmp_line_output, encoding="utf8")

                    tmp_lines = tmp_line_output.split("\n")
                    for tmp_line in tmp_lines:
                        app.logger.info("job_id:%s %s" % (job_id, tmp_line) )

                app.logger.info("job_id:%s 日志end-------" % job_id)
                ##统计内存占用量
                tmp_job_used_mem = UtilHelper.getUsedMemory( tmp_run_job_pid )
                if tmp_job_used_mem > tmp_max_job_used_mem:
                    tmp_max_job_used_mem = tmp_job_used_mem

                app.logger.info("job_id:%s PID:%s, 使用内存(end) %s" % (job_id, tmp_run_job_pid, tmp_job_used_mem))
                app.logger.info("job_id:%s PID:%s, 最大使用内存 %s" % (job_id, tmp_run_job_pid, tmp_max_job_used_mem))
                app.logger.info("job_id:%s 更新消耗内存完毕" % (job_id))

                # 将标准输出关闭了
                sp.stdout.close()
                tmp_status = sp.wait()
                app.logger.info("job_id:%s status_code:%s,%s" % (t.id, str(tmp_status),tmp_command ))


                #和下面分开就是怕报警影响正常处理
                try:
                    #杀死常驻job也会发生 MySQL server has gone away,只要运行的时间太长就会出问题了
                    self.closePoolDB()
                    #相关报警判断
                    self.alertStatusJudge(t, tmp_status)
                    self.alertRunTimeJudge(t, tmp_job_run_start_time)
                except:
                    app.logger.info( self.getErrMsg() )


                # 更新状态和下一次运行时间
                try:
                    self.closePoolDB()
                    ##提前将文件释放下,因为当服务器状态非常繁忙的时候,进程比较缓慢,会导致状态已经更新但是pid文件没有删除
                    self.atexit_removepid(job_pid_file)
                    if int( t.job_type ) == CommonConstant.default_status_pos_3 :#一次性job
                        JobList.query.filter_by(id=job_id).update( dict( run_status = CommonConstant.default_status_false,status = CommonConstant.default_status_false) )
                        db.session.commit()
                    else:
                        if int( t.job_type ) == CommonConstant.default_status_pos_2:  # 常驻Job,他停止之后下一分钟直接运行
                            tmp_next_time = datetime.datetime.now() + datetime.timedelta(minutes=1)
                            tmp_next_time = tmp_next_time.replace(second=0)
                            tmp_next_time = int( time.mktime(tmp_next_time.timetuple() ) )
                        else:
                            tmp_next_time = t.next_run_time + int( math.ceil((time.time() - t.next_run_time) / (t.run_interval * 60)) * t.run_interval * 60)
                        JobList.query.filter_by(id=job_id).update( dict( run_status = CommonConstant.default_status_true ,next_run_time =  tmp_next_time ) )
                        db.session.commit()

                    ##更新对应日志的log,担心出错影响其他
                    JobService.updateRunLog(tmp_log_id, tmp_max_job_used_mem, (tmp_status == 0))
                except:
                    app.logger.info( self.getErrMsg() )
                # 完成
                self.closePoolDB()

                app.logger.info('job_id:%s 运行完成时间为:%s,子进程结束~~' % (job_id, DateHelper.getCurrentTime() ))
                return 0

            elif pid > 0:  # 父进程
                '''
                status是一个传出参数。
                waitpid的pid参数选择:
                < -1 回收指定进程组内的任意子进程
                = -1 回收任意子进程,等待所有的子进程终止
                = 0  回收和当前调用waitpid一个组的所有子进程
                > 0  回收指定ID的子进程
                '''
                app.logger.info("父进程 job_id:%s pid:%s" % (t.id, pid))
                #os.waitpid( pid , os.WNOHANG)
                os.waitpid(-1, os.WNOHANG)
                app.logger.info("job_id:%s 父进程结束~~" % t.id)
            else:
                app.logger.info("job_id:%s,不能建立调度器" % (t.id))

        app.logger.info("it's over~~")
        return True
Пример #24
0
def home_index():
    return UtilHelper.renderView( "home/user/profile/index.html",{ "info":CurrentUserService.getInfo() }  )
Пример #25
0
def tools_log():
    status_map = CommonConstant.job_log_status_map

    req = request.values
    page = int(req.get("p", 1))
    date_from = req.get("date_from", DateHelper.getCurrentTime(fmt="%Y-%m-%d"))
    date_to = req.get("date_to", DateHelper.getCurrentTime(fmt="%Y-%m-%d"))
    status = int(req.get("status", CommonConstant.default_status_neg_99))
    job_id = int(req.get("job_id", CommonConstant.default_status_false))

    query = JobRunLog.query.filter(
        JobRunLog.created_time.between(date_from, date_to + " 23:59:59"))

    if job_id:
        query = query.filter_by(job_id=job_id)

    if status > CommonConstant.default_status_neg_99:
        query = query.filter_by(status=status)

    page_params = {
        "total": query.count(),
        "page_size": CommonConstant.PAGE_SIZE,
        "page": page,
        "display": CommonConstant.PAGE_DISPLAY,
    }

    pages = UtilHelper.iPagination(page_params)
    offset = (page - 1) * CommonConstant.PAGE_SIZE
    limit = CommonConstant.PAGE_SIZE * page
    list = query.order_by(JobRunLog.id.desc())[offset:limit]
    data = []
    if list:
        job_ids = ModelHelper.getFieldList(list, "job_id")
        job_map = ModelHelper.getDictFilterField(JobList,
                                                 select_field=JobList.id,
                                                 id_list=job_ids.sort())
        for item in list:
            tmp_data = ModelHelper.model2Dict(item)
            tmp_job_info = ModelHelper.model2Dict(
                job_map.get(tmp_data['job_id']))
            tmp_data['status_desc'] = status_map[tmp_data['status']]
            tmp_data['job_name'] = tmp_job_info['name']
            tmp_data['duration'] = ""
            if DateHelper.getCurrentTime(date=tmp_data['end_time']
                                         ) == CommonConstant.DEFAULT_DATETIME:
                tmp_data['end_time'] = "未知"
                tmp_data['duration'] = time.time() - time.mktime(
                    tmp_data['start_time'].timetuple())
            else:
                tmp_data['duration'] = (tmp_data['end_time'].timestamp() -
                                        tmp_data['start_time'].timestamp())
            tmp_data['duration'] = DateHelper.formatBeautyTime(
                tmp_data['duration'])

            data.append(tmp_data)

    sc = {
        'date_from': date_from,
        'date_to': date_to,
        'status': status,
        'job_id': job_id
    }

    return UtilHelper.renderView(
        "home/job/tools/log.html", {
            "list": data,
            "pages": pages,
            "sc": sc,
            "status_map": status_map,
            "current": "log"
        })
Пример #26
0
def error_404(e):
    err_msg = getErrMsg()
    AppLogService.addErrLog(err_msg)
    return UtilHelper.renderView( "home/error/error.html",{ "status":404,"msg":"很抱歉!,您访问的页面不存在 ~~" } )
Пример #27
0
def error_502(e):
    err_msg = getErrMsg()
    AppLogService.addErrLog(err_msg)
    return UtilHelper.renderView("home/error/error.html")
Пример #28
0
def gii_index():
    return UtilHelper.renderView("/home/tools/gii/index.html")
Пример #29
0
def gii_model():
    default_path_prefix = "/common/models/"
    if UtilHelper.isGet():
        db.reflect()
        #dict_keys 转 list
        table_list = list(db.metadata.tables.keys())
        table_list.sort()
        return UtilHelper.renderView("/home/tools/gii/model.html", {
            "default_path_prefix": default_path_prefix,
            "table_list": table_list
        })

    req = request.values

    table = req.get("table", "").strip()
    path = req.get("path", "").strip()

    ##后面这里的数据库做成选择的,因为有多数据库的可能
    engine_uri = app.config.get('SQLALCHEMY_DATABASE_URI', '')
    folder_path = app.root_path + default_path_prefix + path
    #不存在就新建
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)

    model_name = (table.replace("-",
                                " ").replace("_",
                                             " ").title()).replace(" ", "")
    model_path = folder_path + "/" + model_name + ".py"

    #2>&1 标准错误重定向到标准输出, --noinflect 不把复数处理成单数 例如 user_news 会变成 UserNew
    cmd = 'flask-sqlacodegen "{0}" --noinflect --tables {1} --outfile "{2}"  --flask 2>&1'.format(
        engine_uri, table, model_path)
    print(cmd)
    p = os.popen(cmd)
    out_list = p.readlines()
    p.close()
    if out_list and len(out_list) > 0:
        return UtilHelper.renderErrJSON("失败原因:" + "<br/>".join(out_list))

    ##为了不破坏扩展,实现正则替换,读文件,按行替换
    if not os.path.exists(model_path):
        return UtilHelper.renderErrJSON("model文件不存在,无法执行替换~~")
    try:
        f = open(model_path)
        ret = []
        ret.append("# coding: utf-8\n")
        ret.append("from application import db\n\n")
        ignore_kws = [
            "from flask_sqlalchemy", "from sqlalchemy", "SQLAlchemy",
            "coding: utf-8"
        ]
        line_break_kws = ["\n", "\r\n"]
        for line in f.readlines():
            tmp_break_flag = False
            for _ignore_kw in ignore_kws:
                if _ignore_kw in line:
                    tmp_break_flag = True
                    break

            if tmp_break_flag:
                continue

            if line in line_break_kws:
                continue
            ret.append(line)
        f.close()

        ##最后加一些常用方法
        common_funcs = '''
    def __init__(self, **items):
        for key in items:
            if hasattr(self, key):
                setattr(self, key, items[key])
        '''
        f = open(model_path, "w", encoding="utf-8")
        f.write("".join(ret) + common_funcs)
        f.flush()
        f.close()
    except Exception as e:
        pass

    return UtilHelper.renderSucJSON()
Пример #30
0
def error_500(e):
    err_msg = getErrMsg()
    AppLogService.addErrLog(err_msg)
    return UtilHelper.renderView("home/error/error.html",{ "status":500,"msg":"服务器错误" })