ancient.rig --- 拓展的工具方法

check

class ancient.rig.check.BaseMessage(key=None, status=True, msg=None)[源代码]

基类:object

自定义规则函数返回的对象,可以继承该类,自定义返回Message对象

该类是包含校验信息的消息类,当继承该类后,可以为该类添加方法

用于得到该类时直接调用处理

参数:
  • key -- 系统调用,触发message的key值
  • status -- 状态
  • msg -- 自定义rule函数返回的自定义内容
ancient.rig.check.every(content, config)[源代码]

检验dict对象,当全部key值校验完所有规则函数返回message对象

校验字典:

print(every({
    "name": "lisys",
    "age": None
}, {
    "name": not_null,
    "age": [not_null()]
}).__dict__)
参数:
  • content -- 检验dict对象
  • config -- 配置dict对象
返回:

Message

ancient.rig.check.not_null(*args, **kwargs)[源代码]
ancient.rig.check.rule(fn)[源代码]

装饰器,用于装饰自定义规则rule函数

参数:fn -- 被装饰的普通函数
返回:None
ancient.rig.check.some(content, config)[源代码]

检验dict对象,当一个key值触发错误就返回message对象

校验字典:

print(some({
    "name": "lisys",
    "age": None
}, {
    "name": not_null(msg="自定义传参"),
    "age": [not_null]
}).__dict__)
参数:
  • content -- 检验dict对象
  • config -- 配置dict对象
返回:

dict

ancient.rig.check.verify(param, preset, strict=False)[源代码]

校验传入内容

strict为true,并且preset是一个rule列表时,verify会校验所有rule

并且返回一个主Message对象,该Message的msg是一个列表,包含所有的规则错误校验信息

如果有一个规则校验失败,那么主Message对象的status值将为False

使用预设即rule的列表进行校验:

# 检验value的值是否符合规则,not_null为非假的规则函数,verify函数返回BaseMessage对象
value = "hello SystemLight"
print(verify(value, [not_null]).__dict__)

value = "hello SystemLight"
print(verify(value, [not_null(msg="自定义传参")]).__dict__)

直接传入rule函数:

value = None
print(verify(value, not_null(msg="自定义传参")).__dict__)

value = None
print(verify(value, not_null).__dict__)
参数:
  • param -- 检验内容
  • preset -- 预设preset,rule函数列表,也可以直接传递rule函数
  • strict -- 是否为严格模式,即需要校验全部的rule函数才做错误返回
返回:

Message

genSQL

class ancient.rig.genSQL.InputResult[源代码]

基类:object

该类是当数据库module执行输入语句系列时,出现错误会默认返回的错误对象

status : 标识返回状态是否正确,如果处理sql语句时报错且回滚了数据,status标识为False

err_info : 错误信息

affect : sql语句影响到的行数

last_rowid : 返回自增ID的号码

ancient.rig.genSQL.delete_tw(table, where=None)[源代码]

示例内容:

delete_tw("table", where="id=1")
转换sql: delete from table where id=1
参数:
  • table -- 需要删除的表的名称
  • where -- 用于筛选,如id=2
返回:

删除sql

ancient.rig.genSQL.insert_tc(table, content, many=False, ph='%s')[源代码]

示例内容:

insert_tc("table", [1, 2, 3, 4, 5])
转换内容 : ('insert into table values(%s,%s,%s,%s,%s)', [1, 2, 3, 4, 5])

insert_tc("table", [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]], many=True, ph="?")
转换内容 : ('insert into table values(?,?,?,?,?)', [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])

insert_tc("table", {"id": 12, "name": "SystemLight"}, many=False, ph="%s")
转换内容 : ('insert into table(name,id) values(%s,%s)', ['SystemLight', 12])

insert_tc("table", {"key": ["id", "name"], "value": [["1", "lisys"], ["2", "sl"]]}, many=True, ph="%s")
转换内容 : ('insert into table(id,name) values(%s,%s)', [['1', 'lisys'], ['2', 'sl']])
参数:
  • table -- 插入内容的表名称
  • content -- 需要插入的内容,有多种类型方式供选择
  • many -- 是否进行多行插入,默认值:False
  • ph -- 预查询模板占位符,默认值:%s
返回:

元祖(插入预查询模板,预查询参数)

ancient.rig.genSQL.insert_update_tc(table, content, many=False, ph='%s')[源代码]

插入即更新,这条sql语句在mysql中是有效的,不同数据系统可能有所不同

示例内容:

insert_update_tc("table", {"id": 12, "name": "SystemLight"}, many=False, ph="%s")
转换内容 : ('insert into table(id,name) values(%s,%s) on duplicate key update
id = values(id),name = values(name)', [12, 'SystemLight'])

insert_update_tc("table", {"key": ["id", "name"], "value": [["1", "lisys"], ["2", "sl"]]}, many=True, ph="%s")
转换内容 : ('insert into table(id,name) values(%s,%s) on duplicate key update
id = values(id),name = values(name)', [['1', 'lisys'], ['2', 'sl']])
参数:
  • table -- 插入即更新的table名称
  • content -- 需要插入即更新的内容,有两种类型方式供选择
  • many -- 是否进行多行插入,默认值:False
  • ph -- 预查询模板占位符,默认值:%s
返回:

元祖(插入预查询模板,预查询参数)

ancient.rig.genSQL.limit(sql, start, total)[源代码]

生成限制返回数量的sql语句

参数:
  • sql -- 现有sql语句
  • start -- 开始位置
  • total -- 总计条数
返回:

附件limit的sql语句

ancient.rig.genSQL.select_tcw(table, field=('*', ), where=None)[源代码]

示例内容:

select_tcw("table", ("id", "name"), where="id='2' and name='3'")
转换sql: select id,name from table where id='2' and name='3'
参数:
  • table -- 查询的表名称
  • field -- 需要查询的字段,放入元祖中,默认值("*",)
  • where -- 筛选的内容,如 id='2' and name='3',注意'用来声明字符串
返回:

查询sql语句

ancient.rig.genSQL.truncate_t(table)[源代码]

生成清空表sql语句

参数:table -- 需要清空的表的名称
返回:['set foreign_key_checks=0', 'truncate table tabble', 'set foreign_key_checks=1']
ancient.rig.genSQL.update_tcw(table, content, where=None, where_arg=None, ph='%s')[源代码]

生成更新sql语句

示例内容:

update_tcw("table", {"id": 12, "name": "SystemLight"}, ph="%s")
转换内容 : ('update table set name=%s,id=%s', ['SystemLight', 12])
参数:
  • table -- 更新的table名称
  • content -- 需要修改的值,字典类型
  • where -- 用于筛选,如id=2
  • where_arg -- 预查询参数,列表类型
  • ph -- 预查询模板占位符
返回:

元祖

password

ancient.rig.password.encrypt(password: str, salt: bytes = None) → bytes[源代码]

密码加密

参数:
  • password -- 密码值
  • salt -- salt值,默认不用填写
返回:

加密后的密码,无法逆向解析

ancient.rig.password.iso7064mod11_2(source: str) → str[源代码]

iso7064mod11-2校验算法

参数:source -- 需要添加校验的字符串
返回:校验位
ancient.rig.password.iso7064mod37_2(source: str) → str[源代码]

iso7064mod37_2校验算法

参数:source -- 需要添加校验的字符串
返回:校验位
ancient.rig.password.iso7064mod37_hybrid_36(source: str) → str[源代码]

iso7064mod37_HYBRID_36校验算法

参数:source -- 需要添加校验的字符串
返回:校验位
ancient.rig.password.validate(hashed: str, input_password: str) → bool[源代码]

密码验证

参数:
  • hashed -- 加密的密码
  • input_password -- 需要比对的密码
返回:

bool

register

class ancient.rig.register.RESTful(init_entity=None)[源代码]

基类:object

RESTful风格路由生成器,用于快速生成restful风格路由, 生成的路由可以被注册,不建议过长的路由匹配,尽量使用querystring 进行参数传递

示例一:

rf = register.rf

# 以对象的方式描写RESTful风格路由,相当于
# /zoos/{动物园ID}/animals               # 动物园所有动物
# /zoos/{动物园ID}/animals/{动物ID}       # 动物园指定ID的动物
@register.route(url=rf.e("zoos").e("animals").url)

示例二:

# 与上述注册方式效果一致
@register.route(url=RESTful(["zoos", "animals"]).u())
@register.route(url=RESTful([("zoos","(正则的类型,斜杠)w"), "animals"]).url)

示例三:

# 压缩实体去掉前缀路径,使用s方法注册的实体不包含前缀,即/{动物园ID}
@register.route(url=rf.s("zoos").url)

# 控制实例ID标识项是否可以省略,默认是可省略的标识
@register.route(url=rf.e("zoos").u(rf.LOOSE))

# 严格模式下必须包含指定的动物园ID,即无法匹配 /zoos
@register.route(url=rf.e("zoos").u(rf.STRICT))

示例四:

有时你可能需要匹配的参数是可选的,你可以这样注册
url=rf.e("fruit", **rf.union("apple", "banana", "orange")).url

上面的注册只会对三条路径进行匹配,使用union方法创造可选匹配串,通过**的方式传递给实体方法
/fruit/apple,/fruit/banana,/fruit/orange
IGNORE = 2
LOOSE = 0
STRICT = 1
clear()[源代码]

清空注册进来的内容

返回:RESTful实例对象
e(name, shape='[^\\\\/]', union=False)[源代码]

URL中增加一个实体,实体是有前缀的,前缀名等于name

参数:
  • name -- 实体前缀名称
  • shape -- 匹配类型
  • union -- 类型是否为可选匹配
返回:

RESTful实例对象

s(name, shape='[^\\\\/]', union=False)[源代码]

URL中增加一个简易实体,实体没有前缀

参数:
  • name -- 实体前缀名称,仅用于标记无实际意义
  • shape -- 匹配类型
  • union -- 类型是否为可选匹配
返回:

RESTful实例对象

u(need_eof=0)[源代码]

获取url

参数:need_eof -- 结尾字符的种类
返回:生成的URL匹配串
static union(*args)[源代码]

返回一个用于shape参数的匹配字符串,代表该内容类型为可选内容,可选范围为传入的内容

参数:args -- 可选项的列表
返回:用于shape参数的匹配字符串
url

属性方法,获取url

返回:生成的URL匹配串
class ancient.rig.register.Router(version='', prefix='')[源代码]

基类:object

如果不需要分组可以直接在Handler上面增加装饰器,如:

@register.route(version="v3")
class RecpHandler(BaseHandler):
    ...

访问地址:http://127.0.0.1:8095/v3/recp

分组路由,如:

实例化router对象
router=register.Router(prefix="/prefix",version="v3")

@router.route()
class RecpHandler(BaseHandler):
    ...

@router.route(url="/custom")
class NewRecpHandler(BaseHandler):
    ...

访问地址:http://127.0.0.1:8095/v3/prefix/recp
访问地址:http://127.0.0.1:8095/v3/perfix/custom
参数:
  • version -- restful风格版本号
  • prefix -- 统一路由前缀
static get_pe8(content: str)[源代码]

将大写字母分割转换成下划线分割的形式,如AbcDef-->abc_def

参数:content -- 转换的类名,如果带有Handler结尾将自动去除
返回:转换后的内容
route(url: str = None, prefix: str = '', urls: list = None, end=False)[源代码]

装饰器 添加该装饰器的请求实例,路由路径会被自动注册到路由表中 如果你并不想使用装饰器,你可以直接获取register.register_route的 路由表进行添加内容,通过装饰器注册的类是不区分顺序的,完全类导入顺序 路由具体生成顺序可以在运行程序后查看log下面的webMap.log文件

是否需要路由结尾有/和没有/匹配的地址一样,例如index/和index匹配是一样的 你可以设置url参数如/index/abc/?,这样两个匹配效果是一样的

如果你在配置文件中配置了url_prefix = [] 这是一个列表,会生成一组带前缀的静态文件路由匹配项 而我们的end=True的路由会放到这些带前缀的静态文件管理路由后面

参数:
  • url -- 路由路径,不填写默认会根据类名生成路径
  • prefix -- 如果提供该内容将在路由中添加一个前缀,这个前缀是在统一路由前缀后面的
  • urls -- 如果设置该参数,传入一个列表对象,url将不起效果,同时为该类增加多个可匹配的路由
  • end -- 声明该路由是否注册到默认路由后面,系统默认路由参考server.py中的default_route
返回:

None

template

class ancient.rig.template.GenerateCodeEngine(template_root_path='')[源代码]

基类:object

生成代码引擎类

使用方法:

gec = GenerateCodeEngine()
gec.catch_write("index.html", "template.html", {
    "anthor": "systemlight"
})
catch_user_code(path, match=None, code_count=1)[源代码]

捕获目标路径文件中的用户代码

参数:
  • path -- 目标文件路径
  • match -- 匹配用户代码规则
  • code_count -- 用户代码数量
返回:

匹配结果列表

catch_write(path, template_path, kwargs=None)[源代码]

捕获用户代码写入方法,执行写入之前会先匹配用户代码

参数:
  • path -- 目标文件路径
  • template_path -- 模板文件路径
  • kwargs -- 其它额外参数,参考catch_user_code方法,包含写入模板中的变量数据和函数等
返回:

None

end_match_tag
register_glob_content(name, value)[源代码]

注册全局方法或者变量,每个模板渲染时都将附带该内容

参数:
  • name -- 名称
  • value -- 内容
返回:

None

render(template_path, kwargs=None)[源代码]

根据模板渲染并生成字符串返回

参数:
  • template_path -- 模板文件路径
  • kwargs -- 包含写入模板中的变量数据和函数等
返回:

渲染后的内容

start_match_tag
write(path, template_path, kwargs=None)[源代码]

将渲染内容希尔到文件当中

参数:
  • path -- 目标文件路径
  • template_path -- 模板文件路径
  • kwargs -- 包含写入模板中的变量数据和函数等
返回:

None

utils

class ancient.rig.utils.Rectangular(x, y, w, h)[源代码]

基类:object

collision(r2)[源代码]

判断两个矩形是否产生碰撞关系

r1.x0 < r2.x1 r1.y0 < r2.y1 r1.x1 > r2.x0 r1.y1 > r2.y0

参数:r2 -- Rectangular
返回:布尔
contain(r2)[源代码]

判断矩形中是否包含另外一个矩形r2,注意包含也是矩形碰撞所以collision方法会返回True

r1.x0 < r2.x0 r1.x1 > r2.x1 r1.y0 < r2.y0 r1.y1 > r2.y1

参数:r2 -- Rectangular
返回:布尔
class ancient.rig.utils.TreeOperate(key=None)[源代码]

基类:object

TreeOperate允许你操作一颗树型结构数据,支持数据导入和导出,数据必须含有key唯一标识, 子元素必须存储在children键值下 示例内容:

_data = {
    "key": "1",
    "title": "root",
    "children": [
        {"key": "2", "title": "2", "children": [
            {"key": "4", "title": "4"},
            {"key": "5", "title": "5"}
        ]},
        {"key": "3", "title": "3", "children": [
            {"key": "6", "title": "6"},
            {"key": "7", "title": "7"}
        ]}
    ]
}
tree_root = TreeOperate.from_dict(_data)
tree_root.find("2").append(TreeOperate.from_dict({"key": "8", "title": "8"}))
print(tree_root.find("8"))
tree_root.find("8").remove()
print(tree_root.find("8"))
append(sub_tree: ancient.rig.utils.TreeOperate)[源代码]

为当前节点添加子节点,节点类型必须是TreeOperate类型 :param sub_tree: 子类型节点 :return: None

children
count()[源代码]

统计树型结构节点数量

返回:节点数量
find(key: str)[源代码]

根据key值查找节点 :param key: key值 :return: TreeOperate

static from_dict(data)[源代码]

从dict对象中返回TreeOperate对象 :param data: dict :return: TreeOperate

static from_file(path)[源代码]

从json文件中读取数据

参数:path -- json文件路径
返回:TreeOperate
parse(callback: Callable[[TreeOperate, List[T], int], T], deep=0)[源代码]

遍历定制解析规则,返回解析内容

参数:
  • callback -- Callable[["TreeOperate", List[T], int], T] 解析回调函数返回解析结果
  • deep -- 当前解析深度,默认不需要填写,用于回调函数接收判断所在层级
返回:

解析结果

remove(key=None)[源代码]

删除节点,如果传递key值,将删除当前节点下匹配的子孙节点, 如果不传递key值将当前节点从父节点中删除 :param key: [可选] key值 :return:

to_dict(flat=False)[源代码]

输出dict类型数据,用于json化 :param flat: 是否将data参数内容直接映射到对象 :return: dict

class ancient.rig.utils.UpdateList(*args, **kwargs)[源代码]

基类:list

主要方法update(),该方法是对list类型拓展, 当update的数据对象存在时对其更新,注意请保证UpdateList 的子项是dict类型而不要使用值类型,值类型对于UpdateList毫无意义

on_update hook函数,接收old_val(旧数据), p_object(新数据),需要返回更新数据 on_append hook函数,接收p_object(添加数据),需要返回添加数据 on_fetch_key hook函数,当key属性定义为函数时需要同时定义如何捕获key值

key 支持字符串,字符串指定子元素中的更新参考值
支持函数,接收val(当前数据),key(参考key值)该key值由on_fetch_key返回,函数返回bool值True为更新,False为添加

on_fetch_key作用:

复杂场景下我们可能需要up[("home2", True)]这样来找到响应的item,这样显示传递key值没有什么问题,key函数可以获取到
相应的key数据以供我们处理,但是当我们调用update时,update需要判断该内容是更新还是添加,这时我们传入的内容是数据,显然
update无法知晓如何获取我们想要的类型key值,如("home2", True),所以我们要定义on_fetch_key来告知update如何捕获我们
想要的类型的key值,on_fetch_key只有当key属性定义为函数时才有意义。
find(callback)[源代码]

返回满足回调函数的内容

参数:callback -- 回调函数,返回布尔类型用于判断是否满足要求
返回:(索引,值)
update(p_object)[源代码]

类似于append方法,不同的是当内容存在时会对内容进行更新,更新逻辑遵从update_callback 而当内容不存在时与append方法一致进行末尾加入内容

参数:p_object -- 内容对象
返回:None
ancient.rig.utils.assign(*args)[源代码]

与js中Object.assign表现形式一样

将所有可枚举属性的值从一个或多个源对象复制到目标对象

与dict.update(dict)效果一致

参数:args -- 复数的dict对象
返回:合并后的dict对象
ancient.rig.utils.deque(iterable=(), maxlen=None)[源代码]

deque返回deque对象,该对象包含的元素恒定,当你添加一个元素时最上层的元素会被销毁

参数:
  • iterable --
  • maxlen --
返回:

ancient.rig.utils.find(iterable, func)[源代码]

查找可迭代对象的指定项,匹配第一个子项并返回,无匹配项时返回(-1,None)

参数:
  • func -- 匹配函数
  • iterable -- 可迭代对象
返回:

索引,子对象

ancient.rig.utils.grunt(cup, water)[源代码]

grunt将cup中的dict对象作为最终产物,用water中的数据进行替换, 如果water未提供cup中相对应key值的字段,将使用cup中提供的默认内容

参数:
  • cup -- 需要的数据dict
  • water -- 源数据dict
返回:

最终产生的dict

ancient.rig.utils.inin(content, pool)[源代码]

查找指定内容是否存在于列表的字符串中,这种情况content一定要比列表中字符串短

举例:

inin("a",["asdf","fsfsdf"]) 将返回 "asdf"
参数:
  • content -- 内容
  • pool -- 列表
返回:

匹配内容

ancient.rig.utils.kill_form_port(port)[源代码]

传入端口号,杀死进程

参数:port -- 端口号,int类型
返回:None
ancient.rig.utils.loop(loop_iter)[源代码]

导入一个可迭代对象,loop将循环遍历它,通过next()取出下一个内容, 有时你可能需要循环变换一个状态例如从0-1再从0-1你可能需要loop, 这个函数类似轮播图,播放到结尾再从头播放

与itertools.cycle函数效果一致

参数:loop_iter -- 可迭代对象
返回:generator
ancient.rig.utils.plunder(obj: dict, which: list) → dict[源代码]

从字典中获取which中指定的内容,如果不存在或值不为真不获取该值

参数:
  • obj -- 源字典
  • which -- 需要获取哪些值
返回:

捞取后的字典

ancient.rig.utils.rang_split(content: str, index: int) → list[源代码]

根据提供的索引位置分割字符串

举例:

abcdefg  index=2
return ["ab","cdefg"]
参数:
  • content -- 字符串
  • index -- 索引位置
返回:

截取后的列表

ancient.rig.utils.read(path, encoding='utf-8')[源代码]

快捷读取文件函数

参数:
  • path -- 文件路径
  • encoding --
返回:

读取的文件内容

ancient.rig.utils.rectangular_factor(x0, y0, x1, y1)[源代码]

根据左上角和右下角坐标返回的Rectangular对象

返回:Rectangular
ancient.rig.utils.require(path, encoding='utf-8')[源代码]

有时你可能只是需要从文件中读取到json数据,这是require函数将根据 获取到的path,返回dict对象,相当方便,该函数同样类似于json.load

参数:path --
返回:dict
ancient.rig.utils.retry(freq=3, retry_callback=None)[源代码]

装饰器,为函数添加此装饰器当函数抛出异常时会对函数重新调用,重新调用次数取决于freq指定的参数

参数:
  • freq -- 重试次数
  • retry_callback -- 重试时回调执行的函数
返回:

原函数返回值

ancient.rig.utils.rinin(content, pool)[源代码]

查找指定内容是否存在于列表的字符串中,这种情况content一定要比列表中字符串长

举例:

inin("asdf",["a","fsfsdf"]) 将返回 "a"
参数:
  • content -- 内容
  • pool -- 列表
返回:

匹配内容

ancient.rig.utils.scoop(obj: dict, which: list) → dict[源代码]

从字典中获取which中指定的内容,如果不存在则捞取的值为None

参数:
  • obj -- 源字典
  • which -- 需要获取哪些值
返回:

捞取后的字典

ancient.rig.utils.write(path, data, encoding='utf-8')[源代码]

快捷写入文件函数

参数:
  • path -- 文件路径
  • data -- 写入数据
  • encoding --
返回:

None