class UserGroup(Model): name = Field(str, max_length=128, verbose_name=_('Name'), index=True, nullable=True) parent = SelfReference(verbose_name=_('Parent Group'), collection_name='children', nullable=True, default=0) users = ManyToMany('user', verbose_name=_('Users'), collection_name='groups') deleted = Field(bool, verbose_name=_('Deleted')) created_time = Field(datetime.datetime, verbose_name=_('Created Datetime'), auto_now_add=True) number_of_children = Field(int, verbose_name=_('Number of Children')) number_of_people = Field(int, verbose_name=_('Number of People')) order = Field(int, verbose_name=_('Order'), default=9999) type = Field(CHAR, max_length=1, verbose_name=_('Group Type'), choices=get_var('AUTH/USER_GROUP_TYPE')) auth_type = Field(int, default=get_var('AUTH/AUTH_TYPE_DEFAULT'), verbose_name=_('Auth type')) def __unicode__(self): return self.name @classmethod def OnInit(cls): Index('usergroup_idx', cls.c.parent, cls.c.name)
class Tutorials_Chapters(Model): __verbose_name__ = '章节' tutorial = Reference('tutorials', verbose_name='所属教程', collection_name='turotial_chapters') parent = SelfReference(verbose_name='上级章节', collection_name='children_chapters') title = Field(str, max_length=255, verbose_name='标题', required=True) order = Field(int, verbose_name='顺序号') content = Field(TEXT, verbose_name='内容', default='', nullable=False, required=True) format = Field(CHAR, max_length=1, verbose_name='格式', choices=get_var('TUTORIALS/format'), default='2') render = Field(CHAR, max_length=1, verbose_name='渲染器', choices=get_var('TUTORIALS/render'), default='1') html = Field(TEXT, verbose_name='显示内容', default='', nullable=False) modified_user = Reference('user', verbose_name='修改人') modified_date = Field(datetime, verbose_name='修改时间') hits = Field(int, verbose_name='点击次数') votes = Field(int, verbose_name='支持票数') deleted = Field(bool, verbose_name='删除标志') chars_count = Field(int, verbose_name='字节数', default=0, server_default='0') comments_count = Field(int, verbose_name='评论条数', default=0, server_default='0') #enable_para_comment = Field(bool, verbose_name='是否打开段落评论', default=True) theme = Field(CHAR, max_length=1, verbose_name='代码块样式', choices=get_var('TUTORIALS/theme'), default='1') linenum = Field(bool, verbose_name='行号显示') scrollable = Field(bool, verbose_name='代码滚动') def __unicode__(self): return self.title class AddForm: fields = ['title', 'content', 'format', 'render', 'theme', 'scrollable'] class EditForm: fields = ['title', 'content', 'format', 'render', 'theme', 'scrollable'] @classmethod def OnInit(cls): Index('tutchp_indx', cls.c.tutorial, cls.c.parent, cls.c.order)
class Model_Config_His(Model): model_name = Field(str, verbose_name=_('Model Name'), index=True, required=True) display_name = Field(str, verbose_name=_('Display Name')) description = Field(str, verbose_name=_('Description'), max_length=255) table_name = Field(str, verbose_name=_('Tablename')) uuid = Field(CHAR, max_length=32) basemodel = Field(str, verbose_name=_('Base Model Class'), hint=_('Underlying model class path')) has_extension = Field(bool, verbose_name=_('Has Extension Model')) extension_model = Field(str, verbose_name=_('Extension Model Class'), hint=_('Underlying model class path')) fields = Field(TEXT) indexes = Field(TEXT) extension_fields = Field(TEXT) extension_indexes = Field(TEXT) version = Field(int) status = Field(CHAR, max_length=1, verbose_name=_('Publish Status'), choices=get_var('MODEL_SETTING/'), default='0') create_time = Field(datetime.datetime, verbose_name=_('Create Time'), auto_now_add=True) published_time = Field(datetime.datetime, verbose_name=_('Published Time')) @classmethod def OnInit(cls): Index('model_cfg_his_idx', cls.c.model_name, cls.c.uuid)
class Workflow_Trans(Model): """ 工作流活动流向表 """ workflow = Reference('workflow', verbose_name='所属工作流', collection_name="trans", index=True) from_task = Reference('workflow_task', verbose_name='流出活动', collection_name="child_tasks") to_task = Reference('workflow_task', verbose_name='流入活动', collection_name="parent_tasks") from_name = Field(CHAR, verbose_name='前点名称', max_length=255) to_name = Field(CHAR, verbose_name='终点名称', max_length=255) created_date = Field(datetime.datetime, verbose_name='创建时间', auto_now_add=True) created_user = Reference('user', verbose_name='创建人') message = Field(CHAR, verbose_name='流转意见', max_length=255) type = Field(int, verbose_name='流向类型', choices=get_var('PARA/WF_TRANS_TYPE'), default=2)
class Class_StudyRecord(Model): issue = Field(int, verbose_name='期数', default=1) class_obj = Reference('class', verbose_name='课程', required=True) student = Reference('user', verbose_name='学生', required=True) score = Field(int, verbose_name='成绩') create_date = Field(datetime.datetime, verbose_name='报名时间', auto_now_add=True) evaluate_level = Field(TEXT, verbose_name='评价级别', choices=get_var('CLASSES/evaluate_level')) evaluation = Field(TEXT, verbose_name='评语') deleted = Field(bool, verbose_name='删除标志') @classmethod def OnInit(cls): Index('cls_std_idx', cls.c.class_obj, cls.c.issue, cls.c.student, unique=True) class QueryStudents: fields = [ 'student', 'image', 'name', ]
class Workflow_Task(Model): """ 工作流活动实例表 """ workflow = Reference('workflow', verbose_name='所属工作流', collection_name="tasks", index=True) spec_name = Field(CHAR, verbose_name='活动定义名称', max_length=255) desc = Field(CHAR, verbose_name='活动显示名称', max_length=255) alias_name = Field(CHAR, verbose_name='活动名称', max_length=255) state = Field(int, verbose_name='活动状态', default=1, choices=get_var('PARA/WF_TASK_STATUS')) created_date = Field(datetime.datetime, verbose_name='创建时间', auto_now_add=True) created_user = Reference('user', verbose_name='创建人') modified_date = Field(datetime.datetime, verbose_name='修改时间') modified_user = Reference('user', verbose_name='修改人') data = Field(PICKLE, verbose_name='工作流活动绑定数据') uuid = Field(CHAR, verbose_name='UUID', max_length=255) async_status = Field(int, default=0) async_deliver_date = Field(datetime.datetime, auto_now=True, auto_now_add=True) async_deliver_try_count = Field(int, default=0)
class Workflow(Model): """ 工作流实例表 """ spec_name = Field(CHAR, verbose_name='工作流定义标识', max_length=255, required=True) desc = Field(CHAR, verbose_name='工作流显示名称', max_length=255) state = Field(int, verbose_name='工作流状态', default=1, choices=get_var('PARA/WF_STATUS'), index=True) created_date = Field(datetime.datetime, verbose_name='创建时间', auto_now_add=True) created_user = Reference('user', verbose_name='创建人', default=get_modified_user, auto_add=True) modified_date = Field(datetime.datetime, verbose_name='修改时间', auto_now=True, auto_now_add=True) modified_user = Reference('user', verbose_name='修改人', default=get_modified_user, auto=True, auto_add=True) data = Field(PICKLE, verbose_name='工作流绑定数据') ref_unique_id = Field(CHAR, verbose_name='关联数据标识', max_length=255)
class Audit(Model): table_id = Reference('tables', verbose_name=_('OperationTable'), required=True) title = Field(str, max_length=255, verbose_name=_('Title')) obj_id = Field(int, verbose_name="ID", required=True) changed_value = Field(BLOB, verbose_name=_('ModifiedContent')) old_value = Field(BLOB, verbose_name=_('OriginalContent')) modify_flag = Field(CHAR, max_length=1, verbose_name=_('ModifiedFlag'), choices=get_var('PARA/AUDIT_MODIFY_FLAG')) modified_date = Field(datetime.datetime, verbose_name=_('ModifiedDate')) modified_user = Reference('user', verbose_name=_('ModifiedUser'), collection_name='modifier_audits')
class Class_Issue(Model): """ 按期数来区分 """ issue = Field(int, verbose_name='期数', default=1) class_obj = Reference('class', verbose_name='课程', required=True) teachers = ManyToMany('user', verbose_name='教师', required=True) begin_date = Field(datetime.datetime, verbose_name='开始时间', required=True) finish_date = Field(datetime.datetime, verbose_name='结束时间', required=True) need_num = Field(int, verbose_name='招生人数', required=True) students_num = Field(int, verbose_name='学生数') position = Field(str, verbose_name='上课地点', required=True) map = Field(str, verbose_name='地图') type = Field(CHAR, max_length=1, verbose_name='课程性质', choices=get_var('CLASSES/class_type'), required=True) fee = Field(str, verbose_name='收费说明') @classmethod def OnInit(cls): Index('cls_issue_idx', cls.c.class_obj, cls.c.issue, unique=True) class AddForm: fields = ['begin_date', 'finish_date', 'teachers', 'need_num', 'position', 'map', 'type', 'fee'] class EditForm: fields = ['begin_date', 'finish_date', 'teachers', 'need_num', 'position', 'map', 'type', 'fee'] class Table: fields = [ {'name':'issue', 'width':45}, {'name':'teachers'}, {'name':'begin_date', 'width':100}, {'name':'finish_date', 'width':100}, {'name':'need_num', 'width':75}, {'name':'position'}, {'name':'type', 'width':75}, {'name':'fee', 'width':90}, ] class ListTable: fields = [ {'name':'issue'}, {'name':'teachers'}, {'name':'begin_date'}, {'name':'finish_date'}, {'name':'need_num'}, {'name':'students_num'}, {'name':'position'}, {'name':'type'}, {'name':'fee'}, {'name':'enroll'}, {'name':'enrolled'}, ]
class Message(Model): __verbose_name__ = u'消息' type = Field(CHAR, verbose_name='消息类别', max_length=1, choices=get_var('MESSAGES/MESSAGE_TYPE')) message = Field(TEXT, verbose_name='内容') user = Reference('user', verbose_name='用户', collection_name='user_messages') read_flag = Field(bool, verbose_name='阅读标志') create_date = Field(datetime.datetime, verbose_name='创建时间', auto_now=True, auto_now_add=True) sender = Reference('user', verbose_name='创建人') send_flag = Field(CHAR, max_length=1, verbose_name='发送标志', default='r') #'s' 发送, 'r' 接收 def __unicode__(self): return self.message class Table: fields = [ 'message', 'type', 'user', 'read_flag', 'create_date', 'sender', 'id', 'send_flag', 'user_image', ] @classmethod def OnInit(cls): Index('msg_idx', cls.c.user, cls.c.read_flag)
class User(Model): username = Field(str, verbose_name=_('Username'), max_length=30, unique=True, index=True, nullable=False) nickname = Field(str, verbose_name=_('Nick Name'), max_length=30) email = Field(str, verbose_name=_('Email'), max_length=40) password = Field(str, verbose_name=_('Password'), max_length=128) is_superuser = Field(bool, verbose_name=_('Is Superuser')) last_login = Field(datetime.datetime, verbose_name=_('Last Login')) date_join = Field(datetime.datetime, verbose_name=_('Joined Date'), auto_now_add=True) image = Field(FILE, verbose_name=_('Portrait'), max_length=256) active = Field(bool, verbose_name=_('Active Status')) locked = Field(bool, verbose_name=_('Lock Status')) weibo = Field(str, verbose_name='微博') blog = Field(str, verbose_name='博客') qq = Field(str, verbose_name='QQ号', max_length=20) description = Field(TEXT, verbose_name='自我介绍') sex = Field(CHAR, verbose_name='性别', choices=get_var('PARA/SEX')) def set_password(self, raw_password): self.password = encrypt_password(raw_password) self.save() def check_password(self, raw_password): """ Returns a boolean of whether the raw_password was correct. Handles encryption formats behind the scenes. """ return check_password(raw_password, self.password) def get_image_url(self): from uliweb.contrib.upload import get_url from uliweb.contrib.staticfiles import url_for_static if self.image: return get_href(self.image) else: return functions.url_for_static('images/user%dx%d.jpg' % (50, 50)) def get_default_image_url(self, size=50): from uliweb.contrib.staticfiles import url_for_static return functions.url_for_static('images/user%dx%d.jpg' % (size, size)) def __unicode__(self): return self.nickname or self.username class Meta: display_field = 'username' class AddForm: fields = ('username', 'nickname', 'email', 'weibo', 'blog', 'qq', 'description', 'is_superuser') class EditForm: fields = ('username', 'nickname', 'email', 'weibo', 'blog', 'qq', 'description') class DetailView: fields = ('username', 'nickname', 'email', 'weibo', 'blog', 'qq', 'description', 'is_superuser', 'date_join', 'last_login') class Table: fields = [ { 'name': 'username' }, { 'name': 'nickname' }, { 'name': 'email', 'width': 150 }, { 'name': 'weibo' }, { 'name': 'blog' }, { 'name': 'qq' }, { 'name': 'is_superuser' }, { 'name': 'date_join', 'width': 200 }, { 'name': 'last_login', 'width': 200 }, ]
class Async_Tasks(Model): task_id = Field(str, max_length=32, verbose_name=_('Task ID'), index=True, unique=True) title = Field(str, max_length=200, verbose_name=_('Title')) parent_task = Reference(reference_fieldname='task_id', verbose_name=_('Parent Task'), index=True, collection_name='tasks') category = Field(str, max_length=40, verbose_name=_('Category')) message_source = Field(CHAR, max_length=1, verbose_name=_('Message Source'), choices=get_var('ASYNC_TASKS/MESSAGE_SOURCE'), default='l') message_type = Field(CHAR, max_length=1, verbose_name=_('Message Type'), choices=get_var('ASYNC_TASKS/MESSAGE_TYPE')) #如果command_name为空,表示无命令需要执行 command_name = Field(str, max_length=256, verbose_name=_('Command Name')) command_info = Field(JSON, verbose_name=_('Command Info')) depend_tasks = Field(JSON, verbose_name=_('Depend Tasks'), default=[]) status = Field(CHAR, max_length=1, verbose_name=_('Status'), choices=get_var('ASYNC_TASKS/ASYNC_STATUS'), default='0', index=True) #记录当前状态,主要用在parent_task中 current_status = Field(CHAR, max_length=1, verbose_name=_('Current Status'), choices=get_var('ASYNC_TASKS/ASYNC_STATUS'), default='0') #子结点个数 children_count = Field(int, verbose_name=_('Children Count')) created_time = Field(datetime.datetime, verbose_name=_('Created Time'), auto_now_add=True) execution_info = Field(TEXT, verbose_name=_('Execution Info')) message = Field(str, max_length=2000, verbose_name=_('Message')) startup_time = Field(datetime.datetime, verbose_name=_('Startup Time')) started_time = Field(datetime.datetime, verbose_name=_('Started Time')) finished_time = Field(datetime.datetime, verbose_name=_('Finished Time')) max_retry_times = Field(int, verbose_name=_('Max Retry Times')) retry_time_interval = Field(int, verbose_name=_('Retry Time Interval')) retry_times = Field(int, verbose_name=_('Retry Times')) timeout = Field(int, verbose_name=_('Timeout')) user_id = Field(str, max_length=40, default='SYS', verbose_name=_('User ID')) src_ip = Field(str, max_length=15, verbose_name=_('Source IP')) correlation = Field(str, max_length=80, verbose_name=_('Correlation'), index=True) correlation_link = Field(str, max_length=2000, verbose_name=_('Correlation Link')) version = Field(int) @classmethod def OnInit(cls): Index('async_tasks_idx', cls.c.created_time, cls.c.status) @classmethod def get_task(cls, task_id): return cls.get(cls.c.task_id == task_id) def get_handler(self, **kwargs): from . import Handler from uliweb.utils.common import import_attr cls = import_attr(self.command_info.get('base', Handler)) return cls(self, **kwargs) def check_depend_tasks(self): """ Check if depend pre tasks have done all, if exists unfinished task, then return False """ if self._parent_task_: if self.parent_task.current_status != SUCCESS: return self.parent_task for t in self.depend_tasks: task = self.get_task(t) if task.status != SUCCESS: return task def reset(self, force=False, log=None): """ :param force: True will reset without condition, False will only reset for Failed, Error, Cancel status """ from . import SUCCESS, STARTED, QUEUED now = date.now() task = self if force or (not force and task.status != SUCCESS and (task.status != STARTED or task.status == STARTED and task.started_time + datetime.timedelta(milliseconds=task.timeout) > now)): task.status = QUEUED task.retry_times = 0 task.startup_time = None task.execution_info = '' task.message = 'The task is reset' handler = self.get_handler(log=log) handler.save() #处理子结点 for t in self.tasks: t.reset(force=force, log=log) return True else: return False def cancel(self, message='', process_child=False, log=None): """ 只处理状态为QUEUE, ERROR的记录,其它的不处理 """ from . import CANCEL, QUEUED, ERROR if self.status in (QUEUED, ERROR): self.status = CANCEL self.finished_time = date.now() self.message = message handler = self.get_handler(log=log) handler.save() if process_child: #处理子结点 for t in self.tasks: t.cancel(message, process_child, log) @classmethod def clear_data(cls, days, count=5000): from datetime import timedelta His = get_model('async_tasks_his') now = date.now() i = 0 for row in cls.filter( cls.c.status.in_(['C', '1', 'F']), cls.c.created_time < (now - timedelta(days=days))): his = His(**row.to_dict()) his.save(insert=True) row.delete() i += 1 if i == count: yield i i = 0 yield i class Table: fields = [ { 'name': 'task_id', 'width': 150 }, { 'name': 'title', 'width': 200 }, { 'name': 'command_name', 'width': 150 }, { 'name': 'category', 'width': 100 }, { 'name': 'message_source', 'width': 60 }, { 'name': 'message_type', 'width': 60 }, # {'name':'command_info', 'width':200}, { 'name': 'status', 'width': 120 }, { 'name': 'current_status', 'width': 120, 'hidden': True }, { 'name': 'retry_times', 'width': 30 }, # {'name':'depend_tasks', 'width':150}, { 'name': 'created_time', 'width': 120 }, { 'name': 'startup_time', 'width': 120 }, { 'name': 'started_time', 'width': 120 }, { 'name': 'finished_time', 'width': 120 }, { 'name': 'user_id', 'width': 100 }, { 'name': 'src_ip', 'width': 100 }, { 'name': 'parent', 'width': 120 }, { 'name': 'children_count', 'width': 120, 'hidden': True }, { 'name': 'correlation', 'width': 120 }, ]
class User(Model): username = Field(str, verbose_name=_('Username'), max_length=30, unique=True, index=True, nullable=False) nickname = Field(str, verbose_name=_('Nick Name'), max_length=30) email = Field(str, verbose_name=_('Email'), max_length=40) password = Field(str, verbose_name=_('Password'), max_length=128) is_superuser = Field(bool, verbose_name=_('Is Superuser')) last_login = Field(datetime.datetime, verbose_name=_('Last Login'), nullable=True) date_join = Field(datetime.datetime, verbose_name=_('Joined Date'), auto_now_add=True) image = Field(FILE, verbose_name=_('Portrait'), max_length=256) active = Field(bool, verbose_name=_('Active Status')) locked = Field(bool, verbose_name=_('Lock Status')) deleted = Field(bool, verbose_name=_('Deleted')) auth_type = Field(int, default=get_var('AUTH/AUTH_TYPE_DEFAULT'), verbose_name=_('Auth type')) def set_password(self, raw_password): self.password = encrypt_password(raw_password) # self.save() def check_password(self, raw_password): """ Returns a boolean of whether the raw_password was correct. Handles encryption formats behind the scenes. """ return check_password(raw_password, self.password) def get_image_url(self): if self.image: return functions.get_href(self.image) else: return functions.url_for_static('images/user%dx%d.jpg' % (50, 50)) def get_default_image_url(self, size=50): return functions.url_for_static('images/user%dx%d.jpg' % (size, size)) def __unicode__(self): return (self.nickname or self.username) + (_('(Deleted)') if self.deleted else '') class Meta: display_field = 'username' class AddForm: fields = ['username', 'nickname', 'email', 'is_superuser'] class EditForm: fields = ['email'] class AdminEditForm: fields = ['email', 'is_superuser'] class DetailView: fields = [ 'username', 'nickname', 'email', 'is_superuser', 'date_join', 'last_login' ] class Table: fields = [ { 'name': 'username' }, { 'name': 'nickname' }, { 'name': 'email' }, { 'name': 'is_superuser' }, { 'name': 'date_join' }, { 'name': 'last_login' }, { 'name': 'deleted' }, ]
class Resource(Model): __verbose_name__ = u'资源表' # category = Reference('resource_category', verbose_name=u'分类') name = Field(str, max_length=80, verbose_name=u'英文名称', index=True, unique=True, required=True) title = Field(str, max_length=200, verbose_name=u'标题', required=True) value = Field(str, max_length=512, verbose_name=u'值') description = Field(str, max_length=200, verbose_name=u'说明') parent = Reference(verbose_name=u'父结点', server_default='0') has_children = Field(bool, verbose_name=u'是否有子结点') icon = Field(str, max_length=20, verbose_name=u'图标') order = Field(int, verbose_name=u'序号') target = Field(str, max_length=10) type = Field(CHAR, max_length=5, choices=get_var('RESOURCE/TYPE'), verbose_name=u'类型') status = Field(CHAR, max_length=5, choices=get_var('RESOURCE/STATUS'), verbose_name=u'状态', server_default='00001') deploy_type = Field(CHAR, max_length=1, choices=get_var('PARA/DEPLOY_TYPE'), verbose_name=u'部署类型') permissions = ManyToMany('permission', verbose_name=u'权限') modified_user = Reference('user', verbose_name=u'修改人') modified_time = Field(DATETIME, verbose_name=u'修改时间', auto_now=True, auto_now_add=True) def __unicode__(self): return self.name @classmethod def get_menu(cls, parent): from uliweb import functions, settings from uliweb.utils.common import Serial def _f(_p): menus = [] for row in cls.filter(cls.c.parent == _p, cls.c.type == 'M0000', cls.c.deploy_type == 'F', cls.c.status == '00001').order_by( cls.c.order): item = row.to_dict() item['link'] = row.value item['permissions'] = [x.name for x in row.permissions] menus.append(item) if row.has_children: item['subs'] = _f(item.id) else: item['subs'] = [] return menus menus = [] use_redis = settings.get_var('RESOURCE/USE_REDIS') key = 'MENU:{}'.format(parent) if use_redis: redis = functions.get_redis() v = redis.get(key) if v: menus = Serial.load(v) if not menus: p = cls.get(cls.c.name == parent) menus = _f(p.id) if menus and use_redis: redis.set(key, Serial.dump(menus)) return menus @classmethod def iter_menu(cls, parent, user): from uliweb import functions def _f(_m): menus = [] for row in _m: if row.get('permissions'): if functions.has_permission(user, row['permissions']): menus.append(row) else: menus.append(row) if row.get('subs'): row['subs'] = _f(row['subs']) return menus return _f(cls.get_menu(parent)) def clear_menu(self): from uliweb import functions #只处理菜单根结点 if self.type == 'M0000': p = self while p.parent: p = p.parent key = 'MENU:{}'.format(p.name) redis = functions.get_redis() redis.delete(key) class Table: fields = [ { 'name': 'name', 'width': 120 }, { 'name': 'title', 'width': 300 }, { 'name': 'value', 'width': 200 }, { 'name': 'description' }, { 'name': 'target', 'width': 120 }, { 'name': 'status', 'width': 60, 'align': 'center' }, { 'name': 'deploy_type', 'width': 80, 'align': 'center' }, { 'name': 'icon', 'hidden': True }, { 'name': 'order', 'hidden': True }, { 'name': 'parent', 'hidden': True }, { 'name': 'id', 'hidden': True }, { 'name': 'has_children', 'hidden': True }, ] class AddForm: fields = [ 'parent', 'name', 'title', 'value', 'description', 'target', 'status', 'icon', 'permissions' ] layout = {'fields': {'status': {'inline': True}}} class EditForm: fields = [ 'parent', 'name', 'title', 'value', 'description', 'target', 'status', 'icon', 'permissions', 'modified_time' ] layout = { 'fields': { 'status': { 'inline': True } }, } class DetailView: fields = [ 'parent', 'name', 'title', 'value', 'description', 'target', 'status', 'icon', 'permissions' ] layout = [ '-- 基本信息 --', 'parent', ['name', 'title', 'value'], 'description', 'target', 'status', '-- 权限信息 --', 'permissions' ]