Beispiel #1
0
class MatchView(View):
    @staticmethod
    @Analyse.r(q=[
        P('phrase').process(Processor(phrase_processor,
                                      yield_name='phonetics')),
        P('phrase_len').default(0).process(int),
        P('min_max_match').default(0).process(int),
        P('cluster').process(lambda x: x.upper()),
        P('cluster_type').process(cluster_type_processor),
    ])
    def get(r):
        return worker.match(**r.d.dict())
Beispiel #2
0
class ArticleView(View):
    @staticmethod
    @Analyse.r(q=[P('role', '角色').default('owner')])
    @Auth.require_login
    def get(r):
        user = r.user  # type: MiniUser
        if r.d.role == 'owner':
            return user.article_set.order_by('-pk').all().dict(Article.d_base)
        else:
            return list(
                map(lambda aid: Article.get(aid).d_base(),
                    user.get_commented_articles()))

    @staticmethod
    @Analyse.r([
        ArticleP.title,
        ArticleP.origin,
        ArticleP.author,
        ArticleP.self_product,
        ArticleP.require_review,
        ArticleP.allow_open_reply,
    ])
    @Auth.require_login
    def post(r):
        Weixin.msg_sec_check(r.d.title)
        Weixin.msg_sec_check(r.d.origin)
        Weixin.msg_sec_check(r.d.author)
        return Article.create(r.user, **r.d.dict()).d_create()
Beispiel #3
0
class TicketView(View):
    """/space/:space_id/ticket"""
    PTicket = P('ticket',
                yield_name='spaceman').process(Auth.analyse_invite_ticket)

    @staticmethod
    @Analyse.r(a=[SpaceP.space_getter])
    @Auth.require_space_member
    def get(r):
        """生成邀请"""
        return Auth.get_invite_ticket(r.spaceman)

    @staticmethod
    @Analyse.r(b=[PTicket])
    @Auth.require_login
    def post(r):
        """获取邀请信息"""
        return r.d.spaceman.d_invite()

    @staticmethod
    @Analyse.r(b=[PTicket])
    @Auth.require_login
    def put(r):
        """进入星球"""
        space = r.d.spaceman.space
        space.not_member_checker(r.user)
        space.add_member(r.user)
        return 0
Beispiel #4
0
class PinyinService(Service):
    name = 'pinyin'
    desc = '汉字转拼音'
    long_desc = Lines("👉pinyin 林俊杰", "✅lín jùn jié",
                      "当输入单个汉字且是多音字时,默认返回该字的所有拼音", "👉pinyin 给", "✅gěi/jǐ",
                      "可以使用-s或--single来获得单个拼音", "👉pinyin -s 给", "✅gěi")

    PSingle = Parameter(P(read_name='多音字返回一个拼音').default(),
                        long='single',
                        short='s')

    @classmethod
    def run(cls, directory: 'Service', storage: ServiceData, pd: ParamDict,
            *args):
        if not args:
            return cls.need_help()
        text = args[0]

        heteronym_when_single = not pd.has(cls.PSingle)
        resp = Tools.get(Tools.Pinyin, {
            'text': text,
            'heteronym_when_single': heteronym_when_single
        })
        resp = list(filter(lambda x: x, resp))

        return ' /'[len(text) == 1].join(resp)

    @classmethod
    def init(cls):
        cls.validate(cls.PSingle)
Beispiel #5
0
class SpaceP:
    space_id, name, rename_card, access = Space.P('space_id', 'name',
                                                  'rename_card', 'access')

    space_getter = space_id.clone().rename('space_id',
                                           yield_name='space',
                                           stay_origin=True).process(Space.get)

    spaceman_getter = P('space_user',
                        yield_name='spaceman').process(SpaceMan.get_by_union)
Beispiel #6
0
class AxiosValidateView(View):
    @staticmethod
    @Analyse.r(b=[
        P('geetest_challenge', 'challenge'),
        P('geetest_seccode', 'seccode'),
        P('geetest_validate', '验证码')
    ])
    def post(request):
        gt = GeetestLib(geetest_id, geetest_key)
        challenge = request.d.geetest_challenge
        validate = request.d.geetest_validate
        seccode = request.d.geetest_seccode
        status = request.session[gt.GT_STATUS_SESSION_KEY]
        user_id = request.session["user_id"]
        if status:
            result = gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)
        result = {"status": "success"} if result else {"status": "fail"}
        return HttpResponse(json.dumps(result))
Beispiel #7
0
class TalkContentView(View):
    @staticmethod
    @Analyse.r(a=[
        P('tid', 'talkid', 'talk').process(int).process(Talk.get_talk_by_pk)
    ],
               b=[
                   P('last', '最后一条commit的时间').default(
                       0, through_processors=True).process(last_timer),
                   P('count', '每页数目').default(5).process(int)
               ])
    @Auth.require_login
    def post(request):
        """POST /api/talk/@<int:tid>

        获取此talk的内容及commit
        """
        return dict(
            talk=request.d.talk.d(),
            commits=Commit.get_commit(**request.d.dict()),
        )
Beispiel #8
0
class ImageTokenView(View):
    @staticmethod
    @Analyse.r(a=[AlbumP.id_getter],
               q=[P('image_num', '图片数量').process(boundary(max_=99, min_=1))])
    @Auth.require_album_member
    def get(r):
        album = r.d.album  # type: Album
        image_num = r.d.image_num

        return Image.get_tokens(action=ImageUploadAction.ALBUM,
                                num=image_num,
                                album_id=album.res_id)
Beispiel #9
0
class UserView(View):
    @staticmethod
    @Auth.require_login
    def get(request):
        """ GET /api/user/

        获取我的信息
        """
        user = request.user
        # print(user.username)
        return UsernameView.get_info(user.username)

    @staticmethod
    @Analyse.r(b=[UserP.username, UserP.password, UserP.invite_code])
    def post(request):
        """ POST /api/user/

        创建用户
        """
        print(1111)
        invite_code = request.d.invite_code
        if invite_code is not None:
            # print(invite_code)
            user = User.create_invite(**request.d.dict())
        else:
            user = User.create(**request.d.dict('username', 'password'))
        return Auth.get_login_token(user)

    @staticmethod
    @Analyse.r(
        b={
            UserP.password.clone().default(None),
            UserP.password.clone().rename('old_password').default(None),
            P('nickname', '昵称').default(None)  # 教学示范
        })
    @Auth.require_login
    def put(request):
        """ PUT /api/user/

        修改用户信息
        """
        user = request.user

        password = request.d.password
        nickname = request.d.nickname
        old_password = request.d.old_password

        if password is not None:
            user.change_password(password, old_password)
        else:
            user.modify_info(nickname)
        return user.d()
Beispiel #10
0
class CommitView(View):
    @staticmethod
    @Analyse.r(a=[
        P('tid', 'talkid').process(int),
    ], b=[
        CommitP.commit,
    ])
    @Auth.require_login
    def post(request):
        """POST /api/talk/@<int:tid>/commit

        添加评论
        """
        return Commit.create(request.d.commit, request.d.tid, request.user).d()
Beispiel #11
0
    def __init__(self,
                 p: Union[P, str, None] = None,
                 long=None,
                 short=None,
                 default=NotSet,
                 allow_default=True):
        self.p = P(p) if isinstance(p, str) else p
        self.short = short
        self.long = long
        self.default = default
        self.allow_default = allow_default

        if not self.short and not self.long:
            raise ServiceMessage.PARAM_NAME
Beispiel #12
0
class TokenView(View):
    @staticmethod
    @Analyse.r(q=PDict().set_fields(
        SpaceP.name_getter, AlbumP.name,
        P('image_num',
          '图片数量').process(boundary(max_=99, min_=1))).process(Album.getter))
    @Auth.require_admin
    def get(r):
        album = r.d.album
        image_num = r.d.image_num

        return Foto.get_tokens(
            num=image_num,
            album=album.name,
            space=album.space.name,
        )
Beispiel #13
0
class LSService(Service):
    name = 'ls'
    desc = '查看工具箱'
    long_desc = Lines('👉ls lang', '👉ls ../web')

    PLong = Parameter(P(read_name='是否显示完整信息').default(), short='l')

    @staticmethod
    def find_path(current: Service, paths: str):
        if paths and paths[0] == '/':
            current = ServiceDepot.get(ROOT_NAME)
        paths = paths.split('/')
        for path in paths:
            if path == '..':
                if not current.parent:
                    raise LSMessage.PARENT
                current = current.parent
            elif path != '.' and path != '':
                current = current.get(path)
                if not current:
                    raise LSMessage.NOT_FOUND(path)
                if not current.as_dir:
                    raise LSMessage.CD_DIR(current.name)
        return current

    @classmethod
    def init(cls):
        cls.validate(cls.PLong)

    @classmethod
    def run(cls, directory: Service, storage: ServiceData, pd: ParamDict,
            *args):
        paths = args[0] if args else ''
        terminal = cls.find_path(directory, paths)

        long = cls.PLong.is_set_in(pd)
        messages = ['%s中拥有以下工具:' % terminal.name]
        for child in terminal.get_services():
            name = child.name + ['(工具)', '(工具箱)'][child.as_dir]
            if long:
                messages.append('%s\t%s' % (name, child.desc))
            else:
                messages.append(name)
        return '\n'.join(messages)
Beispiel #14
0
class RoomMemberView(View):
    @staticmethod
    @Auth.require_login
    @Analyse.r(a=[RoomP.room_number])
    @Roomm.is_room_member
    def post(request):
        """POST /api/room/member/@<int:number>
        获取房间信息
        """
        return request.d.room.d()

    @staticmethod
    @Auth.require_login
    @Analyse.r(a=[RoomP.room_number])
    @Roomm.is_room_member
    def delete(request):
        """DELETE /api/room/member/@<int:number>

        退出房间
        """
        room_number = request.d.room.number
        Member.leave_room(request.user)
        Room.change_position(Room.get_room_by_number(room_number))

    @staticmethod
    @Auth.require_login
    @Analyse.r(a=[RoomP.room_number],
               b=[P('ready', '是否准备').default(True).process(bool)])
    @Roomm.is_room_member
    def put(request):
        """PUT /api/room/member/@<int:number>

        房间状态操作(开始游戏(两人准备)/准备)
        """
        return Room.room_ready_status(request.user,
                                      **request.d.dict('room', 'ready')).d()
Beispiel #15
0
class MilestoneP:
    name, start_date = Milestone.P('name', 'start_date')
    start_date.process(
        lambda s: datetime.datetime.strptime(s, '%Y-%m-%d').date(), begin=True)

    id_getter = P('mid', yield_name='milestone').process(Milestone.get)
Beispiel #16
0
class BindPhoneService(Service):
    name = 'bind'
    desc = '绑定手机号'
    long_desc = Lines('用于推送其他功能产生的结果', '手机号绑定后允许更改',
                      '设置手机号并发送验证码:bind -p13xxxxxxxxx',
                      '非中国大陆手机号发送验证码格式为:bind -p+地区代码+手机号',
                      '如香港代码为852,则bind -p+85212345678',
                      '验证码反馈完成手机绑定:bind -c123456')

    WAIT = 0
    DONE = 1

    PPhone = Parameter(
        P(read_name='手机号').process(str).validate(phone_validator),
        long='phone',
        short='p')
    PCaptcha = Parameter(P(read_name='验证码').default(),
                         long='captcha',
                         short='c')

    @classmethod
    def init(cls):
        cls.validate(cls.PPhone, cls.PCaptcha)

    @staticmethod
    def readable_send_wait(send_wait: int):
        s = ''
        send_wait = int(send_wait)
        if send_wait // 60:
            s += '%s分' % (send_wait // 60)
        if send_wait % 60:
            s += '%s秒' % (send_wait % 60)
        return s

    @classmethod
    def run(cls, directory: 'Service', storage: ServiceData, pd: ParamDict,
            *args):
        data = storage.classify()

        # if data.status:  # 设置手机号
        #     raise BindPhoneError.MODIFY_NOT_ALLOWED

        crt_time = datetime.datetime.now().timestamp()
        last_time = data.last_time or 0

        if pd.has(cls.PPhone):
            phone = pd.get(cls.PPhone)
            captcha = get_random_string(length=6, allowed_chars='1234567890')

            send_wait = last_time + 60 - crt_time
            if send_wait > 0:
                raise BindPhoneMessage.SEND_WAIT(send_wait)

            Phone.validate(phone, captcha)
            storage.update(
                dict(
                    phone=phone,
                    captcha=captcha,
                    last_time=crt_time,
                    attempt=3,
                ))
            raise BindPhoneMessage.CAPTCHA_SENT
        elif pd.has(cls.PCaptcha):
            if not data.attempt:
                raise BindPhoneMessage.CAPTCHA_RESENT

            data.attempt -= 1
            storage.update(data)
            if last_time + 5 * 60 < crt_time:
                raise BindPhoneMessage.TIME_EXPIRED

            captcha = pd.get(cls.PCaptcha)
            if captcha != data.captcha:
                raise BindPhoneMessage.CAPTCHA_WRONG(data.attempt)

            storage.user.set_phone(data.phone)
            storage.update(dict(status=cls.DONE))
            raise BindPhoneMessage.SUCCESS
        else:
            return cls.need_help()
Beispiel #17
0
class RoomP:
    password, number, = Room.get_params('password', 'number')
    room_number = P('number', '房间号', 'room').process(Room.get_room_by_number)
    room_password = P('password', '房间密码')
Beispiel #18
0
class MeatP:
    content, status = Meat.get_params('content', 'status')
    notification = P('notification', '目标日期').default(False).process(bool)
    target_time = P('target_time', '目标时间').process(int).process(target_timer)
    mid = P('mid', '天鹅肉id', 'meat').process(int).process(Meat.get_meat_by_pk)
Beispiel #19
0
@E.register()
class MathError:
    DIV_ZERO = E("除数不能为0")
    POSITIVE = E("需要为正数")


def positive_check(v):
    """check if value is positive"""

    if v < 0:
        raise MathError.POSITIVE


def not_zero(v):
    """check if value is zero"""

    if v == 0:
        raise MathError.DIV_ZERO


pos_num = P('positive', '正数').process(float).validate(positive_check)
divided_num = pos_num.clone().rename('divided').validate(not_zero)


@Analyse.p(pos_num, divided_num)
def div(positive, divided):
    return positive // divided


print(div(999.9, '-0.2'))
Beispiel #20
0
class Service:
    """服务"""
    name = 'NAME'
    desc = 'DESCRIPTION'
    long_desc = """暂无详细说明"""

    as_dir = False
    parent = None
    async_user_task = False
    async_service_task = False

    PHelper = Parameter(P(read_name='获取帮助').default(), long='help', short='h')
    PInline = Parameter(P(read_name='批处理模式').default(), long='inline')

    __parameters = [PHelper, PInline]  # type: List[Parameter]
    __services = []  # type: List['Service']

    @classmethod
    def init(cls):
        pass

    @classmethod
    def get_global_storage(cls):
        return ServiceData.get_or_create(cls.name, None)

    @classmethod
    def need_help(cls):
        return '请使用%s -h查看本工具的使用方法' % cls.name

    @classmethod
    def helper(cls):
        messages = ['%s: %s' % (cls.name, cls.desc), str(cls.long_desc), '', '功能参数说明:']
        for parameter in cls.__parameters:
            messages.append('%s: %s' % (str(parameter), parameter.p.read_name))
        return '\n'.join(messages)

    @classmethod
    def work(cls, directory: 'Service', storage: ServiceData, pd: ParamDict, *args):
        if cls.as_dir:
            raise ServiceMessage.DIR_NOT_CALLABLE

        if not pd.has(cls.PHelper):
            return str(cls.run(directory, storage, pd, *args))
        return cls.helper()

    @classmethod
    def run(cls, directory: 'Service', storage: ServiceData, pd: ParamDict, *args):
        pass

    @classmethod
    def get(cls, name):
        for service in cls.__services:
            if service.name == name:
                return service

    @classmethod
    def process_parameters(cls, kwargs: dict):
        parameters = dict()
        for parameter in cls.__parameters:
            value = parameter.get_from(kwargs)
            if value == Parameter.NotFound:
                if parameter.default == Parameter.NotSet and not parameter.allow_default:
                    raise ServiceMessage.PARAM_NO_VALUE(str(parameter))
                else:
                    value = parameter.default
            else:
                _, value = parameter.p.run(value)
            parameters[parameter] = value
        return parameters

    @classmethod
    def register(cls, service: 'Service'):
        ServiceDepot.register(service)
        service.init()
        return service

    @classmethod
    def contains(cls, *services):
        if cls.__services:
            cls.__services.extend(services)
        else:
            cls.__services = list(services)
        for service in services:
            service.parent = cls

    @classmethod
    def validate(cls, *parameters):
        cls.__parameters = cls.__parameters + list(parameters)

    @classmethod
    def get_services(cls):
        return cls.__services

    @classmethod
    def async_user_handler(cls, storage_list: List[ServiceData]):
        pass

    @classmethod
    def async_user(cls, storage: ServiceData):
        pass

    @classmethod
    def async_service(cls, storage: ServiceData):
        pass
Beispiel #21
0
class WatchService(Service):
    name = 'watch'
    desc = '网页变化监控'
    long_desc = Lines('当网页发送变化时,将会发送短信提醒,且任务自动结束', '⚠️监控最短时间单位为1分钟',
                      '⚠️暂不支持中文域名网址监控', '⚠️网页格式规范,应以http/https开头',
                      '👉watch -n百度 https://www.baidu.com',
                      '👉watch -i2 https://www.zju.edu.cn')

    async_user_task = True

    PInterval = Parameter(P(read_name='监控时间单位').default(5).process(int),
                          long='interval',
                          short='i')
    PName = Parameter(P(read_name='监控名').default(), long='name', short='n')
    PCancel = Parameter(P(read_name='取消当前任务').default(), long='cancel')
    PStatus = Parameter(P(read_name='查看当前任务').default(), long='status')

    @staticmethod
    def readable_time(create_time):
        return datetime.datetime.fromtimestamp(create_time).strftime(
            '%m-%d %H:%M')

    @classmethod
    def init(cls):
        cls.validate(cls.PName, cls.PCancel, cls.PStatus, cls.PInterval)

    @classmethod
    def run(cls, directory: 'Service', storage: ServiceData, pd: ParamDict,
            *args):
        storage.user.require_phone()

        data = storage.classify()
        if pd.has(cls.PCancel):
            data.work = False
            storage.update(data)
            return '任务已取消'

        if pd.has(cls.PStatus):
            if not data.work:
                return '暂无监控任务'
            return Lines(
                '正在监控:%s' % data.name,
                '任务开始时间:%s' % cls.readable_time(data.create_time),
                '已监控次数:%s' % data.visit_times, '监控时间间隔:%s分钟' %
                (data.interval or cls.PInterval.p.default_value))

        if not args:
            return cls.need_help()
        url = args[0]
        if not url_validate(url):
            raise WatchError.URL

        key = cls.get_key_of(url)
        name = urlparse(url).netloc
        if pd.has(cls.PName):
            name = pd.get(cls.PName)
        interval = pd.get(cls.PInterval)

        crt_time = datetime.datetime.now().timestamp()
        storage.update(
            dict(
                work=True,
                name=name,
                url=url,
                visit_times=0,
                error_times=0,
                create_time=crt_time,
                last_visit_time=crt_time,
                key=key,
                interval=interval,
            ))

        return '监控已开启'

    @classmethod
    def async_user_handler(cls, storage_list: List[ServiceData]):
        for service_data in storage_list:
            cls.async_user(service_data)

    @staticmethod
    def get_key_of(url):
        try:
            with requests.get(url, timeout=3) as r:
                content = r.content  # type: bytes
        except Exception:
            raise WatchError.GET_URL

        return md5(content)

    @classmethod
    def async_user(cls, storage: ServiceData):
        data = storage.classify()
        data.interval = data.interval or cls.PInterval.p.default_value

        if not data.work:
            return

        crt_time = datetime.datetime.now().timestamp()
        if data.last_visit_time + 60 * data.interval > crt_time:
            return

        data.last_visit_time = crt_time
        data.visit_times += 1

        try:
            key = cls.get_key_of(data.url)
            data.error_times = 0
        except E:
            data.error_times += 1
            if data.error_times == 3:
                Phone.announce(storage.user, cls,
                               '监控任务%s网页连续三次无法访问,已停止任务' % data.name)
                storage.update(dict(work=False))
            return

        if data.key != key:
            Phone.announce(storage.user, cls, '监控任务%s的网页发生变化' % data.name)
            storage.update(dict(work=False))
            return

        storage.update(data)
Beispiel #22
0
class BOCService(Service):
    name = 'boc'
    desc = '中银外汇牌价监测'
    long_desc = Lines(
        '监测中国银行外汇牌价',
        '⚠️支持多个币种现汇/现钞的买入/卖出价格',
        '⚠️使用短信提醒功能时需要设定具体的现汇/现钞和买入/卖出参数',
        '👉通过boc GBP -a命令获取英镑(GBP)的实时卖出价',
        '👉通过boc -s命令获取货币简写名称列表',
        '👉通过boc USA --ask --bn --sms=min命令监测美元的现钞卖出价,价格低于历史时会发短信提醒',
    )

    FX = {
        'GBP': '英镑',
        'UK': '英镑',
        'HKD': '港币',
        'HK': '港币',
        'USD': '美元',
        'US': '美元',
        'USA': '美元',
        'CHF': '瑞士法郎',
        'DEM': '德国马克',
        'FRF': '法国法郎',
        'FF': '法国法郎',
        'SGD': '新加坡元',
        'SEK': '瑞典克朗',
        'DKK': '丹麦克朗',
        'NOK': '挪威克朗',
        'JPY': '日元',
        'JP': '日元',
        'CAD': '加拿大元',
        'CA': '加拿大元',
        'AUD': '澳大利亚元',
        'AU': '澳大利亚元',
        'EUR': '欧元',
        'EU': '欧元',
        'MOP': '澳门元',
        'MO': '澳门元',
        'PHP': '菲律宾比索',
        'THB': '泰国铢',
        'NZD': '新西兰元',
        'KIWI': '新西兰元',
        'WON': '韩元',
        'SK': '韩元',
        'RUB': '卢布',
        'RU': '卢布',
        'MYR': '林吉特',
        'SEN': '林吉特',
        'NTD': '新台币',
        'TW': '新台币',
        'ESP': '西班牙比塞塔',
        'ITL': '意大利里拉',
        'ANG': '荷兰盾',
        'BEF': '比利时法郎',
        'FIM': '芬兰马克',
        'INR': '印度卢比',
        'IDR': '印尼卢比',
        'BRL': '巴西里亚尔',
        'AED': '阿联酋迪拉姆',
        'ZAF': '南非兰特',
        'SAR': '沙特里亚尔',
        'TRY': '土耳其里拉',
        'YTL': '土耳其里拉'
    }

    FX_REVERSE = dict()

    KEY_TRANS = dict(SE_BID='现汇买入价',
                     BN_BID='现钞买入价',
                     SE_ASK='现汇卖出价',
                     BN_ASK='现钞卖出价')
    M_TRANS = dict(min='低', max='高')

    async_user_task = True

    START = 1
    STOP = 0

    PSpotEx = Parameter(P(read_name='现汇价').default(), long='se')
    PBankNo = Parameter(P(read_name='现钞价').default(), long='bn')
    PBid = Parameter(P(read_name='买入价').default(), long='bid', short='b')
    PAsk = Parameter(P(read_name='卖出价').default(), long='ask', short='a')
    PShow = Parameter(P(read_name='显示货币简写列表').default(),
                      long='show',
                      short='s')
    PSms = Parameter(P(read_name='短信提醒').validate(sms_validator), long='sms')
    PSmsStop = Parameter(P(read_name='停止短信提醒').default(), long='sms-stop')

    @classmethod
    def init(cls):
        cls.validate(cls.PSpotEx, cls.PBankNo, cls.PBid, cls.PAsk, cls.PShow,
                     cls.PSms, cls.PSmsStop)
        for k in cls.FX:
            if cls.FX[k] in cls.FX_REVERSE:
                cls.FX_REVERSE[cls.FX[k]].append(k)
            else:
                cls.FX_REVERSE[cls.FX[k]] = [k]

    @classmethod
    def async_user_handler(cls, storage_list: List[ServiceData]):
        for service_data in storage_list:
            cls.async_user(service_data)

    @classmethod
    def run(cls, directory: 'Service', storage: ServiceData, pd: ParamDict,
            *args):
        data = storage.classify()

        if pd.has(cls.PShow):
            return Lines(*[
                '%s:%s' % (k, '或'.join(cls.FX_REVERSE[k]))
                for k in cls.FX_REVERSE
            ])

        if pd.has(cls.PSmsStop):
            if data.status == cls.START:
                data.status = cls.STOP
                storage.update(data)
                raise BOCError.STOP
            raise BOCError.NOT_START

        if not args:
            return cls.need_help()

        currency = args[0].upper()
        if currency not in cls.FX:
            raise BOCError.CURRENCY

        if pd.has(cls.PSms):
            storage.user.require_phone()
            if not (pd.has(cls.PSpotEx) ^ pd.has(cls.PBankNo)):
                raise BOCError.SE_BN
            if not (pd.has(cls.PAsk) ^ pd.has(cls.PBid)):
                raise BOCError.BID_ASK

            sort = ('SE' if pd.has(cls.PSpotEx) else 'BN') + ','
            sort += 'ASK' if pd.has(cls.PAsk) else 'BID'
            storage.update(
                dict(
                    currency=currency,
                    sort=sort,
                    monitor=pd.get(cls.PSms),
                    value=None,
                    status=cls.START,
                ))
            raise BOCError.START

        try:
            keys, values = bocfx(currency)
        except Exception as e:
            raise BOCError.SERVICE_INACCESSIBLE(debug_message=e)

        lines = []
        time = '实时'
        for i, k in enumerate(keys):
            if k in cls.KEY_TRANS:
                if pd.has(cls.PSpotEx) ^ pd.has(cls.PBankNo):
                    if pd.has(cls.PSpotEx) ^ ('SE' in k):
                        continue
                if pd.has(cls.PAsk) ^ pd.has(cls.PBid):
                    if pd.has(cls.PAsk) ^ ('ASK' in k):
                        continue
                lines.append('%s:%s' % (cls.KEY_TRANS[k], values[i]))
            if k == 'Time':
                time = values[i]
        lines.insert(0, '中国银行%s牌价(%s)' % (cls.FX[currency], time))
        return Lines(*lines)

    @classmethod
    def async_user(cls, storage: ServiceData):
        data = storage.classify()

        if not data.status:
            return
        if not data.error_times:
            data.error_times = 0

        crt_time = datetime.datetime.now().timestamp()
        if data.last_visit_time and data.last_visit_time + 60 * 60 > crt_time:
            return

        data.last_visit_time = crt_time

        try:
            value = bocfx(data.currency, data.sort)
        except E:
            data.error_times += 1
            if data.error_times == 3:
                Phone.announce(storage.user, cls,
                               '中银%s汇率连续三次无法访问,已停止任务' % cls.FX[data.currency])
                storage.update(dict(status=cls.STOP))
            return

        value = float(value[0])
        if not data.value or ((data.value > value) ^ (data.monitor == 'max')):
            data.value = value
            message = str(value) + '!' + \
                      '中银%s的%s达到历史新' % (cls.FX[data.currency], cls.KEY_TRANS[data.sort.replace(',', '_')]) + \
                      cls.M_TRANS[data.monitor] + '。'
            Phone.announce(storage.user, cls, message)

        storage.update(data)
Beispiel #23
0

def get_url(url):
    import re
    pattern = re.compile(
        r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!#*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
    )  # 匹配模式

    urls = re.findall(pattern, url)
    if urls:
        return urls[0]
    raise Error.NO_URL


param_list = [
    P('url').process(parse.unquote),
    P('v').default(1).process(int),
]


def check_support(url, v):
    web_str = ''
    new_support_str = ''

    for web in websites:
        if web.detect(url):
            if v < web.SUPPORT_VERSION:
                raise Error.NEW_VERSION_SUPPORT
            return web
        web_str += web.NAME + ' '
        if v < web.SUPPORT_VERSION:
Beispiel #24
0
class CommentP:
    content, reply_to = Comment.P('content', 'reply_to')
    cid_getter = P('cid',
                   yield_name='comment').process(int).process(Comment.get)
    reply_to_getter = reply_to.process(Comment.get)
Beispiel #25
0
class SMSService(Service):
    name = 'sms'
    desc = '共享手机短信'
    long_desc = Lines(
        '浏览某些不重要的网站且需要手机号注册时,本工具可以提供共享手机号。',
        '通过sms -g命令获取当前手机号,通过sms -s命令获取接收到的短信(由于手机号共享,收到的短信可能还有其他用户的,您收到的短信也公开),通过sms -r命令获取新手机号'
    )

    async_service_task = True

    PGet = Parameter(P(read_name='获取当前手机号').default(), long='get', short='g')
    PShow = Parameter(P(read_name='显示短信').default(), long='show', short='s')
    PRenew = Parameter(P(read_name='获取新手机号').default(),
                       long='renew',
                       short='r')

    crawler = FreeReceiveSMS()

    @classmethod
    def init(cls):
        cls.validate(cls.PGet, cls.PShow, cls.PRenew)

    @classmethod
    def run(cls, directory: 'Service', storage: ServiceData, pd: ParamDict,
            *args):
        data = storage.classify()

        if pd.has(cls.PRenew):
            global_storage = cls.get_global_storage()
            global_data = global_storage.classify()
            if not global_data.phones:
                raise SMSMessage.NONE
            phone_num = len(global_data.phones)
            phone_index = random.randint(0, phone_num - 1)
            data.phone = global_data.phones[phone_index]
            storage.update(data)
            return data.phone

        if not data.phone:
            raise SMSMessage.NO_PHONE

        if pd.has(cls.PGet):
            return data.phone

        if pd.has(cls.PShow):
            lines = cls.crawler.get_msg(data, service=cls)
            return Lines(*lines)

        return cls.need_help()

    @classmethod
    def async_service(cls, storage: ServiceData):
        data = storage.classify()

        last_time = data.last_update_time or 0
        crt_time = datetime.datetime.now().timestamp()
        if last_time + 60 * 30 > crt_time:
            return

        data.last_update_time = crt_time
        data.error_web_times = data.error_web_times or 0
        data.error_re_times = data.error_re_times or 0

        data.phones = cls.crawler.get_phone_list(data) or []
        storage.update(data)