示例#1
0
 def __init__(self):
     super().__init__()
     # self.authors = {}
     self.posts_num = 0
     self.voted_posts = 0
     self.curator = SteemAccount(self.by())
     self.followings = self.curator.get_followings()
示例#2
0
 def _get_reply_body(self, message_id, author):
     account = SteemAccount(author)
     comments_num = account.remaining_comments() or ''
     daily_comments_num = round(account.daily_recovery_comments(), 1) or ''
     return get_message(message_id).format(
         name=author,
         comments_num=comments_num,
         daily_comments_num=daily_comments_num)
示例#3
0
 def get_votes(self, authors, up=None):
     votes = []
     for author in authors:
         acc = SteemAccount(author=author)
         my_votes = acc.get_votes(up)
         for v in my_votes:
             v['voter'] = author
         votes += my_votes
     return votes
示例#4
0
class CnReaderVoter(VoteRecipe):
    def __init__(self):
        super().__init__()
        # self.authors = {}
        self.posts_num = 0
        self.voted_posts = 0
        self.curator = SteemAccount(self.by())
        self.followings = self.curator.get_followings()

    def mode(self):
        return "query.comment.post"

    def config(self):
        return {
            "account": RESTEEM_ACCOUNT,
            "days": CURATION_CYCLE,
            "reblog": True
        }

    def by(self):
        return VOTER_ACCOUNT

    def what_to_vote(self, ops):
        if not self.ops.is_upvoted_by(self.by()):
            logger.info("We will vote the post {}".format(self.ops.get_url()))
            self.posts_num += 1
            return True
        return False

    def who_to_vote(self, author):
        if not author in self.followings:
            self.curator.follow(author)
            logger.info("follow the new author @{}".format(author))
            self.followings.append(author)
        return True

    def when_to_vote(self, ops):
        return VOTE_TIMING  # mins

    def how_to_vote(self, post):
        self.voted_posts += 1
        logger.info("voting {} / {} posts".format(self.voted_posts,
                                                  self.posts_num))
        weight = self.voter.estimate_vote_pct_for_n_votes(
            days=CURATION_CYCLE, n=self.posts_num) * VOTE_PERCENTAGE
        if weight > UPVOTE_LIMIT:
            weight = UPVOTE_LIMIT
        return weight

    def after_success(self, res):
        if self.voted_posts == self.posts_num:
            logger.info("Done with voting. Exit.")
            sys.exit()
示例#5
0
    def _get_daily_blog_body(self, message_id):
        delta = 0.05
        daily_replies = self._get_replies("welcome", 1.0 - delta)  # 1 days
        weekly_replies = self._get_replies("welcome", 7.0 - delta)  # 7 days

        daily_total = len(daily_replies)
        weekly_total = len(weekly_replies)

        articles = [
            ("@{}".format(r['receiver']),
             "<a href=\"{}\">{}</a>".format(self._get_accessible_url(r['url']),
                                            r['title'])) for r in daily_replies
        ]
        articles_table = build_table(["作者", "文章"], articles)

        stats = []
        for r in weekly_replies:
            author = r['receiver']
            account = SteemAccount(author)
            steemd_link = "{}/@{}".format(STEEMD_HOST, author)
            row = ("@{}".format(author), round(account.age_in_days(), 1),
                   round(account.reputation(),
                         1), "<a href=\"{}\">{}%</a>".format(
                             steemd_link, round(account.rc_percentage(), 1)),
                   round(account.steem_power(),
                         1), account.follower_count(), account.post_count())
            stats.append(row)
        stats = sorted(stats, key=(lambda row: row[1]), reverse=False)
        stats_table = build_table(
            ["新人", "天数", "声望", "活动能量", "Steem Power", "粉丝数", "发帖数"], stats)

        return get_message(message_id).format(daily_total=daily_total,
                                              weekly_total=weekly_total,
                                              articles_table=articles_table,
                                              stats_table=stats_table)
示例#6
0
class ClaimBot:

    def __init__(self):
        self.claimer_author = settings.get_env_var(PILOT_ACCOUNT_KEY) or DEFAULT_PILOT_ACCOUNT
        self.claimer_account = SteemAccount(author=self.claimer_author)

    def get_users(self):
        users = []
        delegations = self.claimer_account.incoming_delegations()
        for delegation in delegations:
            vesting_shares = float(delegation["vesting_shares"]["amount"])
            if vesting_shares > MINIMUM_SP_DELEGATION:
                users.append(delegation["delegator"])
        return users

    def claim_all_accounts(self):
        users = self.get_users()
        logger.info("The current users are : {}".format(users))
        for user in users:
            logger.info("Claim rewards for @{}".format(user))
            self.claim_all_scot_tokens(user)

    def claim_scot_token(self, author, token):
        claimer = Claimer(author)
        claimer.claim_scot_token(token)

    def claim_all_scot_tokens(self, author):
        claimer = Claimer(author)
        claimer.claim_all_scot_tokens()
    def who_to_vote(self, author):
        if author in BLACKLIST:
            logger.info("Skip [{}] who is in my blacklist".format(author))
            return False

        account = SteemAccount(author)
        if account.reputation() < ACCOUNT_REPUTATION_THRESHOLD:
            logger.info("Skip [{}] whose reputation is too low".format(author))
            return False

        if self.authors.get(author) is None:
            self.authors[author] = 1
            self.posts_num += 1
            return True
        elif self.authors.get(author) < VOTE_PER_ACCOUNT_LIMIT:
            self.authors[author] += 1
            self.posts_num += 1
            return True
        elif self.authors.get(author) >= VOTE_PER_ACCOUNT_LIMIT:
            return False
        return False
示例#8
0
 def _add_reply_record(self, receiver, message_id, post, timestamp=None):
     if receiver and message_id and post:
         if not self._has_reply_record(receiver, message_id):
             timestamp = timestamp or datetime.now(pytz.utc)
             reply = {
                 "receiver": receiver,
                 "reputation": SteemAccount(receiver).reputation(),
                 "message_id": message_id,
                 "url": post.get_url(),
                 "title": post.get_comment().title,
                 "updated": timestamp
             }
             self.db.insert_reply(reply)
             logger.info(
                 "Add reply to author @{} with message [{}] into database".
                 format(receiver, message_id))
             return True
     return False
示例#9
0
def curation_rewards(username):
    if username.startswith("@"):
        username = username.replace("@", "")
    s = get_steem_conn()
    account = Account(username, s).set_account_deta()
    info = s.get_dynamic_global_properties()
    checkpoint_val = request.args.get("checkpoint")
    total_sp, total_rshares, checkpoints = get_curation_rewards(
        SteemAccount(username, steemd_instance=s),
        info,
        checkpoint_val=checkpoint_val)
    return render_template(
        "curation_rewards.html",
        account=account,
        total_sp=round(total_sp, 2),
        total_rshares=total_rshares,
        checkpoints=checkpoints,
    )
示例#10
0
    def update_config(self, incremental=False):
        if not self.account:
            return

        domain = self._get_domain()
        organization = BLOG_ORGANIZATION
        logo = BLOG_AVATAR
        favicon = BLOG_FAVICON

        language = settings.get_env_var("LANGUAGE") or "en"

        a = SteemAccount(self.account)
        author = self.account
        name = self._yaml_compatible(a.get_profile("name"), "")
        avatar = self._yaml_compatible(a.avatar(), "")
        # about = a.get_profile("about") or ""
        location = self._yaml_compatible(a.get_profile("location"), "")
        website = self._yaml_compatible(a.get_profile("website"), "''")
        incremental = "true" if incremental else "false"

        # build config file with template
        template = get_message("config")
        config = template.format(organization=organization,
                                 domain=domain,
                                 language=language,
                                 name=name,
                                 author=author,
                                 incremental=incremental)
        filename = CONFIG_FILE
        with open(filename, "w", encoding="utf-8") as f:
            f.write(config)
        logger.info("{} file has been updated for the account @{}".format(
            filename, author))

        # build config theme file with template
        template = get_message("config.theme")
        config = template.format(organization=organization,
                                 favicon=favicon,
                                 logo=logo,
                                 author=author,
                                 name=name,
                                 location=location,
                                 avatar=avatar,
                                 website=website)
        filename = CONFIG_THEME_FILE
        with open(filename, "w", encoding="utf-8") as f:
            f.write(config)
        logger.info("{} file has been updated for the account @{}".format(
            filename, author))
示例#11
0
 def __init__(self, author):
     self.author = author
     self.account = SteemAccount(self.author)
     self.vp_limit = {}
示例#12
0
class Voter:
    def __init__(self, author):
        self.author = author
        self.account = SteemAccount(self.author)
        self.vp_limit = {}

    def vote(self, post, weight=100):
        if post:
            if weight and weight >= -100 and weight <= 100:
                if weight > 0:
                    if self.has_vp(up=True):
                        return self._upvote(post, weight)
                    else:
                        logger.error("{} has no enough VP for upvote".format(
                            self.author))
                else:
                    if self.has_vp(up=False):
                        return self._downvote(post, weight)
                    else:
                        logger.error("{} has no enough VP for downvote".format(
                            self.author))
            else:
                logger.error(
                    "Failed: the vote weight {} exceeds the range [-100, 100]".
                    format(weight))
        return False

    def _upvote(self, post, weight):
        c = SteemComment(comment=post)
        if not c.is_upvoted_by(self.author):
            post.upvote(weight=weight, voter=self.author)
            logger.info(
                "Upvoted to [{}] [{}] with weight [{:.2f}] successfully".
                format(post.title, c.get_url(), weight))
            return True
        else:
            logger.info(
                "Skip upvote because I already upvoted this post [{}]  [{}]".
                format(post.title, c.get_url()))
            return False

    def _downvote(self, post, weight):
        c = SteemComment(comment=post)
        if not c.is_downvoted_by(self.author):
            post.downvote(weight=weight, voter=self.author)
            logger.info(
                "Downvoted to [{}] [{}] with weight [{:.2f}] successfully".
                format(post.title, c.get_url(), weight))
            return True
        else:
            logger.info(
                "Skip downvote because I already downvoted this post [{}] [{}]"
                .format(post.title, c.get_url()))
            return False

    def estimate_vote_value_for_token(self, symbol, weight=100, up=True):
        token_voting_power = self.account.get_scot_voting_power(symbol, up)
        scot_staked = self.account.get_scot_staked(symbol)
        multiplier = self.account.get_vote_multiplier(symbol, up)

        pending_rshares = scot_token_info(symbol, "pending_rshares")
        reward_pool = scot_token_info(symbol, "reward_pool")
        precision = scot_token_info(symbol, "precision")
        author_curve_exponent = scot_token_config(symbol,
                                                  "author_curve_exponent")

        # print ("estimate_vote_value", token_voting_power, scot_staked, pending_rshares, reward_pool, author_curve_exponent, multiplier)

        def apply_reward_curve(rshares):
            return pow(max(0, rshares),
                       author_curve_exponent) * reward_pool / pending_rshares

        direction = 1 if up else -1
        rshares = float(up) * float(scot_staked) * min(
            abs(multiplier * weight),
            100) * float(token_voting_power) / (10000 * 100)
        # newValue = apply_reward_curve(voteRshares + rshares);
        # print ("reshares", rshares)
        value = apply_reward_curve(rshares)
        return round(value / pow(10, precision), precision)

    def estimate_vote_pct_for_token(self, symbol, value):
        up = True if value >= 0 else False
        token_voting_power = self.account.get_scot_voting_power(symbol, up)
        scot_staked = self.account.get_scot_staked(symbol)
        multiplier = self.account.get_vote_multiplier(symbol, up)

        pending_rshares = scot_token_info(symbol, "pending_rshares")
        reward_pool = scot_token_info(symbol, "reward_pool")
        precision = scot_token_info(symbol, "precision")
        author_curve_exponent = scot_token_config(symbol,
                                                  "author_curve_exponent")

        # print ("get_vote_pct_for_token", token_voting_power, scot_staked, pending_rshares, reward_pool, author_curve_exponent, multiplier)

        def get_rshares_from_reward(reward):
            return pow(pending_rshares * reward / reward_pool,
                       1.0 / author_curve_exponent)

        if token_voting_power and scot_staked and pending_rshares and reward_pool and author_curve_exponent and multiplier:
            # calculation method
            # vote_value = vote_weight / 100 * voting_power / 100 * rshares / pending_rshares * reward_pool
            # reference: https://busy.org/@holger80/palnet-how-to-check-your-voting-power-and-your-pal-vote-value
            value = value * pow(10, precision)
            rshares = get_rshares_from_reward(value)
            # print ("reshares", rshares)
            vote_weight = 10000.0 * rshares / float(
                token_voting_power) / float(scot_staked / 100.0) / multiplier
            return vote_weight
        else:
            return None

    def set_vp_limit(self, token, limit):
        if token and limit:
            self.vp_limit[token] = limit

    def get_vp_limit(self, token):
        if token and token in self.vp_limit:
            return self.vp_limit[token]
        else:
            return 0

    def has_vp(self, token=None, up=True):
        if token:
            vp = self.account.get_scot_voting_power(token, up)
            if vp:
                if float(vp) / 100 >= self.get_vp_limit(token):
                    return True
            return False
        else:
            for k, v in self.vp_limit.items():
                vp = self.account.get_scot_voting_power(k, up)
                if not vp or float(vp) / 100 < float(v):
                    return False
            return True

    def estimate_vote_pct_for_n_votes(self, days, n):
        total_SBD = self.account.account.steem.sp_to_sbd(
            sp=self.account.steem_power()) * 10 * float(days)
        return float(self.account.account.get_vote_pct_for_SBD(
            total_SBD / n)) / 100
示例#13
0
 def __init__(self, account):
     self.account = SteemAccount(account)
     self.transfers = None
     self.se_wallet = Wallet(self.account.author)
示例#14
0
 def __init__(self):
     self.claimer_author = settings.get_env_var(PILOT_ACCOUNT_KEY) or DEFAULT_PILOT_ACCOUNT
     self.claimer_account = SteemAccount(author=self.claimer_author)