def get_latest_flags(self): flags = {} total_amount = 0 account = Account(self.account_for_flag_report, steemd_instance=self.steemd_instance) for vote in account.history_reverse(filter_by="vote"): if vote["weight"] > 0: continue if vote["voter"] != self.account_for_flag_report: continue ts = parse(vote["timestamp"]) if ts < (datetime.utcnow() - timedelta(days=1)): break try: p = Post("%s/%s" % (vote["author"], vote["permlink"]), steemd_instance=self.steemd_instance) except steembase.exceptions.PostDoesNotExist: logger.info("Couldnt load the post. %s" % vote["permlink"]) continue if vote["author"] not in flags: flags[vote.get("author")] = { "posts": 0, "comments": 0, "total_removed": 0 } if p.is_main_post(): flags[vote.get("author")].update( {"posts": flags[vote.get("author")]["posts"] + 1}) else: flags[vote.get("author")].update( {"comments": flags[vote.get("author")]["comments"] + 1}) logger.info("Analyzing %s" % self.url(p)) for active_vote in p.get("active_votes"): if float(active_vote.get("rshares")) > 0: continue if active_vote.get("voter") != self.account_for_flag_report: continue amount_removed = self.get_payout_from_rshares( active_vote.get("rshares")) total_amount += amount_removed flags[vote.get("author")].update({ "total_removed": flags[vote.get("author")]["total_removed"] + amount_removed, }) return flags, round(total_amount, 2)
def handle_curation(self, op_type, op_value): curators = [c["account"] for c in get_curators()] # we're only interested in votes if op_type != "vote": return # if the voter is not a trusted curator, skip it. if op_value.get("voter") not in curators: return # check the post if we have already voted? p = Post("%s/%s" % (op_value.get("author"), op_value.get("permlink")), steemd_instance=self.s) # we're only interested in main posts if not p.is_main_post(): return # the post is tagged with the tags we defined? if len(set(self.expected_tags).intersection(p.get("tags"))) == 0: return # is the author in the blacklist? if is_blacklisted(op_value.get("author")): return score = 0 already_voted = False curators_on_the_post = [] for active_vote in p.get("active_votes", []): if active_vote.get("voter") == self.bot_account: already_voted = True if active_vote.get("voter") in curators: score += active_vote.get("percent") curators_on_the_post.append({ "curator": active_vote.get("voter"), "weight": active_vote.get("percent"), }) # if we already voted on that, skip. if already_voted: return # if the score is lower then the threshold, skip. if score < int(get_option(THRESHOLD_OPTION_ID)["value"]): return bot_account = Account(self.bot_account, steemd_instance=self.s) weight = bot_account.voting_power() self.upvote(p, weight, self.bot_account) self.post_to_webhooks(p, curators_on_the_post, score, weight)
def getUpvoteCandidate(account): """ Gets link to comments author has not voted on but is within voting window Args: account: A Steem Account object. Returns: identifier of posts/comments within voting window not already voted on """ # Make sure we have the latest data account.refresh() epoch_last_vote = 0 # Get last 2000 votes from account history = account.get_account_history(-1, 1000, filter_by='comment') current_time = epochDiff() oldest_id = [] print('got history, now filtering...') for event in history: try: # Make sure we are the author if (event['author'] == account.name): # Not really needed due to filter if (event['type'] == 'comment'): # Double confirmation of comment if event['permlink'].startswith("re-"): epoch_last_vote = epochVote(event) elapsed_time = current_time - epoch_last_vote # Is post in within time limit if elapsed_time < cutofftime: # Get details of main post identifier = "@" + event[ 'parent_author'] + "/" + event[ 'parent_permlink'] parent = Post(identifier, s) while not parent.is_main_post(): identifier = "@" + parent[ 'parent_author'] + "/" + parent[ 'parent_permlink'] parent = Post(identifier, s) # Make sure Original post is in desired tag if targeted_tag in parent['tags']: identifier = "@" + event[ 'author'] + "/" + event['permlink'] # Store comment if it meets conditions oldest_id.append(identifier) else: # Everything else will be older than cutoff break except Exception as e: print('issue with history: ' + str(e)) # print(oldest_id) print('completed history search') return list(reversed(oldest_id))
def pending_payout(username): context = {} for post in steem.get_blog(username, 500, 500): post = Post(post["comment"]) if post.is_main_post() and post["author"] == username: if "1970-01-01 00:00:00" == str(post["last_payout"]): payout = Amount(post["pending_payout_value"]).amount if payout == 0: payout = (Amount(post["total_payout_value"]).amount + Amount(post["curator_payout_value"]).amount) context[post.title] = payout * 0.56 * 0.5 return context
def profile_as_json(): steemd_instance = get_steemd_instance() if request.method == "GET": links = request.args.get("links") else: links = request.form.get("links") rewards = [] links = links.split(",") for link in links: try: post = Post(link, steemd_instance=steemd_instance) except PostDoesNotExist: abort(404) total, curation, author, beneficiaries, sbd_amount, sp_amount, \ usd_amount = calculate_rewards(steemd_instance, post) rewards.append({ "link": link, "total": total, "curation": curation, "author": author, "beneficiaries": beneficiaries, "cashout_time": post["cashout_time"], "is_main_post": post.is_main_post(), "title": post["title"], "elapsed_seconds": int(post.time_elapsed().total_seconds()), "sbd_amount": sbd_amount, "sp_amount": sp_amount, "usd_amount": usd_amount, }) rewards = sorted(rewards, key=lambda k: k['elapsed_seconds']) return jsonify({"rewards": rewards})
def check_block(self, block_num): logger.info("Parsing block: %s", block_num) operation_data = self.steem.get_ops_in_block(block_num, virtual_only=False) for operation in operation_data: operation_type, raw_data = operation["op"][0:2] if operation_type == "comment": try: post = Post(raw_data) except PostDoesNotExist: continue if not post.is_main_post(): # we're only interested in posts. continue if post["author"] in self.authors: thread = Thread(target=self.upvote, args=(post, )) thread.start()
def check_block(self, block_num): operation_data = self.steem.get_ops_in_block(block_num, virtual_only=False) for operation in operation_data: operation_type, raw_data = operation["op"][0:2] if operation_type == "comment": try: post = Post(raw_data, steemd_instance=self.steem) except Exception as error: logger.error(error) continue if post.is_main_post(): # we're only interested in comments. continue if "@" + self.account in post["body"]: try: self.handle_command(post) except Exception as e: logger.error(e)
def run(self): blockchain = Blockchain(steemd_instance=self.steem) # stream of comments stream = blockchain.stream(filter_by=['comment']) while True: try: for comment in stream: post = Post(comment, steemd_instance=self.steem) if not post.is_main_post() and post['url']: main_post = self.main_post(post) # if self.tags is empty bot analyzes all tags # otherwise bot analyzes only comments that contains at least one of given tag if self.filter_by_tag(main_post['tags']): # users on whitelist are ignored if post['author'] in self.whitelist: print('Ignored:', post['author']) continue # users on scamlist are flagged without immediately elif post['author'] in self.scamlist: print('Scam:', post['author']) self.reply( post, 'Scam alert! Do not click in link!') self.vote(post) else: message = get_message_from_post(post) spam_probability = self.model.spam_probability( message) blog = Blog(account_name=post['author'], comments_only=True, steemd_instance=self.steem) average_spam_probability, generic_comment, rep = self.model.average_spam_probability( blog, self.num_previous_comments) print('*' if average_spam_probability > self.probability_threshold else ' ', end='') self.log(spam_probability, average_spam_probability, post['author'], message) if spam_probability > self.probability_threshold and average_spam_probability > self.probability_threshold: self.append_to_blacklist(post['author']) self.append_message('spam', message) response = self.response( average_spam_probability, generic_comment, rep) inp = input( 'y/n\n' ) # currently I approve manually if inp == 'y': if self.reply_mode: self.reply(post, response) if self.vote_mode: self.vote(post) except PostDoesNotExist as pex: continue except Exception as ex: print(repr(ex)) continue
steem = Steem() current_time = datetime.datetime.now() time_period = datetime.timedelta(hours=24) account = "amosbastian" User = namedtuple("User", ["name", "post", "pending"]) users = [] for vote in Account(account).history_reverse(filter_by="vote"): if vote["voter"] == account: time_voted = parse(vote["timestamp"]) if current_time - time_voted < time_period: permlink = "@{}/{}".format(vote["author"], vote["permlink"]) post = Post(permlink) if post.is_main_post(): user = User(post["author"], post["title"], Amount(post["pending_payout_value"]).amount) users.append(user) else: break total_pending = sum([user.pending for user in users]) width = 40 for user in users: print("{0:16} - {1:43} - ${2}".format( user.name, user.post[:width] + (user.post[width:] and "..."), user.pending)) print("Total pending payout: ${}".format(total_pending))
today = datetime.today().date() days = today - created # Create dictionary dates = {} for day in range(days.days + 1): dates[str(created + timedelta(days=day))] = 0 # Iterate over all blog posts print("\n\n Date \t\tPayout SBD\n") print(" ==========\t\t==============\n\n") post_limit = 500 if post_limit > 0: for post in steem.get_blog(account, 0, post_limit): post = Post(post["comment"]) if post.is_main_post() and post["author"] == account: post_date = str(post["created"].date()) payout = ((Amount(post["pending_payout_value"]).amount * 0.75) / 2) if payout == 0: payout = (Amount(post["total_payout_value"]).amount - Amount(post["curator_payout_value"]).amount) dates[post_date] += payout permlink = post['permlink'] total = total + payout print(" " + post_date + "\t\t" + str(payout) + "\t\t\t\t" + permlink) print("\n\n\n============\n" + str(total) + " SBD\n\n\n")
### Calculating author and beneficiary rewards def estimate_rewards(post): votes = [vote for vote in post["active_votes"]] total_share = sum([float(vote["rshares"]) * reward_share * base for vote in votes]) curation_share = sum([curation_reward(post, vote) for vote in votes]) author_share = (total_share - curation_share) * (1.0 - beneficiaries_pct(post)) beneficiary_share = (total_share - curation_share) * beneficiaries_pct(post) print(f"Estimated total reward for this post is ${total_share:.2f}") print(f"Estimated author reward for this post is ${author_share:.2f}") print(f"Estimated beneficiary reward for this post is ${beneficiary_share:.2f}") print(f"Estimated curation reward for this post is ${curation_share:.2f}\n") ### Estimating rewards in last `N` days account = "steempytutorials" time_period = timedelta(days=3) posts = set() for post in Account(account).history_reverse(filter_by="comment"): try: post = Post(post) if post.time_elapsed() < time_period: if post.is_main_post() and not post["title"] in posts: posts.add(post["title"]) print(post["title"]) estimate_rewards(post) else: break except Exception as error: continue
def report(): with open('reportlayout.txt') as layout: report_layout = layout.read() steem = Steem(node='wss://gtg.steem.house:8090') main_report = ('|' + column_title_thumbnail + ' | ' + column_title_author + ' | ' + column_title_post_title + ' | ' + column_title_payout + ' |\n' + '| --- | --- | --- | --- |\n') total_rewards = 0 total_posts = 0 trailing_24h_t = time.time() - datetime.timedelta( minutes=1440).total_seconds() # 24 * 60 = 1440 stoptime = time.time() starttime = trailing_24h_t author_list = [] for i in account.history_reverse(filter_by="vote", batch_size=10000): timestamp = parse_time(i['timestamp']).timestamp() if timestamp > trailing_24h_t: if i['voter'] == report_author: link = str('@' + i["author"] + "/" + i["permlink"]) full_link = ('https://steemit.com/tag/' + link) post = Post(link) reward = (Amount(post.get('total_payout_value')) + Amount(post.get('pending_payout_value'))) total_posts = total_posts + 1 tags = (post['json_metadata'].get('tags', [])) category = post.category if post.is_main_post() and not i['author'] == report_author: if scan_tag in tags or scan_tag in category: if total_rewards == 0: total_rewards = reward else: total_rewards = total_rewards + reward try: imagelink = post['json_metadata'].get('image')[0] except: imagelink = 'https://steem.io/images/steem.png' if len( imagelink ) > 100: # prevents problems with some image-links imagelink = 'https://steem.io/images/steem.png' image = ( '![main_image](https://img1.steemit.com/128x256/' + imagelink + ')') post_title = (post['title']) if len( post_title ) > 30: # cut off long titles, so the images scale properly post_title = post_title[:30] + " ..." if '|' in post_title: # these symbols mess with the markdown layout post_title = post_title.replace('|', ';') if '[' in post_title: post_title = post_title.replace('[', '') if ']' in post_title: post_title = post_title.replace(']', '') main_report = (main_report + image + '|@' + i['author'] + '|[' + post_title + '](' + full_link + ')|' + str(reward) + '\n') if not i['author'] in author_list: author_list.append(i['author']) date = time.strftime(date_format, time.localtime(stoptime)) report_starttime = time.strftime(time_format, time.localtime(starttime)) report_stoptime = time.strftime(time_format, time.localtime(stoptime)) a = Amount(total_rewards) average_rewards = a * (1 / total_posts) total_authors = len(author_list) dated_report_title = (report_title + str(date)) beneficiaries = author_list beneficiaries.append(report_author) bene_list = [] bene_weight = 10000 // len(beneficiaries) bene_rest = 10000 - (bene_weight * len(beneficiaries)) for author in beneficiaries: bene_dict = OrderedDict() bene_dict['account'] = author bene_dict['weight'] = bene_weight if author == report_author: bene_dict['weight'] = bene_weight + bene_rest bene_list.append(bene_dict) report = report_layout report = report.replace('STARTTIME_GOES_HERE', str(report_starttime)) report = report.replace('STOPTIME_GOES_HERE', str(report_stoptime)) report = report.replace('REPORT_AUTHOR_GOES_HERE', str(report_author)) report = report.replace('TOTAL_POSTS_GOES_HERE', str(total_posts)) report = report.replace('TOTAL_AUTHORS_GOES_HERE', str(len(author_list))) report = report.replace('TOTAL_REWARDS_GOES_HERE', str(total_rewards)) report = report.replace('AVERAGE_REWARDS_GOES_HERE', str(average_rewards)) report = report.replace('TOTAL_BENEFICIARIES_GOES_HERE', str(len(beneficiaries))) report = report.replace('REPORT_GOES_HERE', str(main_report)) steem = Steem(keys=report_author_key, node='wss://gtg.steem.house:8090' ) # instanciate again, for good measure # uncomment this to post automatically """ steem.post(
def handle_command(self, post): if post["author"] in self.config["blacklisted_users"]: logger.info("User on blacklist. (%s). Skipping", post["permlink"]) return # welcome command if re.findall("@%s\s!(welcome)" % self.account, post["body"]): main_post = Post(post.root_identifier, steemd_instance=self.steem) already_welcomed = self.get_table('welcome').find_one( author=main_post["author"]) if already_welcomed: logger.info("This user: %s already welcomed. Skipping" % main_post["author"]) return body = open(self.config["welcome_message"]).read() body = body.replace("$username", main_post["author"]) main_post.reply( body=body, author=self.account, ) if not main_post.is_main_post(): logger.info("Skipping. Not a main post.") return try: self.upvote(main_post) except Exception as e: logger.error(e) logger.info("Replied and upvoted user: %s", main_post["author"]) self.get_table('welcome').insert( dict( author=main_post["author"], permlink=main_post["permlink"], created_at=str(datetime.now()), )) if self.config["send_welcome_gift"] == "yes": self.commit.transfer(main_post["author"], self.config["welcome_gift"], memo=self.config["welcome_gift_message"], asset="SBD", account=self.account) # handle help commands help_commands = [ "creating_new_accounts", "bots", "curation_rewards", "downvote", "esteem", "security", "voting_power", "upvote", "tag_spam", "comment_spam", "wallet", "plagiarism", "posting" ] for command in help_commands: if re.findall("@%s\s!(%s)" % (self.account, command), post["body"]): message_path = "%s%s.md" % (self.config["help_commands_path"], command) main_post = Post(post.root_identifier, steemd_instance=self.steem) body = open(message_path).read() body = body.replace("$username", main_post["author"]) if not main_post.is_main_post(): logger.info("Skipping. Not a main post.") return main_post.reply( body=body, author=self.account, ) logger.info("Posted %s command reply." % command)