Exemplo n.º 1
0
class ImageItem(db.Document):
    """ 图片模型 """

    MENU_ICON = 'picture-o'

    image = db.XImageField(verbose_name='图片')
    created = db.DateTimeField(default=datetime.now, verbose_name='创建时间')
Exemplo n.º 2
0
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]
Exemplo n.º 3
0
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='',
        )
Exemplo n.º 4
0
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',
        ]
    }
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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),
        )
Exemplo n.º 7
0
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='登陆')
    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,
            icon=self.icon.link,
            target=self.target,
            share=unicode(self.share),
            login=self.login,
            login_show=self.login_show,
            debug=self.debug,
        )
Exemplo n.º 8
0
class Share(db.EmbeddedDocument):
    """ 分享模型 """

    title = db.StringField(verbose_name='标题')
    content = db.StringField(verbose_name='描述')
    url = db.StringField(verbose_name='链接')
    image = db.XImageField(verbose_name='图片链接')

    def __unicode__(self):
        url = self.url
        if current_user.is_authenticated() and url.strip():
            if url and '?' in url:
                url = '%s&uid=%d' % (url, current_user.id)
            else:
                url = '%s?uid=%d' % (url, current_user.id)

        return json.dumps(
            dict(
                title=self.title,
                content=self.content,
                url=url,
                image=self.image.link,
            ))

    @staticmethod
    def get(share, title='', content='', url='', image=''):
        if share:
            title = share.title or title
            content = share.content or content
            url = share.url or url
            image = share.image.link or image

        if current_user.is_authenticated() and url.strip():
            if url and '?' in url:
                url = '%s&uid=%d' % (url, current_user.id)
            else:
                url = '%s?uid=%d' % (url, current_user.id)

        return json.dumps(
            dict(
                title=title,
                content=content,
                url=url,
                image=image,
            ))
Exemplo n.º 9
0
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),
        )
Exemplo n.º 10
0
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='',
        )
Exemplo n.º 11
0
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')
Exemplo n.º 12
0
class ImageItem(db.Document):

    image = db.XImageField(verbose_name='图片')
    created = db.DateTimeField(default=datetime.now, verbose_name='创建时间')
Exemplo n.º 13
0
class ArticleItem(db.EmbeddedDocument):

    title = db.StringField(verbose_name='标题')
    description = db.StringField(verbose_name='描述')
    img = db.XImageField(verbose_name='图片链接')
    url = db.StringField(verbose_name='跳转链接')
Exemplo n.º 14
0
class QRCode(db.Document):
    """ 二维码 """

    MENU_ICON = 'qrcode'

    user = db.ReferenceField('User', verbose_name='用户')
    url = db.StringField(verbose_name='链接')
    image = db.XImageField(verbose_name='二维码')
    modified = db.DateTimeField(default=datetime.now, verbose_name='修改时间')
    created = db.DateTimeField(default=datetime.now, verbose_name='创建时间')

    meta = dict(indexes=['user', '-created'])

    @staticmethod
    def get(user, url=None):
        qr = QRCode.objects(user=user.id).first()
        if not qr:
            qr = QRCode(user=user.id, url=url)
            qr.save()

        if not qr.url and url:
            qr.url = url

        config = current_app.config.get('QRCODE', {})
        if config.get('wxclient', True) and (not qr.url or datetime.now() >
                                             qr.modified + timedelta(days=25)):
            data = dict(
                expire_seconds=2592000,
                action_name='QR_SCENE',
                action_info=dict(scene=dict(scene_id=user.id)),
            )
            qr.url = current_app.wxclient.create_qrcode(**data).get('url')
            qr.modified = datetime.now()

        if qr.url and not qr.image:

            @retry(3)
            def simple():
                qr.create_image(user)

        qr.save()
        return qr

    def create_qrcode(self, config):
        logo = config.get('logo', current_app.get_data_path('imgs/logo.jpg'))
        A, B, C = 250, 66, 58
        qr = qrcode.QRCode(version=2,
                           box_size=10,
                           border=1,
                           error_correction=qrcode.constants.ERROR_CORRECT_M)
        qr.add_data(self.url)
        qr.make(fit=True)
        im = qr.make_image()
        im = im.convert("RGBA")
        im = im.resize((A, A), Image.BILINEAR)

        if config.get('qr_logo', True):
            em = Image.new("RGBA", (B, B), "white")
            im.paste(em, ((A - B) / 2, (A - B) / 2), em)

            with open(logo) as fd:
                icon = Image.open(StringIO(fd.read()))
            icon = icon.resize((C, C), Image.ANTIALIAS)
            icon = icon.convert("RGBA")
            im.paste(icon, ((A - C) / 2, (A - C) / 2), icon)

        qr_width = config.get('qr_width', im.size[0])
        im = im.resize((qr_width, qr_width), Image.BILINEAR)
        return im

    def create_bg(self, config, user, qr):
        logo = config.get('logo', current_app.get_data_path('imgs/logo.jpg'))
        bgpath = config.get('bg')
        if bgpath:
            with open(bgpath) as fd:
                bg = Image.open(StringIO(fd.read()))
            qr_x = config.get('qr_x', (bg.size[0] - qr.size[0]) / 2)
            qr_y = config.get('qr_y', bg.size[1] / 2)

            bg.convert("RGBA")
            bg.paste(qr, (qr_x, qr_y), qr)

            if user.avatar:
                ic = Image.open(StringIO(user.avatar.content))
            else:
                with open(logo) as fd:
                    ic = Image.open(StringIO(fd.read()))

            avatar_width = config.get('avatar_width', ic.size[0])
            avatar_x = config.get('avatar_x', (bg.size[0] - avatar_width) / 2)
            avatar_y = config.get('avatar_y', bg.size[1] / 2)
            ic = ic.resize((avatar_width, avatar_width), Image.ANTIALIAS)
            ic = ic.convert("RGBA")

            if config.get('avatar_circle', False):
                bigsize = (ic.size[0] * 3, ic.size[1] * 3)
                mask = Image.new('L', bigsize, 0)
                draw = ImageDraw.Draw(mask)
                draw.ellipse((0, 0) + bigsize, fill=255)
                del draw
                mask = mask.resize(ic.size, Image.ANTIALIAS)
                ic.putalpha(mask)
            bg.paste(ic, (avatar_x, avatar_y), ic)
            return bg
        return qr

    def textsize(self, user, draw, font, width, texts):
        w, has_nick = 0, False
        for text in texts:
            if type(text) in [list, tuple]:
                text = text[0]

            if '<nickname>' in text:
                has_nick = True

            text = text.replace('<id>', str(user.id))
            text = text.replace('<nickname>', user.nickname or '佚名')
            text = text.replace('<expire>',
                                (self.modified +
                                 timedelta(days=30)).strftime('%Y-%m-%d'))
            w += draw.textsize(text, font=font)[0]

        limit = len(user.nickname)
        if has_nick:
            nick_width = draw.textsize(user.nickname or '佚名', font=font)[0]
            while limit > 4 and width - w + draw.textsize(
                    user.nickname[:limit], font=font)[0] < nick_width:
                limit -= 1
            w += draw.textsize(user.nickname[:limit],
                               font=font)[0] - nick_width
        return (width - w) / 2, limit

    def draw_texts(self, config, user, bg):
        draw = ImageDraw.Draw(bg)
        default = config.get('font', current_app.get_data_path('fonts/yh.ttf'))
        for line in config.get('lines', []):
            size = line.get('size', 18)
            font = ImageFont.truetype(line.get('font', default), size)
            x = line.get('x', 0)
            y = line.get('y', 0)

            texts = line.get('texts', [])
            if x == 'center':
                x, limit = self.textsize(user, draw, font, bg.size[0], texts)

            for text in texts:
                color = line.get('color', '#333333')
                if type(text) in [list, tuple]:
                    text, color = text[0], text[1]
                text = text.replace('<id>', str(user.id))
                text = text.replace('<nickname>', user.nickname[:limit]
                                    or '佚名')
                text = text.replace('<expire>',
                                    (self.modified +
                                     timedelta(days=30)).strftime('%Y-%m-%d'))
                width, _ = draw.textsize(text, font=font)
                draw.text((x, y), text, font=font, fill=color)
                x += width
        del draw
        return bg

    def create_image(self, user):
        config = current_app.config.get('QRCODE', {})
        qr = self.create_qrcode(config)
        bg = self.create_bg(config, user, qr)
        bg = self.draw_texts(config, user, bg)
        stream = StringIO()
        bg.save(stream, format='png')
        self.image = dict(stream=stream, format='png')
        self.save()