Exemplo n.º 1
0
def num_or_else(cand: Any) -> numbers.Number:
    asint = flow.silent(int)(cand)
    if decl.numeric(asint):
        return asint
    asfloat = flow.silent(float)(cand)
    if decl.numeric(asfloat):
        return asfloat
    return cand
Exemplo n.º 2
0
def test_print_errors():
    def error():
        1 / 0

    f = print_errors(error)
    assert f.__name__ == 'error'
    assert 'ZeroDivisionError' in capture(silent(f))

    g = print_errors(stack=False)(error)
    assert g.__name__ == 'error'
    assert capture(silent(g)).startswith('ZeroDivisionError')
Exemplo n.º 3
0
def test_print_errors():
    def error():
        1 / 0

    f = print_errors(error)
    assert f.__name__ == 'error'
    assert 'ZeroDivisionError' in capture(silent(f))

    g = print_errors(stack=False)(error)
    assert g.__name__ == 'error'
    assert capture(silent(g)).startswith('ZeroDivisionError')
Exemplo n.º 4
0
def test_log_errors():
    log = []

    @log_errors(log.append)
    def f(x):
        return 1 / x

    silent(f)(1)
    silent(f)(0)
    assert len(log) == 1
    assert log[0].startswith('Traceback')
    assert re.search(r'ZeroDivisionError: .*\n    raised in f\(0\)$', log[0])
Exemplo n.º 5
0
def test_log_calls_raise():
    log = []

    @log_calls(log.append, stack=False)
    def f():
        raise Exception('something bad')

    silent(f)()
    assert log == [
        "Call f()",
        "-> Exception: something bad raised in f()",
    ]
Exemplo n.º 6
0
def test_log_errors():
    log = []

    @log_errors(log.append)
    def f(x):
        return 1 / x

    silent(f)(1)
    silent(f)(0)
    assert len(log) == 1
    assert log[0].startswith('Traceback')
    assert re.search(r'ZeroDivisionError: .*\n    raised in f\(0\)$', log[0])
Exemplo n.º 7
0
def test_log_calls_raise():
    log = []

    @log_calls(log.append, stack=False)
    def f():
        raise Exception('something bad')

    silent(f)()
    assert log == [
        "Call f()",
        "-> Exception: something bad raised in f()",
    ]
Exemplo n.º 8
0
    def take(self, limit=5):
        """ Take up to n (n = limit) posts/comments at a time.

        You can call this method as many times as you want. Once
        there are no more posts to take, it will return [].

        Returns:
            List of posts/comments in a batch of size up to `limit`.
        """
        # get main posts only
        comment_filter = is_comment if self.comments_only else complement(
            is_comment)
        hist = filter(comment_filter, self.history)

        # filter out reblogs
        def match_author(x):
            return x['author'] == self.account.name

        hist2 = filter(match_author, hist)

        # post edits will re-appear in history
        # we should therefore filter out already seen posts
        def ensure_unique(post):
            if post['permlink'] not in self.seen_items:
                self.seen_items.add(post['permlink'])
                return True

        unique = filter(ensure_unique, hist2)

        serialized = filter(bool, map(silent(Post), unique))

        batch = take(limit, serialized)
        return batch
Exemplo n.º 9
0
    def take(self, limit=5):
        """ Take up to n (n = limit) posts/comments at a time.

        You can call this method as many times as you want. Once
        there are no more posts to take, it will return [].

        Returns:
            List of posts/comments in a batch of size up to `limit`.
        """
        # get main posts only
        comment_filter = is_comment if self.comments_only else complement(
            is_comment)
        hist = filter(comment_filter, self.history)

        # filter out reblogs
        def match_author(x):
            return x['author'] == self.account.name

        hist2 = filter(match_author, hist)

        # post edits will re-appear in history
        # we should therefore filter out already seen posts
        def ensure_unique(post):
            if post['permlink'] not in self.seen_items:
                self.seen_items.add(post['permlink'])
                return True

        unique = filter(ensure_unique, hist2)

        serialized = filter(bool, map(silent(Post), unique))

        batch = take(limit, serialized)
        return batch
Exemplo n.º 10
0
    def steem_btc_ticker():
        prices = {}
        urls = [
            "https://poloniex.com/public?command=returnTicker",
            "https://bittrex.com/api/v1.1/public/getmarketsummary?market=BTC-STEEM",
        ]
        responses = list(silent(requests.get)(u, timeout=30) for u in urls)

        for r in [
                x for x in responses if hasattr(x, "status_code")
                and x.status_code == 200 and x.json()
        ]:
            if "poloniex" in r.url:
                data = r.json()["BTC_STEEM"]
                prices['poloniex'] = {
                    'price': float(data['last']),
                    'volume': float(data['baseVolume'])
                }
            elif "bittrex" in r.url:
                data = r.json()["result"][0]
                price = (data['Bid'] + data['Ask']) / 2
                prices['bittrex'] = {
                    'price': price,
                    'volume': data['BaseVolume']
                }

        if len(prices) == 0:
            raise RuntimeError(
                "Obtaining STEEM/BTC prices has failed from all sources.")

        return Tickers._wva([x['price'] for x in prices.values()],
                            [x['volume'] for x in prices.values()])
Exemplo n.º 11
0
def get_multi(urls):
    """ A generator of successful url fetching responses. """
    with rs.Session() as s:
        for url in urls:
            resp = silent(get_safe)(url, session=s)
            if resp:
                yield resp
Exemplo n.º 12
0
    def sbd_btc_ticker(verbose=False):
        prices = {}
        urls = [
            "https://poloniex.com/public?command=returnTicker",
            "https://bittrex.com/api/v1.1/public/getticker?market=BTC-SBD",
        ]
        responses = list(silent(requests.get)(u, timeout=5) for u in urls)

        for r in [
                x for x in responses if hasattr(x, "status_code")
                and x.status_code == 200 and x.json()
        ]:
            if "poloniex" in r.url:
                data = r.json()["BTC_SBD"]
                if verbose:
                    print("Spread on Poloniex is %.2f%%" % Tickers.calc_spread(
                        data['highestBid'], data['lowestAsk']))
                prices['poloniex'] = {
                    'price': float(data['last']),
                    'volume': float(data['baseVolume'])
                }
            elif "bittrex" in r.url:
                data = r.json()["result"]
                if verbose:
                    print("Spread on Bittfex is %.2f%%" %
                          Tickers.calc_spread(data['Bid'] + data['Ask']))
                price = (data['Bid'] + data['Ask']) / 2
                prices['bittrex'] = {'price': price, 'volume': 0}

        if len(prices) == 0:
            raise RuntimeError(
                "Obtaining SBD/BTC prices has failed from all sources.")

        return mean([x['price'] for x in prices.values()])
Exemplo n.º 13
0
    def btc_usd_ticker(verbose=False):
        prices = {}
        urls = [
            "https://api.bitfinex.com/v1/pubticker/BTCUSD",
            # "https://api.coinbase.com/v2/prices/BTC-USD/spot",
            "https://api.kraken.com/0/public/Ticker?pair=XBTUSD",
            "https://www.okcoin.com/api/v1/ticker.do?symbol=btc_usd",
            "https://www.bitstamp.net/api/v2/ticker/btcusd/",
            "https://btc-e.com/api/2/btc_usd/ticker",
        ]
        responses = list(silent(requests.get)(u, timeout=5) for u in urls)

        for r in [
                x for x in responses if hasattr(x, "status_code")
                and x.status_code == 200 and x.json()
        ]:
            if "bitfinex" in r.url:
                data = r.json()
                prices['bitfinex'] = {
                    'price': float(data['last_price']),
                    'volume': float(data['volume'])
                }
            elif "kraken" in r.url:
                data = r.json()['result']['XXBTZUSD']['p']
                prices['kraken'] = {
                    'price': float(data[0]),
                    'volume': float(data[1])
                }
            elif "okcoin" in r.url:
                data = r.json()["ticker"]
                prices['okcoin'] = {
                    'price': float(data['last']),
                    'volume': float(data['vol'])
                }
            elif "bitstamp" in r.url:
                data = r.json()
                prices['bitstamp'] = {
                    'price': float(data['last']),
                    'volume': float(data['volume'])
                }
            elif "btce" in r.url:
                data = r.json()["ticker"]
                prices['btce'] = {
                    'price': float(data['avg']),
                    'volume': float(data['vol_cur'])
                }

        if verbose:
            pprint(prices)

        if len(prices) == 0:
            raise RuntimeError(
                "Obtaining BTC/USD prices has failed from all sources.")

        # vwap
        return Tickers._wva([x['price'] for x in prices.values()],
                            [x['volume'] for x in prices.values()])
Exemplo n.º 14
0
    def refresh(self):
        post_author, post_permlink = resolve_identifier(self.identifier)
        post = self.steemd.get_content(post_author, post_permlink)
        if not post["permlink"]:
            raise PostDoesNotExist("Post does not exist: %s" % self.identifier)

        # If this 'post' comes from an operation, it might carry a patch
        if "body" in post and re.match("^@@", post["body"]):
            self.patched = True

        # Parse Times
        parse_times = ["active",
                       "cashout_time",
                       "created",
                       "last_payout",
                       "last_update",
                       "max_cashout_time"]
        for p in parse_times:
            post[p] = parse_time(post.get(p, "1970-01-01T00:00:00"))

        # Parse Amounts
        sbd_amounts = [
            "total_payout_value",
            "max_accepted_payout",
            "pending_payout_value",
            "curator_payout_value",
            "total_pending_payout_value",
            "promoted",
        ]
        for p in sbd_amounts:
            post[p] = Amount(post.get(p, "0.000 SBD"))

        # turn json_metadata into python dict
        meta_str = post.get("json_metadata", "{}")
        post['json_metadata'] = silent(json.loads)(meta_str) or {}

        post["tags"] = []
        post['community'] = ''
        if isinstance(post['json_metadata'], dict):
            if post["depth"] == 0:
                post["tags"] = (
                    post["parent_permlink"],
                    *get_in(post, ['json_metadata', 'tags'], default=[])
                )

            post['community'] = get_in(post, ['json_metadata', 'community'], default='')

        # If this post is a comment, retrieve the root comment
        self.root_identifier, self.category = self._get_root_identifier(post)

        self._store_post(post)
Exemplo n.º 15
0
def handle_post(post):
    meta = silent(json.loads)(post['json_metadata']) or {}

    if not isinstance(meta, dict):
        return

    meta.setdefault('tags', post['parent_permlink'])

    if APP_TAG in meta['tags']:
        post = Post(post).export()
        if post['depth'] > 0:
            return

        del post['id']
        post['tags'] = list(post['tags'])
        post['json_metadata'] = fix_legacy_json(meta)
        PostModel.objects(url=post['url']).update(upsert=True, **post)

        print('saved', post['url'])
Exemplo n.º 16
0
 def get_replies(self):
     """ Return **first-level** comments of the post.
     """
     post_author, post_permlink = resolve_identifier(self.identifier)
     replies = self.dpayd.get_content_replies(post_author, post_permlink)
     return map(silent(Post), replies)
Exemplo n.º 17
0
    def post(self,
             title,
             body,
             author,
             permlink=None,
             reply_identifier=None,
             json_metadata=None,
             comment_options=None,
             community=None,
             tags=None,
             beneficiaries=None,
             self_vote=False):
        """ Create a new post.

        If this post is intended as a reply/comment, `reply_identifier` needs
        to be set with the identifier of the parent post/comment (eg.
        `author/permlink`).

        Optionally you can also set json_metadata, comment_options and upvote
        the newly created post as an author.

        Setting category, tags or community will override the values provided
        in json_metadata and/or comment_options where appropriate.

        Args:

        title (str): Title of the post
        body (str): Body of the post/comment
        author (str): Account are you posting from
        permlink (str): Manually set the permlink (defaults to None).
            If left empty, it will be derived from title automatically.
        reply_identifier (str): Identifier of the parent post/comment (only
            if this post is a reply/comment).
        json_metadata (str, dict): JSON meta object that can be attached to
            the post.
        comment_options (str, dict): JSON options object that can be
            attached to the post.

        Example::
            comment_options = {
                'max_accepted_payout': '1000000.000 SMOKE',
                'allow_votes': True,
                'allow_curation_rewards': True,
                'extensions': [[0, {
                    'beneficiaries': [
                        {'account': 'account1', 'weight': 5000},
                        {'account': 'account2', 'weight': 5000},
                    ]}
                ]]
            }

        community (str): (Optional) Name of the community we are posting
            into. This will also override the community specified in
            `json_metadata`.

        tags (str, list): (Optional) A list of tags (5 max) to go with the
            post. This will also override the tags specified in
            `json_metadata`. The first tag will be used as a 'category'. If
            provided as a string, it should be space separated.

        beneficiaries (list of dicts): (Optional) A list of beneficiaries
            for posting reward distribution. This argument overrides
            beneficiaries as specified in `comment_options`.

        For example, if we would like to split rewards between account1 and
        account2::

            beneficiaries = [
                {'account': 'account1', 'weight': 5000},
                {'account': 'account2', 'weight': 5000}
            ]

        self_vote (bool): (Optional) Upvote the post as author, right after
            posting.

        """

        # prepare json_metadata
        json_metadata = json_metadata or {}
        if isinstance(json_metadata, str):
            json_metadata = silent(json.loads)(json_metadata) or {}

        # override the community
        if community:
            json_metadata.update({'community': community})

        # deal with the category and tags
        if isinstance(tags, str):
            tags = list(set(filter(None, (re.split("[\W_]", tags)))))

        category = None
        tags = tags or json_metadata.get('tags', [])
        if tags:
            if len(tags) > 5:
                raise ValueError('Can only specify up to 5 tags per post.')

            # first tag should be a category
            category = tags[0]
            json_metadata.update({"tags": tags})

        # can't provide a category while replying to a post
        if reply_identifier and category:
            category = None

        # deal with replies/categories
        if reply_identifier:
            parent_author, parent_permlink = resolve_identifier(
                reply_identifier)
            if not permlink:
                permlink = derive_permlink(title, parent_permlink)
        elif category:
            parent_permlink = derive_permlink(category)
            parent_author = ""
            if not permlink:
                permlink = derive_permlink(title)
        else:
            parent_author = ""
            parent_permlink = ""
            if not permlink:
                permlink = derive_permlink(title)

        post_op = operations.Comment(
            **{
                "parent_author": parent_author,
                "parent_permlink": parent_permlink,
                "author": author,
                "permlink": permlink,
                "title": title,
                "body": body,
                "json_metadata": json_metadata
            })
        ops = [post_op]

        # if comment_options are used, add a new op to the transaction
        if comment_options or beneficiaries:
            options = keep_in_dict(comment_options or {}, [
                'max_accepted_payout', 'percent_steem_dollars', 'allow_votes',
                'allow_curation_rewards', 'extensions'
            ])
            # override beneficiaries extension
            if beneficiaries:
                # validate schema
                # or just simply vo.Schema([{'account': str, 'weight': int}])
                schema = vo.Schema([{
                    vo.Required('account'):
                    vo.All(str, vo.Length(max=16)),
                    vo.Required('weight', default=10000):
                    vo.All(int, vo.Range(min=1, max=10000))
                }])
                schema(beneficiaries)
                options['beneficiaries'] = beneficiaries

            default_max_payout = "1000000.000 SMOKE"
            comment_op = operations.CommentOptions(
                **{
                    "author":
                    author,
                    "permlink":
                    permlink,
                    "max_accepted_payout":
                    options.get("max_accepted_payout", default_max_payout),
                    "percent_steem_dollars":
                    int(options.get("percent_steem_dollars", 10000)),
                    "allow_votes":
                    options.get("allow_votes", True),
                    "allow_curation_rewards":
                    options.get("allow_curation_rewards", True),
                    "extensions":
                    options.get("extensions", []),
                    "beneficiaries":
                    options.get("beneficiaries"),
                })
            ops.append(comment_op)

        if self_vote:
            vote_op = operations.Vote(
                **{
                    'voter': author,
                    'author': author,
                    'permlink': permlink,
                    'weight': 10000,
                })
            ops.append(vote_op)

        return self.finalizeOp(ops, author, "posting")