class User(db.Document, UserMixin): """ 用户模型 """ MENU_ICON = 'user' SEX_UNKNOWN = 'unknown' SEX_MALE = 'male' SEX_FEMALE = 'female' SEX_CHOICES = ( (SEX_UNKNOWN, '保密'), (SEX_MALE, '男'), (SEX_FEMALE, '女'), ) SEX_VALUES = [x[0] for x in SEX_CHOICES] SEX_DICT = dict(SEX_CHOICES) SEX_FROM_WECHAT = {0: SEX_UNKNOWN, 1: SEX_MALE, 2: SEX_FEMALE} id = db.IntField(primary_key=True, verbose_name='ID') phone = db.StringField(max_length=20, verbose_name='手机') email = db.StringField(max_length=40, verbose_name='邮箱') password = db.StringField(max_length=40, verbose_name='密码') nickname = db.StringField(max_length=40, verbose_name='昵称') avatar = db.XImageField(verbose_name='头像') birthday = db.DateTimeField(verbose_name='生日') sex = db.StringField(default=SEX_UNKNOWN, choices=SEX_CHOICES, verbose_name='性别') location = db.AreaField(verbose_name='所在地') address = db.StringField(max_length=100, verbose_name='通讯地址') resume = db.StringField(max_length=100, verbose_name='简介') debug = db.BooleanField(default=False, verbose_name='允许调试') active = db.BooleanField(default=True, verbose_name='激活') inviter = db.ReferenceField('User', verbose_name='邀请者') inviter2 = db.ReferenceField('User', verbose_name='邀请者2') inviter3 = db.ReferenceField('User', verbose_name='邀请者3') channel = db.IntField(verbose_name='注册渠道ID') spm = db.StringField(max_length=100, verbose_name='登录SPM') ip = db.StringField(max_length=20, verbose_name='登录IP') generate = db.BooleanField(default=False, verbose_name='生成') error = db.IntField(default=0, verbose_name='登录错误次数') locked = db.DateTimeField(default=lambda: datetime(1970, 1, 1), verbose_name='锁定时间') logined = db.DateTimeField(default=lambda: datetime.now(), verbose_name='登录时间') registered = db.DateTimeField(default=lambda: datetime.now(), verbose_name='注册时间') meta = { 'indexes': [ 'phone', 'nickname', 'ip', '-logined', '-registered', ], } @property def sex_text(self): return self.SEX_DICT[self.sex]
class WeiBoUser(db.Document): """ QQ用户信息 """ user = db.IntField(verbose_name='用户') uid = db.IntField(verbose_name='ID') nickname = db.StringField(verbose_name='昵称') sex = db.IntField(verbose_name='性别') country = db.StringField(verbose_name='国家') province = db.StringField(verbose_name='省份') city = db.StringField(verbose_name='城市') headimgurl = db.StringField(verbose_name='头像链接') headimgurl_large = db.StringField(verbose_name='头像链接2') headimgurl_hd = db.StringField(verbose_name='头像链接3') subscribe = db.BooleanField(default=False, verbose_name='是否关注') subscribe_time = db.DateTimeField(verbose_name='关注时间') follow = db.IntField(verbose_name='是否关注') access_token = db.StringField(verbose_name='令牌') expires_in = db.DateTimeField(verbose_name='过期时间') refresh_token = db.StringField(verbose_name='令牌刷新') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'uid', '-modified', '-created', ], } def __unicode__(self): return 'WeiBo %d - %d' % (self.user or 0, self.uid) def oauth(self): User.from_weibo(self) def is_user(self): return False def is_authenticated(self): """ 是否登录 """ return True def is_active(self): """ 是否激活 """ return True def is_anonymous(self): """ 是否游客 """ return False def get_id(self): """ 获取用户ID """ return 'weibo:%s' % str(self.id)
class IOSVersion(db.Document): """ IOS版本 """ MENU_ICON = 'mobile' id = db.IntField(primary_key=True, verbose_name='ID') version = db.StringField(max_length=200, verbose_name='版本') log = db.StringField(verbose_name='更新日志') url = db.StringField(verbose_name='应用地址') force = db.StringField(verbose_name='强制更新') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ] } def __unicode__(self): return '%d - %s' % (self.id, self.version) def create(self): """ 创建版本 """ if not self.id: self.id = Item.inc('ios_version_index', 100) self.save() return self.id
class APIItem(db.Document): """ 接口模型 """ MENU_ICON = 'server' name = db.StringField(verbose_name='名称') key = db.StringField(verbose_name='键名') url = db.StringField(verbose_name='链接') expire = db.IntField(default=0, verbose_name='缓存') is_cache = db.BooleanField(verbose_name='已缓存') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ] } @property def detail(self): return dict( name=self.name, key=self.key, url=self.url, expire=self.expire, is_cache=self.is_cache, )
class AdminUser(db.Document): """ 管理员 """ xid = db.IntField(verbose_name='XID') username = db.StringField(verbose_name='用户') password = db.StringField(verbose_name='密码') group = db.ReferenceField('Group', verbose_name='组') root = db.BooleanField(default=False, verbose_name='超级管理员') active = db.BooleanField(default=True, verbose_name='激活') freezed = db.DateTimeField(verbose_name='冻结时间') logined = db.DateTimeField(default=datetime.now, verbose_name='登录时间') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') def __unicode__(self): return self.username def is_user(self): return True def is_authenticated(self): """ 是否登录 """ return True def is_active(self): """ 是否激活 """ return self.active def is_anonymous(self): """ 是否游客 """ return False def get_id(self): s = sign(current_app.config.get('SECRET_KEY'), password=self.password) return '{0}|{1}'.format(self.id, s)
class PhoneCode(db.Document): """ 手机验证码 """ MENU_ICON = 'volume-control-phone' ACTION_BIND = 'bind' ACTION_REGISTER = 'register' ACTION_RESET_PASSWORD = '******' ACTION_CHOICES = [ (ACTION_BIND, '绑定'), (ACTION_REGISTER, '注册'), (ACTION_RESET_PASSWORD, '重置密码'), ] ACTION_VALUES = [x[0] for x in ACTION_CHOICES] REGISTERED_ACTIONS = [ACTION_REGISTER] UNREGISTERED_ACTIONS = [ACTION_RESET_PASSWORD] PASS_ACTIONS = [] phone = db.StringField(max_length=20, verbose_name='手机') action = db.StringField(choices=ACTION_CHOICES, verbose_name='类型') code = db.StringField(max_length=40, verbose_name='验证码') error = db.IntField(default=0, verbose_name='错误次数') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ ('phone', 'action'), '-created', ], } def __unicode__(self): return '<%s - %s>' % (self.phone, self.action) @property def timelimit(self): return datetime.now() < self.created + timedelta(seconds=60) @property def timeout(self): return datetime.now() > self.created + timedelta(seconds=1800) @property def registered(self): User = um.models.User return User.objects(phone=self.phone).count() > 0 def make(self): self.created = datetime.now() self.code = str(random.randint(1000, 9999)) self.save() def send(self): um.funcs.send_sms(self) def access(self): self.error += 1 self.save()
class WXMenu(db.Document): """ 微信菜单 """ name = db.StringField(verbose_name='主菜单') second = db.ListField(db.EmbeddedDocumentField(Second), verbose_name='二级菜单') url = db.StringField(verbose_name='链接') sort = db.IntField(verbose_name='排序') make = db.BooleanField(verbose_name='使用', default=False) created = db.DateTimeField(verbose_name='创建时间', default=datetime.now)
class WeiBoUser(db.Document, ThirdUserMixin): """ 微博用户 """ MENU_ICON = 'weibo' key = 'weibo' user = db.IntField(verbose_name='用户') uid = db.IntField(verbose_name='ID') nickname = db.StringField(verbose_name='昵称') sex = db.IntField(verbose_name='性别') country = db.StringField(verbose_name='国家') province = db.StringField(verbose_name='省份') city = db.StringField(verbose_name='城市') headimgurl = db.StringField(verbose_name='头像链接') headimgurl_large = db.StringField(verbose_name='头像链接2') headimgurl_hd = db.StringField(verbose_name='头像链接3') subscribe = db.BooleanField(default=False, verbose_name='是否关注') subscribe_time = db.DateTimeField(verbose_name='关注时间') follow = db.IntField(verbose_name='是否关注') access_token = db.StringField(verbose_name='令牌') expires_in = db.DateTimeField(verbose_name='过期时间') refresh_token = db.StringField(verbose_name='令牌刷新') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'uid', '-modified', '-created', ], } def __unicode__(self): return 'WeiBo %d - %d' % (self.user or 0, self.uid) def oauth(self): return um.models.User.from_weibo(self)
class Action(db.Document): """ 功能模型 """ MENU_ICON = 'bars' key = db.StringField(verbose_name='ID') name = db.StringField(verbose_name='名称') desc = db.StringField(verbose_name='描述') icon = db.Base64ImageField(verbose_name='图标') active_icon = db.Base64ImageField(verbose_name='激活图标') module = choice(db.StringField(verbose_name='模块'), 'action_module', '功能模块') data = db.StringField(verbose_name='数据') target = db.StringField(verbose_name='目标') share = db.EmbeddedDocumentField(Share, verbose_name='分享') sort = db.IntField(verbose_name='排序') android_start = db.ReferenceField(AndroidVersion, verbose_name='安卓版本') android_end = db.ReferenceField(AndroidVersion, verbose_name='安卓最大版本') ios_start = db.ReferenceField(IOSVersion, verbose_name='IOS版本') ios_end = db.ReferenceField(IOSVersion, verbose_name='IOS最大版本') login = db.BooleanField(default=False, verbose_name='登陆') login_show = db.BooleanField(default=False, verbose_name='显示') debug = db.BooleanField(default=False, verbose_name='调试') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'key', 'sort', '-created', ] } @property def detail(self): return dict( id=self.key, name=self.name, desc=self.desc, icon=self.icon.base64, active_icon=self.active_icon.base64, data=self.data, target=self.target, share=unicode(self.share), login=self.login, login_show=self.login_show, debug=self.debug, )
class ActionItem(db.Document): """ 功能模型 """ MENU_ICON = 'bars' name = db.StringField(verbose_name='名称') key = db.StringField(verbose_name='键名') desc = db.StringField(verbose_name='描述') icon = db.XImageField(verbose_name='图标') module = db.ReferenceField('ActionModule', verbose_name='模块') action = db.StringField(default=Action.DEFAULT, verbose_name='动作', choices=Action.CHOICES) url = db.StringField(verbose_name='链接') share = db.EmbeddedDocumentField(ShareItem, verbose_name='分享') sort = db.IntField(verbose_name='排序') android_version = db.ReferenceField(AndroidVersion, verbose_name='安卓版本') android_version_end = db.ReferenceField(AndroidVersion, verbose_name='安卓最大版本') ios_version = db.ReferenceField(IOSVersion, verbose_name='IOS版本') ios_version_end = db.ReferenceField(IOSVersion, verbose_name='IOS最大版本') login = db.BooleanField(default=False, verbose_name='登陆') login_show = db.BooleanField(default=False, verbose_name='登录显示') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'key', 'sort', '-created', ] } @property def detail(self): return dict( name=self.name, key=self.key, desc=self.desc, icon=self.icon.link, action=self.action, login=self.login, url=self.url, share=unicode(self.share), extras='', )
class UserImage(db.Document): """ 用户图片 """ user = db.IntField(verbose_name='用户') source = db.StringField(verbose_name='来源') image = db.XImageField(config='USER_IMAGES', verbose_name='图片') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'source', '-created', ] }
class QQUser(db.Document): """ QQ用户信息 """ user = db.IntField(verbose_name='用户') openid = db.StringField(verbose_name='开放ID') nickname = db.StringField(verbose_name='昵称') figureurl = db.StringField(verbose_name='空间头像') figureurl_1 = db.StringField(verbose_name='空间头像1') figureurl_2 = db.StringField(verbose_name='空间头像2') figureurl_qq_1 = db.StringField(verbose_name='头像链接') figureurl_qq_2 = db.StringField(verbose_name='头像链接2') is_yellow_vip = db.IntField(verbose_name='黄钻') vip = db.IntField(verbose_name='黄钻2') yellow_vip_level = db.IntField(verbose_name='黄钻等级') level = db.IntField(verbose_name='黄钻等级2') is_yellow_year_vip = db.IntField(verbose_name='年黄钻') access_token = db.StringField(verbose_name='令牌') expires_in = db.DateTimeField(verbose_name='过期时间') refresh_token = db.StringField(verbose_name='令牌刷新') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'openid', '-modified', '-created', ], } def __unicode__(self): return 'QQ %d - %s' % (self.user or 0, self.openid) def oauth(self): User.from_qq(self) def is_user(self): return False def is_authenticated(self): """ 是否登录 """ return True def is_active(self): """ 是否激活 """ return True def is_anonymous(self): """ 是否游客 """ return False def get_id(self): """ 获取用户ID """ return 'qq:%s' % str(self.id)
class Channel(db.Document): """ 渠道模型 """ MENU_ICON = 'road' id = db.IntField(primary_key=True, verbose_name='ID') name = db.StringField(max_length=40, verbose_name='名称') password = db.StringField(max_length=40, verbose_name='密码') desc = db.StringField(verbose_name='描述') url = db.StringField(verbose_name='链接') image = db.XImageField(verbose_name='二维码') active = db.BooleanField(default=True, verbose_name='激活') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ] } def is_user(self): return True def is_authenticated(self): """ 是否登录 """ return True def is_active(self): """ 是否激活 """ return True def is_anonymous(self): """ 是否游客 """ return False def get_id(self): """ 获取用户ID """ return '%s:%s' % ('channel', str(self.id)) def create(self): """ 创建渠道 """ if not self.id: self.id = Item.inc('channel_index', 1000) self.save() return self.id
class ActionItem(db.Document): """ 功能模型 """ DEFAULT = 'default' MODULE_CHOICES = ((DEFAULT, '默认')) MODULE_VALUES = [x[0] for x in MODULE_CHOICES] name = db.StringField(verbose_name='名称') key = db.StringField(verbose_name='键名') icon = db.XImageField(verbose_name='图标') module = db.StringField(default=DEFAULT, verbose_name='模块', choices=MODULE_CHOICES) action = db.StringField(default=Action.DEFAULT, verbose_name='动作', choices=Action.CHOICES) url = db.StringField(verbose_name='链接') share = db.EmbeddedDocumentField(ShareItem, verbose_name='分享') sort = db.IntField(verbose_name='排序') login = db.BooleanField(default=False, verbose_name='登陆') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'key', 'sort', '-created', ] } @property def detail(self): return dict( name=self.name, key=self.key, icon=self.icon.link, action=self.action, login=self.login, url=self.url, share=unicode(self.share), )
class TraceLog(db.Document): """ 监控统计 """ key = db.StringField(verbose_name='KEY') tid = db.StringField(verbose_name='TID') user = db.IntField(verbose_name='用户') label = db.StringField(verbose_name='标识') value = db.StringField(verbose_name='结果') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'key', 'tid', 'label', '-created', ] }
class SlideItem(db.Document): """ 广告模型 """ MODULE_HEAD = 'home_head' MODULE_FOOT = 'home_foot' MODULE_CHOICES = ( (MODULE_HEAD, '头部'), (MODULE_FOOT, '底部'), ) name = db.StringField(verbose_name='名称') image = db.XImageField(verbose_name='图片') module = db.StringField(default=MODULE_HEAD, verbose_name='模块', choices=MODULE_CHOICES) action = db.StringField(default=Action.DEFAULT, verbose_name='动作', choices=Action.CHOICES) url = db.StringField(verbose_name='链接') share = db.EmbeddedDocumentField(ShareItem, verbose_name='分享') sort = db.IntField(verbose_name='排序') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'sort', '-created', ] } @property def detail(self): return dict( name=self.name, icon=self.image.link, action=self.action, url=self.url, share=unicode(self.share), )
class SlideItem(db.Document): """ 广告模型 """ MENU_ICON = 'paw' name = db.StringField(verbose_name='名称') key = db.StringField(verbose_name='键名') icon = db.XImageField(verbose_name='图标') module = db.ReferenceField('SlideModule', verbose_name='模块') action = db.StringField(default=Action.DEFAULT, verbose_name='动作', choices=Action.CHOICES) url = db.StringField(verbose_name='链接') share = db.EmbeddedDocumentField(ShareItem, verbose_name='分享') sort = db.IntField(verbose_name='排序') login = db.BooleanField(default=False, verbose_name='登陆') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'key', 'sort', '-created', ] } @property def detail(self): return dict( name=self.name, key=self.key, icon=self.icon.link, action=self.action, login=self.login, url=self.url, share=unicode(self.share), extras='', )
class Menu(db.Document): """ 菜单模型 """ MENU_ICON = 'sitemap' key = db.StringField(verbose_name='键名') name = db.StringField(verbose_name='名称') link = db.StringField(verbose_name='链接') icon = db.XImageField(verbose_name='图标') module = choice(db.StringField(verbose_name='模块'), 'menu_module', '菜单模块') sort = db.IntField(verbose_name='排序') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = dict(indexes=[('enable', 'module', 'sort')]) @staticmethod def get(module): return Menu.objects(module=module, enable=Enable.get()).order_by('sort')
class Slide(db.Document): """ 广告模型 """ MENU_ICON = 'paw' key = db.StringField(verbose_name='ID') name = db.StringField(verbose_name='名称') icon = db.XImageField(verbose_name='图标') module = choice(db.StringField(verbose_name='模块'), 'slide_module', '广告模块') target = db.StringField(verbose_name='目标') share = db.EmbeddedDocumentField(Share, verbose_name='分享') sort = db.IntField(verbose_name='排序') android_start = db.ReferenceField(AndroidVersion, verbose_name='安卓版本') android_end = db.ReferenceField(AndroidVersion, verbose_name='安卓最大版本') ios_start = db.ReferenceField(IOSVersion, verbose_name='IOS版本') ios_end = db.ReferenceField(IOSVersion, verbose_name='IOS最大版本') login = db.BooleanField(default=False, verbose_name='登陆') enable = db.StringField(default=Enable.ENABLED, verbose_name='状态', choices=Enable.CHOICES) modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'key', 'sort', '-created', ] } @property def detail(self): return dict( id=self.key, name=self.name, icon=self.icon.link, action=self.action, login=self.login, url=self.url, share=unicode(self.share), extras='', )
class Page(db.Document): """ 网页模型 """ MENU_ICON = 'globe' id = db.IntField(primary_key=True, verbose_name='ID') key = db.StringField(verbose_name='键名') bg = db.StringField(verbose_name='背景颜色(#FFF)') name = db.StringField(verbose_name='名称') content = db.StringField(verbose_name='正文') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = dict(indexes=['-created']) def create(self): """ 创建用户 """ if not self.id: self.id = Item.inc('page_index', 1000) self.save() return self.id
class Channel(db.Document): """ 渠道模型 """ id = db.IntField(primary_key=True, verbose_name='ID') name = db.StringField(max_length=40, verbose_name='名称') desc = db.StringField(verbose_name='描述') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ] } def create(self): """ 创建渠道 """ if not self.id: self.id = Item.inc('channel_index', 1000) self.save() return self.id
class APIItem(db.Document): """ 接口模型 """ name = db.StringField(verbose_name='名称') key = db.StringField(verbose_name='键名') url = db.StringField(verbose_name='链接') cache = db.IntField(default=0, verbose_name='缓存') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ] } @property def detail(self): return dict( name=self.name, key=self.key, url=self.url, cache=self.cache, )
class QQUser(db.Document, ThirdUserMixin): """ QQ用户 """ MENU_ICON = 'qq' key = 'qq' user = db.IntField(verbose_name='用户') openid = db.StringField(verbose_name='开放ID') nickname = db.StringField(verbose_name='昵称') figureurl = db.StringField(verbose_name='空间头像') figureurl_1 = db.StringField(verbose_name='空间头像1') figureurl_2 = db.StringField(verbose_name='空间头像2') figureurl_qq_1 = db.StringField(verbose_name='头像链接') figureurl_qq_2 = db.StringField(verbose_name='头像链接2') is_yellow_vip = db.IntField(verbose_name='黄钻') vip = db.IntField(verbose_name='黄钻2') yellow_vip_level = db.IntField(verbose_name='黄钻等级') level = db.IntField(verbose_name='黄钻等级2') is_yellow_year_vip = db.IntField(verbose_name='年黄钻') access_token = db.StringField(verbose_name='令牌') expires_in = db.DateTimeField(verbose_name='过期时间') refresh_token = db.StringField(verbose_name='令牌刷新') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'openid', '-modified', '-created', ], } def __unicode__(self): return 'QQ %d - %s' % (self.user or 0, self.openid) def oauth(self): return um.models.User.from_qq(self)
class WeChatUser(db.Document, ThirdUserMixin): """ 微信用户 """ MENU_ICON = 'wechat' key = 'wechat' user = db.IntField(verbose_name='用户') scene = db.StringField(verbose_name='邀请码') unionid = db.StringField(verbose_name='联合ID') mp_openid = db.StringField(verbose_name='公众号ID') mobile_openid = db.StringField(verbose_name='手机ID') qrcode_openid = db.StringField(verbose_name='二维码ID') nickname = db.StringField(verbose_name='昵称') sex = db.IntField(verbose_name='性别') country = db.StringField(verbose_name='国家') province = db.StringField(verbose_name='省份') city = db.StringField(verbose_name='城市') headimgurl = db.StringField(verbose_name='头像链接') privilege = db.ListField(db.StringField(), verbose_name='特权信息') subscribe = db.BooleanField(default=False, verbose_name='是否关注公众号') subscribe_time = db.DateTimeField(verbose_name='关注时间') language = db.StringField(verbose_name='语言') remark = db.StringField(max_length=40, verbose_name='备注') groupid = db.IntField(default=0, verbose_name='分组ID') access_token = db.StringField(verbose_name='令牌') expires_in = db.DateTimeField(verbose_name='过期时间') refresh_token = db.StringField(verbose_name='令牌刷新') updated = db.DateTimeField(default=datetime.now, verbose_name='更新时间') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'unionid', 'mp_openid', 'mobile_openid', 'qrcode_openid', '-modified', '-created', ], } def __unicode__(self): return 'WeChat %d - %s' % (self.user or 0, self.unionid) @staticmethod def create(userinfo, action): user = WeChatUser() if current_user.is_authenticated() and current_user.is_user(): user.user = current_user.id user.update_info(userinfo, action) user.update(True) user.save() return user @staticmethod def create_mp(openid, scene=''): user = WeChatUser(mp_openid=openid, scene=scene) if current_user.is_authenticated() and current_user.is_user(): user.user = current_user.id user.save() user.update(True) user.save() return user def sync(self, user, force=False): if not user.nickname or force: user.nickname = self.nickname if not user.avatar or force: user.avatar = url2image(self.headimgurl) if not user.sex or force: user.sex = user.SEX_FROM_WECHAT.get(self.sex, user.SEX_UNKNOWN) if hasattr(user, 'country') and not user.country or force: user.country = self.country if hasattr(user, 'location') and not user.location or force: user.location = '%s|%s' % (self.province, self.city) def oauth(self): return um.models.User.from_wechat(self) def update(self, force=False): if force or self.updated + timedelta(days=1) < datetime.now(): self.updated = datetime.now() self.update_info(current_app.wxauth.get_user_info(self.mp_openid), 'mp') self.save() if um.config.oauth_auto_update is True and self.user: user = um.models.User.objects(id=self.user).first() if user: self.sync(user, True) user.save() def update_info(self, userinfo, action): setattr(self, action + '_openid', userinfo['openid']) self.unionid = userinfo.get('unionid', '') self.nickname = userinfo.get('nickname', self.nickname) self.sex = userinfo.get('sex', self.sex) self.province = userinfo.get('province', self.province) self.city = userinfo.get('city', self.city) self.country = userinfo.get('country', self.country) self.headimgurl = userinfo.get('headimgurl', self.headimgurl) self.privilege = userinfo.get('privilege', self.privilege) if userinfo.get('subscribe') == 1: self.remark = userinfo.get('remark', self.remark) self.language = userinfo.get('language', self.language) self.groupid = userinfo.get('groupid', self.groupid) self.subscribe = True self.subscribe_time = datetime.fromtimestamp( userinfo.get('subscribe_time')) else: self.subscribe = False def unsubscribe(self): self.subscribe = False self.subscribe_time = datetime.now() self.save() def dosubscribe(self): self.subscribe = True self.subscribe_time = datetime.now() self.save()
class WeChatUser(db.Document): """ 微信用户信息 """ user = db.IntField(verbose_name='用户') unionid = db.StringField(verbose_name='联合ID') mp_openid = db.StringField(verbose_name='公众号ID') mobile_openid = db.StringField(verbose_name='手机ID') qrcode_openid = db.StringField(verbose_name='二维码ID') nickname = db.StringField(verbose_name='昵称') sex = db.IntField(verbose_name='性别') country = db.StringField(verbose_name='国家') province = db.StringField(verbose_name='省份') city = db.StringField(verbose_name='城市') headimgurl = db.StringField(verbose_name='头像链接') privilege = db.ListField(db.StringField(), verbose_name='特权信息') subscribe = db.BooleanField(default=False, verbose_name='是否关注公众号') subscribe_time = db.DateTimeField(verbose_name='关注时间') remark = db.StringField(max_length=40, verbose_name='备注') groupid = db.IntField(default=0, verbose_name='分组ID') access_token = db.StringField(verbose_name='令牌') expires_in = db.DateTimeField(verbose_name='过期时间') refresh_token = db.StringField(verbose_name='令牌刷新') updated = db.DateTimeField(default=datetime.now, verbose_name='更新时间') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'unionid', 'mp_openid', 'mobile_openid', 'qrcode_openid', '-modified', '-created', ], } def __unicode__(self): return 'WeChat %d - %s' % (self.user or 0, self.unionid) @staticmethod def create(userinfo, action): user = WeChatUser() if current_user.is_authenticated() and current_user.is_user(): user.user = current_user.id user.update_info(userinfo, action) user.save() return user def oauth(self): User.from_wechat(self) def update(self, force=False): if force or self.updated + timedelta(days=1) < datetime.now(): self.updated = datetime.now() self.update_info(current_app.wxauth.get_user_info(self.mp_openid), 'mp') self.save() def update_info(self, userinfo, action): setattr(self, action + '_openid', userinfo['openid']) self.unionid = userinfo.get('unionid', '') self.nickname = userinfo['nickname'] self.sex = userinfo['sex'] self.province = userinfo['province'] self.city = userinfo['city'] self.country = userinfo['country'] self.headimgurl = userinfo['headimgurl'] self.privilege = userinfo.get('privilege', self.privilege) if userinfo.get('subscribe') == 1: self.remark = userinfo['remark'] self.language = userinfo['language'] self.groupid = userinfo['groupid'] self.subscribe = True self.subscribe_time = datetime.fromtimestamp( userinfo['subscribe_time']) def is_user(self): return False def is_authenticated(self): """ 是否登录 """ return True def is_active(self): """ 是否激活 """ return True def is_anonymous(self): """ 是否游客 """ return False def get_id(self): """ 获取用户ID """ return 'wechat:%s' % str(self.id)
class View(db.Document): """ 管理 """ MENU_ICON = 'futbol-o' TYPE_VIEW = 'view' TYPE_MODEL = 'model' TYPE_CATE = 'cate' TYPE_CHOICES = [ (TYPE_VIEW, '默认'), (TYPE_MODEL, '模型'), (TYPE_CATE, '分类'), ] name = db.StringField(max_length=100, verbose_name='名称') label = db.StringField(max_length=100, verbose_name='标识') type = db.StringField(default=TYPE_VIEW, choices=TYPE_CHOICES, verbose_name='类型') model = db.ReferenceField('Model', verbose_name='模型') icon = db.StringField(max_length=100, verbose_name='图标') page_size = db.IntField(default=50, verbose_name='分页数') can_create = db.BooleanField(default=True, verbose_name='能创建') can_edit = db.BooleanField(default=True, verbose_name='能修改') can_delete = db.BooleanField(default=True, verbose_name='能删除') column_default_sort = db.StringField(max_length=100, verbose_name='默认排序') column_list = db.ListField(db.StringField(), verbose_name='显示列表') column_center_list = db.ListField(db.StringField(), verbose_name='居中列表') column_hidden_list = db.ListField(db.StringField(), verbose_name='隐藏列表') column_filters = db.ListField(db.StringField(), verbose_name='过滤器列表') column_sortable_list = db.ListField(db.StringField(), verbose_name='排序列表') column_searchable_list = db.ListField(db.StringField(), verbose_name='查找列表') form_excluded_columns = db.ListField(db.StringField(), verbose_name='表单隐藏列表') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') def __unicode__(self): return self.name def setup(self, admin, view): view.name = self.label or view.name view.menu_icon_value = self.icon or view.menu_icon_value if hasattr(view, 'model'): if not view.menu_icon_value: if view.model and hasattr(view.model, 'MENU_ICON'): view.menu_icon_value = view.model.MENU_ICON else: view.menu_icon_value = 'file-o' view.page_size = self.page_size or view.page_size view.can_create = self.can_create view.can_edit = self.can_edit view.can_delete = self.can_delete if self.column_default_sort: try: view.column_default_sort = json.loads( self.column_default_sort) except: pass view.column_list = self.column_list or view.column_list view.column_center_list = self.column_center_list or getattr( view, 'column_center_list', None) view.column_hidden_list = self.column_hidden_list or getattr( view, 'column_hidden_list', None) view.column_filters = self.column_filters or view.column_filters view.column_sortable_list = self.column_sortable_list or view.column_sortable_list view.column_searchable_list = self.column_searchable_list or view.column_searchable_list view.form_excluded_columns = self.form_excluded_columns or view.form_excluded_columns view._refresh_cache() elif not view.menu_icon_value: if hasattr(view, 'MENU_ICON'): view.menu_icon_value = view.MENU_ICON admin._refresh() def save(self): super(View, self).save() if current_app.cool_manager and not current_app.cool_manager.loading: for admin in current_app.extensions.get('admin', []): for view in admin._views: if view.__class__.__name__ == self.name: self.setup(admin, view) break def add_text(self, key): attr = getattr(self, key) if attr: return ' %s = %s' % (key, json.dumps(attr)) @property def code_text(self): texts = [] keys = [ 'column_list', 'column_center_list', 'column_hidden_list', 'column_filters', 'column_sortable_list', 'column_searchable_list', 'form_excluded_columns' ] for key in keys: text = self.add_text(key) if text: texts.append(text) return '\n'.join(texts)
class UserLog(db.Document): """ 用户日志 """ MENU_ICON = 'info-circle' TYPE_BIND = 'bind' TYPE_REGISTER = 'register' TYPE_LOGIN = '******' TYPE_LOGOUT = 'logout' TYPE_CHANGE_PASSWORD = '******' TYPE_RESET_PASSWORD = '******' TYPE_ACTIVE = 'active' TYPE_CHOICES = ( (TYPE_BIND, '绑定手机'), (TYPE_REGISTER, '注册'), (TYPE_LOGIN, '登录'), (TYPE_LOGOUT, '退出'), (TYPE_CHANGE_PASSWORD, '修改密码'), (TYPE_RESET_PASSWORD, '重置密码'), (TYPE_ACTIVE, '活跃'), ) TYPE_VALUES = [x[0] for x in TYPE_CHOICES] user = db.IntField(verbose_name='用户') type = db.StringField(choices=TYPE_CHOICES, verbose_name='类型') key = db.StringField(verbose_name='键') device = db.StringField(max_length=100, verbose_name='设备ID') spm = db.StringField(max_length=100, verbose_name='SPM') ip = db.StringField(max_length=20, verbose_name='IP') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ 'user', 'ip', '-created', ], } def __unicode__(self): return '%d - %s' % (self.user, self.type) @staticmethod def log(type, id, device, key='', spm=None, ip=None): spm = spm if spm else get_spm() ip = ip if ip else get_ip() UserLog(user=id, type=type, device=device, key=key, spm=spm, ip=ip).save() @staticmethod def active(id, device='', key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_ACTIVE, id, device, key, spm, ip) @staticmethod def bind(id, device, key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_BIND, id, device, key, spm, ip) @staticmethod def register(id, device, key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_REGISTER, id, device, key, spm, ip) @staticmethod def login(id, device, key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_LOGIN, id, device, key, spm, ip) @staticmethod def logout(id, device, key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_LOGOUT, id, device, key, spm, ip) @staticmethod def change_password(id, device, key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_CHNAGE_PASSWORD, id, device, key, spm, ip) @staticmethod def reset_password(id, device, key='', spm=None, ip=None): UserLog.log(UserLog.TYPE_RESET_PASSWORD, id, device, key, spm, ip)
class StatLog(db.Document): """ 统计日志 """ MENU_ICON = 'bar-chart' key = db.StringField(verbose_name='KEY') tid = db.StringField(verbose_name='TID') label = db.StringField(verbose_name='标签') day = db.StringField(verbose_name='日期') hour = db.IntField(default=0, verbose_name='小时') value = db.IntField(default=0, verbose_name='结果') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ('key', 'tid'), ('key', 'tid', 'day', 'hour'), ] } @staticmethod def inc(key, tid, day=lambda: today(), hour=0, value=1): if callable(day): day = day() day = str(day)[:10] item = StatLog.objects(key=key, tid=tid, day=day).modify( inc__value=value, set__modified=datetime.now(), ) if not item: StatLog(key=key, tid=tid, day=day, hour=0, value=value).save() return value else: return item.value + 1 @staticmethod def get(key, tid, day=today(), hour=0, default=0, save=True): if callable(day): day = day() day = str(day)[:10] item = StatLog.objects(key=key, tid=tid, day=day).first() if item: return item.value if save: StatLog(key=key, tid=tid, day=day, hour=0, value=default).save() return default @staticmethod def date_inc(key, tid='', label='', value=1, day=None): day = time.strftime('%Y-%m-%d') if not day else day doc = { '$inc': { 'value': value }, '$set': { 'modified': datetime.now() }, '$setOnInsert': { 'created': datetime.now() } } log = StatLog.objects(key=str(key), tid=tid, label=label, day=day, hour=-1).update_one(__raw__=doc, upsert=True) return StatLog.date_get(key, tid=tid, label=label, day=day) @staticmethod def date_get(key, tid='', label='', day=None): day = time.strftime('%Y-%m-%d') if not day else day log = StatLog.objects(key=str(key), tid=tid, label=label, day=day, hour=-1).first() return log.value if log else 0
class EmailCode(db.Document): """ 邮箱验证码 """ MENU_ICON = 'envelope' ACTION_BIND = 'bind' ACTION_REGISTER = 'register' ACTION_RESET_PASSWORD = '******' ACTION_CHOICES = ( (ACTION_BIND, '绑定'), (ACTION_REGISTER, '注册'), (ACTION_RESET_PASSWORD, '重置密码'), ) ACTION_VALUES = [x[0] for x in ACTION_CHOICES] REGISTERED_ACTIONS = (ACTION_REGISTER, ) UNREGISTERED_ACTIONS = (ACTION_RESET_PASSWORD, ) email = db.StringField(max_length=40, verbose_name='邮箱') action = db.StringField(choices=ACTION_CHOICES, verbose_name='类型') code = db.StringField(max_length=40, verbose_name='验证码') token = db.StringField(max_length=40, verbose_name='令牌') error = db.IntField(default=0, verbose_name='错误次数') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ ('email', 'action'), '-created', ], } def __unicode__(self): return '<%s - %s>' % (self.phone, self.action) @staticmethod def get(token): return EmailCode.objects(token=token).first() @property def timelimit(self): return datetime.now() < self.created + timedelta(seconds=60) @property def timeout(self): return datetime.now() > self.created + timedelta(seconds=1800) @property def registered(self): User = um.models.User return User.objects(email=self.email).count() > 0 def make(self): self.created = datetime.now() self.code = str(random.randint(1000, 9999)) self.token = hashlib.md5( '%s%s%s' % (self.email, self.code, str(self.created))).hexdigest() self.save() def send(self): um.funcs.send_mail(self) def access(self): self.error += 1 self.save()
class StatLog(db.Document): """ 统计日志 """ MENU_ICON = 'bar-chart' key = db.StringField(verbose_name='KEY') tid = db.StringField(verbose_name='TID') label = db.StringField(verbose_name='标签') day = db.StringField(verbose_name='日期') hour = db.IntField(default=0, verbose_name='小时') value = db.IntField(default=0, verbose_name='结果') modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间') created = db.DateTimeField(default=datetime.now, verbose_name='创建时间') meta = { 'indexes': [ '-created', ('key', 'tid'), ('key', 'tid', 'day', 'hour'), ] } @staticmethod def inc(key, tid='', day=lambda: today(), hour=-1, value=1): if callable(day): day = day() day = str(day)[:10] item = StatLog.objects(key=key, tid=tid, day=day, hour=hour).modify( inc__value=value, set__modified=datetime.now(), ) if not item: StatLog(key=key, tid=tid, day=day, hour=hour, value=value).save() return value else: return item.value + value @staticmethod def get(key, tid='', day=lambda: today(), hour=-1, default=0, save=True): if callable(day): day = day() day = str(day)[:10] item = StatLog.objects(key=key, tid=tid, day=day, hour=hour).first() if item: return item.value if save: StatLog(key=key, tid=tid, day=day, hour=hour, value=default).save() return default @staticmethod def date_inc(key, tid='', label='', value=1, day=None): day = time.strftime('%Y-%m-%d') if not day else day item = StatLog.objects(key=str(key), tid=tid, label=label, day=day, hour=-1).modify( inc__value=value, set__modified=datetime.now(), ) if not item: StatLog(key=str(key), tid=tid, label=label, day=day, hour=-1, value=value).save() return value else: return item.value + value @staticmethod def date_get(key, tid='', label='', day=None): day = time.strftime('%Y-%m-%d') if not day else day log = StatLog.objects(key=str(key), tid=tid, label=label, day=day, hour=-1).first() return log.value if log else 0 @staticmethod def xinc(key, tid='', day='', hour=-1, value=1): return StatLog.inc(key, tid, day, hour, value) @staticmethod def xget(key, tid='', day='', hour=-1, default=0, save=True): return StatLog.get(key, tid, day, hour, default, save) @staticmethod def date_limit(key, tid='', label='', limit=timedelta(days=1), default=0, save=True): if type(limit) == int: limit = timedelta(days=limit) log = StatLog.objects(key=str(key), tid=tid, label=label, day='', hour=-1).first() if not log: if save: StatLog(key=str(key), tid=tid, label=label, day='', hour=-1).save() return True if log.modified + limit < datetime.now(): log.modified = datetime.now() log.save() return True return False