def test_delete(self): bts = self.bts c = Comment(self.authorperm, steem_instance=bts) tx = c.delete(account="test") self.assertEqual((tx["operations"][0][0]), "delete_comment") op = tx["operations"][0][1] self.assertIn(self.author, op["author"])
def test_reply(self): bts = self.bts c = Comment(self.authorperm, steem_instance=bts) tx = c.reply(body="Good post!", author="test") self.assertEqual((tx["operations"][0][0]), "comment") op = tx["operations"][0][1] self.assertIn("test", op["author"])
def test_comment(self, node_param): if node_param == "non_appbase": bts = self.bts else: bts = self.appbase with self.assertRaises( exceptions.ContentDoesNotExistsException ): Comment("@abcdef/abcdef", steem_instance=bts) c = Comment(self.authorperm, steem_instance=bts) self.assertTrue(isinstance(c.id, int)) self.assertTrue(c.id > 0) self.assertEqual(c.author, self.author) self.assertEqual(c.permlink, self.permlink) self.assertEqual(c.authorperm, self.authorperm) self.assertEqual(c.category, self.category) self.assertEqual(c.parent_author, '') self.assertEqual(c.parent_permlink, self.category) self.assertEqual(c.title, self.title) self.assertTrue(len(c.body) > 0) for key in ['tags', 'users', 'image', 'links', 'app', 'format']: self.assertIn(key, list(c.json_metadata.keys())) self.assertTrue(c.is_main_post()) self.assertFalse(c.is_comment()) self.assertTrue(isinstance(c.get_reblogged_by(), list)) self.assertTrue(len(c.get_reblogged_by()) > 0) self.assertTrue(isinstance(c.get_votes(), list)) if node_param == "appbase": self.assertTrue(len(c.get_votes()) > 0) self.assertTrue(isinstance(c.get_votes()[0], Vote))
def add_comment(contribution): """Adds the authorperm of the moderator's comment to the database.""" if contribution.moderator == "amosbastian": return post = Comment(contribution.url) inserted = False for comment in post.get_replies(): if comment.author == contribution.moderator: age = comment.time_elapsed() collection = constants.DB.comments collection.insert({ "url": comment.authorperm, "upvote_time": datetime.now() + timedelta(minutes=10) - age, "inserted": datetime.now(), "upvoted": False, "category": contribution.category }) inserted = True if not inserted: collection = constants.DB.missed_posts collection.insert({ "url": contribution.url, "moderator": contribution.moderator, "category": contribution.category })
def vote_discussion( discussion: Comment, voter: str, weight: float ) -> bool: """Vote a discussion (post, comment) with selected account and vote weight. :param discussion: Post or comment :type discussion: beem.comment.Comment :param voter: Voter :type voter: str :param weight: Vote weight :type weight: float :return: True if vote was successful else False :rtype: bool """ try: discussion.upvote(weight, voter) except beem.exceptions.VotingInvalidOnArchivedPost: LOGGER.info("Invalid post, can't vote. %s", discussion["url"]) return False except: LOGGER.exception( "Error during upvoting with %s. %s", voter, discussion["url"] ) return False else: LOGGER.info( "Upvote with account %s at weight %s%%. %s", voter, weight, discussion["url"], ) return True
def obey(command, blocknum): # Once Minion receives his orders, he obeys print('Obeying my master, his orders are:') print(command) # Time to slice the memo, first word action npost(new post) rpost(reply to post or comment) # For rpost, also extract the author/permanentlink Minion is to reply to # the rest of the memo is the body of the post/comment memobreak = command action = memobreak.split( ' ', 1)[0] # get the first word off the memo, the command print('Im performing the action:', action) # on this block any command could be coded if action == 'npost': body = memobreak.split( ' ', 1)[1] # this gets the rest of the memo, it becomes the body steem.post("Incubator Post on Block:" + blocknum, body, author=account, tags=["incubator"], self_vote=True) print('Post Successfully submitted') elif action == 'rpost': authorperm = memobreak.split( ' ', 2)[1] # the link to author/permlink is extracted from the memo c = Comment(authorperm) body = memobreak.split(' ', 2)[2] # body of the reply c.reply(body, title='', author=account, meta=None) # execute reply print('Reply Successfully submitted') else: print('no recognizable command found, error') account.transfer(operator, '0.001', "STEEM", 'Command Executed') # Respond, Refund print('Waiting for new Instructions')
def staff_pick_section(staff_picks): """Creates the staff pick section for the Utopian weekly post.""" LOGGER.info("Generating staff pick statistics section...") section = "## Staff Picks" for staff_pick in staff_picks["staff_picks"]: url = staff_pick["url"] post = Comment(url) title = post.json()["title"] # If title can't be retrieved set it to the post's URL if not title: title = url author = staff_pick['author'] category = staff_pick['category'] # Add staff pick to the string section += ( f"<br><br>### <a href='{url}'>{title}</a> by @{author} " f"[{category}]<br><br>[Image (contributor profile image / image from " "the post)]<br><br>[Paragraph: Background info on project etc.]" "<br><br>[Paragraph: CM review, including etc.]<br><br>" f"Total payout: {staff_pick['total_payout']:.2f} STU<br>" f"Number of votes: {staff_pick['total_votes']}") return section
def vote_update(row, row_index, staff_picked=False): """ Upvotes the highest priority contribution and updates the spreadsheet. """ url = row[2] category = row[4] account = Account(ACCOUNT) # Check if post was staff picked if staff_picked: vote_pct = MAX_VOTE[category] else: vote_pct = float(row[-1]) try: post = Comment(url, steem_instance=steem) logger.info(f"Voting on {post.authorperm} with {vote_pct}%") # If in last twelve hours before payout don't vote if valid_age(post): post.vote(vote_pct, account=account) bot_comment(post, category, account, staff_picked) reviewed.update_cell(row_index, 10, "Yes") else: reviewed.update_cell(row_index, 10, "EXPIRED") except Exception as vote_error: logger.error(vote_error)
def steemstem_vote_finder(user): stm = Steem(node=[ 'https://rpc.steemviz.com', 'https://api.steem.house', 'https://gtg.steem.house:8090', 'wss://gtg.steem.house:8090', 'https://steemd-appbase.steemit.com', 'wss://steemd.privex.io', 'https://steemd.privex.io', 'wss://anyx.io', 'https://anyx.io', 'wss://rpc.curiesteem.com', 'https://rpc.buildteam.io', 'https://rpc.steemliberator.com', 'https://appbasetest.timcliff.com', 'wss://rpc.steemviz.com', 'https://steemd.minnowsupportproject.org' ]) set_shared_steem_instance(stm) steemstem_user = user acc = Account(steemstem_user) for post in acc.blog_history(): if post['parent_author'] == '' and post['author'] == steemstem_user: p_link = post['author'] + '/' + post['permlink'] com_link = Comment(p_link) if 'steemstem' in com_link.get_votes(): html_link = '<a href= \"https://steemit.com/' + '@' + p_link + '\"' + '>' + unidecode( post['title']) + '</a>' print(html_link) f = open(user + "_" + "steemstem.txt", "a") f.write(html_link + '\n') f.close()
def setUpClass(cls): nodelist = NodeList() nodelist.update_nodes(steem_instance=Steem(node=nodelist.get_nodes(hive=True), num_retries=10)) cls.bts = Steem( node=nodelist.get_nodes(hive=True), nobroadcast=True, keys={"active": wif}, num_retries=10 ) # from getpass import getpass # self.bts.wallet.unlock(getpass()) set_shared_steem_instance(cls.bts) cls.bts.set_default_account("test") acc = Account("fullnodeupdate", steem_instance=cls.bts) n_votes = 0 index = 0 entries = acc.get_blog_entries(limit=30)[::-1] while n_votes == 0: comment = Comment(entries[index], steem_instance=cls.bts) votes = comment.get_votes() n_votes = len(votes) index += 1 last_vote = votes[0] cls.authorpermvoter = construct_authorpermvoter(last_vote['author'], last_vote['permlink'], last_vote["voter"]) [author, permlink, voter] = resolve_authorpermvoter(cls.authorpermvoter) cls.author = author cls.permlink = permlink cls.voter = voter cls.authorperm = construct_authorperm(author, permlink)
def banned_comment(url): """ Comments on the given contribution letting them know that they are banned. """ post = Comment(url) comment = constants.COMMENT_BANNED.format(post.author) post.reply(comment, author="amosbastian")
def summon_upvotebot(): print(f"[Starting up]") while True: try: for post in chain.stream(opNames="comment", threading=True, thread_num=5): mentions = re.findall(REGEX, post["body"]) comment = Comment(post) perm = comment.authorperm parent = construct_authorperm( Comment(perm).parent_author, Comment(perm).parent_permlink) author = post["author"] if Comment(perm).is_comment and botname in mentions: print( f"[{author} just mentioned {botname} in {perm} in reply to {parent}]" ) if author in followees: Comment(parent).upvote(weight=weight, voter=botname) print( f"[{botname} voted {weight}% on {parent} per {author}'s request]" ) else: print( f"[{author} tried to summon {botname} but is not in the whitelist]" ) except Exception as error: print(repr(error)) continue
def contribution(row): """Create a dictionary for a contribution post. :param row: list of values from worksheet :return: dict for contribution """ url_split = row[2].split('/') author = url_split[4][1:] if url_split[4][0] == "@" else url_split[3][1:] permlink = url_split[5] if url_split[4][0] == "@" else url_split[4] review_date = parse_date_to_iso(row[1]) repo_split = row[3].split('/') if 'github.com' in row[3] else [] staff_pick = { 'picked_by': row[8], 'date': parse_date_to_iso(row[7]) } if row[6].lower() == 'yes' else None repo_full_name = f'{repo_split[3]}/{repo_split[4].split("?")[0]}' \ if len(repo_split) > 4 else '' score = float(row[5]) if row[5] else 0 category = row[4] post = Comment(f'@{author}/{permlink}') post_meta = post.json_metadata post_json = post.json() created = parse_date_to_iso(post_json['created']) contrib = { 'author': author, 'permlink': permlink, 'post_category': 'utopian-io', 'moderator': { 'account': (row[0]), 'date': review_date }, 'repository': { 'full_name': repo_full_name, 'html_url': (f'https://github.com/{repo_full_name}' if repo_full_name else '') }, 'score': score, 'status': get_status(row), 'category': category or (post_meta.get('tags')[1] if len(post_meta.get('tags')) > 1 else ''), 'tags': (post_meta.get('tags')), 'created': created, 'body': (post_json.get('body', '')), 'utopian_vote': (get_utopian_vote(post)), 'staff_pick': staff_pick } return contrib
def test_export(self): bts = self.bts if bts.rpc.get_use_appbase(): content = bts.rpc.get_discussion( { 'author': self.author, 'permlink': self.permlink }, api="tags") else: content = bts.rpc.get_content(self.author, self.permlink) c = Comment(self.authorperm, steem_instance=bts) keys = list(content.keys()) json_content = c.json() exclude_list = ["json_metadata", "reputation", "active_votes"] for k in keys: if k not in exclude_list: if isinstance(content[k], dict) and isinstance( json_content[k], list): self.assertEqual(list(content[k].values()), json_content[k]) elif isinstance(content[k], str) and isinstance( json_content[k], str): self.assertEqual(content[k].encode('utf-8'), json_content[k].encode('utf-8')) else: self.assertEqual(content[k], json_content[k])
def listen_blockchain_comments(): """Listens to blockchain for comments by specified accounts at Utopian task request posts and put them to a queue. """ for comment_op in listen_blockchain_ops(["comment"]): if not comment_op["parent_author"] or comment_op[ "author"] not in ACCOUNTS: continue try: comment = Comment( f'@{comment_op["author"]}/{comment_op["permlink"]}') except beem.exceptions.ContentDoesNotExistsException: logger.info( "Comment does not exist. %s", f'@{comment_op["author"]}/{comment_op["permlink"]}', ) except: logger.exception("Error while fetching comment") else: root = comment.get_parent() logger.debug("%s, %s", comment["url"], root["url"]) if is_utopian_task_request(root): logger.info("Added to comments queue - %s %s", comment["url"], root["url"]) QUEUE_COMMENTS.put_nowait((comment, root))
def test_reply(self): bts = self.bts bts.txbuffer.clear() c = Comment(self.authorperm, blockchain_instance=bts) tx = c.reply(body="Good post!", author="test") self.assertEqual((tx["operations"][0][0]), "comment") op = tx["operations"][0][1] self.assertIn("test", op["author"])
def test_resteem(self): bts = self.bts c = Comment(self.authorperm, steem_instance=bts) tx = c.resteem(account="test") self.assertEqual( (tx["operations"][0][0]), "custom_json" )
def test_delete(self): bts = self.bts bts.txbuffer.clear() c = Comment(self.authorperm, blockchain_instance=bts) tx = c.delete(account="test") self.assertEqual((tx["operations"][0][0]), "delete_comment") op = tx["operations"][0][1] self.assertIn(self.author, op["author"])
def test_edit_replace(self): bts = self.bts c = Comment(self.authorperm, steem_instance=bts) body = c.body + "test" tx = c.edit(body, meta=c["json_metadata"], replace=True) self.assertEqual((tx["operations"][0][0]), "comment") op = tx["operations"][0][1] self.assertIn(self.author, op["author"]) self.assertEqual(body, op["body"])
def post_detail(request, author, permlink, **args): author_perm = construct_authorperm(author, permlink) post = Comment(author_perm, blockchain_instance=hv) if post: replies = post.get_replies(raw_data=True) post = strip(post) for reply in replies: reply = strip(reply) return render(request, 'blog/post_detail.html', {'post': post, 'replies': replies})
def test_edit(self): bts = self.bts c = Comment(self.authorperm, steem_instance=bts) c.edit(c.body, replace=False) body = c.body + "test" tx = c.edit(body, replace=False) self.assertEqual((tx["operations"][0][0]), "comment") op = tx["operations"][0][1] self.assertIn(self.author, op["author"])
def info(permalink): post = Comment(permalink) p_export = post.json() p_info = [{ "body": p_export["body"], "title": p_export["title"], "author": p_export["author"], "permalink": p_export["permlink"] }] return p_info
def test_edit(self): bts = self.bts bts.txbuffer.clear() c = Comment(self.authorperm, blockchain_instance=bts) c.edit(c.body, replace=False) body = c.body + "test" tx = c.edit(body, replace=False) self.assertEqual((tx["operations"][0][0]), "comment") op = tx["operations"][0][1] self.assertIn(self.author, op["author"])
def read_posts(self, start=0): if not self.exists: return [] c_list = {} posts = [] if self.reblog: blogs = self.account.history_reverse(only_ops=["custom_json"]) elif self.limit: blogs = self.account.get_blog(start_entry_id=start, limit=self.limit) else: blogs = self.account.blog_history(start=start, limit=self.limit, reblogs=self.reblog) days_done = False for c in blogs: if self.reblog: if c['id'] == "follow": json_data = json.loads(c['json']) if len(json_data) > 0 and json_data[0] == "reblog": info = json_data[1] authorperm = "@{}/{}".format(info["author"], info["permlink"]) timestamp = c["timestamp"] c = Comment(authorperm) c["reblogged"] = timestamp else: continue else: continue if c.authorperm in c_list: continue if not c.is_comment(): if ((not self.reblog) and c.author == self.username) or ( self.reblog and c.author != self.username): sc = SteemComment(comment=c) tags = sc.get_tags() if self.tag is None or self.tag in tags: if self.keyword is None or self.keyword in c.title: days_done = self.days is not None and not in_recent_n_days( c, self.days, self.reblog) if days_done: break else: c = sc.refresh() sc.log() c_list[c.authorperm] = 1 posts.append(c) print('{} posts are fetched'.format(len(posts))) return posts
def hundred_voter(): authors = [] with open(file=config['VOTER']['throw_votes_authors'], mode='r') as f: for line in f: line = line.replace('\n', '').replace('@', '') if len(line) >= 3: authors.append(line) random.shuffle(authors) log.info('Authors list: {}'.format(authors)) comment_body = '' if config.getboolean('VOTER', 'throw_write_comment'): with open(file=config['VOTER']['throw_comment_file'], mode='rb') as file: # loading comment text comment_body = file.read().decode('iso-8859-1') log.info('Loaded comment text.') for author in authors: try: for post in Account(author).history_reverse(stop=datetime.now() - timedelta(days=5), only_ops=['comment']): if post.get('parent_author') != '': continue a_perm = '{}/{}'.format(author, post.get('permlink')) log.info(a_perm) c = Comment(authorperm=a_perm) if a.name in c.get_votes(): log.info('Already voted.') continue log.info('Try vote on {}'.format(c.authorperm)) shared_steem_instance().wallet.unlock( config['GENERAL']['wallet_key']) c.vote(weight=config.getfloat('VOTER', 'throw_votes_pct'), account=a.name) if config.getboolean('VOTER', 'write_comment'): shared_steem_instance().post( title='', body=comment_body, author=config['GENERAL']['acc_name'], reply_identifier=c.authorperm, app='https://github.com/PortalMine/portalvotes') log.debug(shared_steem_instance().broadcast()) shared_steem_instance().wallet.lock() return True except AccountDoesNotExistsException: log.info('Account {} does not exist.'.format(author)) continue else: log.info('Nothing found to burn vote.') return False
async def queue_voting(ctx, sfr): """ Voting on steemflagrewards mentions one after one once the voting power of the account reached 90%. This maintains a rather staple flagging ROI """ global queueing while queueing: while sfr.vp < queue_vp: # For not failing because of unexpected manual votes await asyncio.sleep(sfr.get_recharge_timedelta(queue_vp).total_seconds()) sfr.refresh() next_queued = cursor.execute( 'SELECT comment, flagger, category, weight, followon FROM steemflagrewards WHERE queue == 1 ORDER BY created ASC LIMIT 1;').fetchone() if not next_queued: queueing = False await ctx.send('No more mentions left in the queue. Going back to instant voting mode.') return authorperm, flagger, cats, weight, follow_on = next_queued comment = Comment(authorperm,steem_instance=stm) #gets post created date without timezone info for comparing to now created = comment['created'].replace(tzinfo=None) now=datetime.datetime.utcnow().replace(microsecond=0) dif = now - created ts = round(dif.total_seconds()) difmin=round((ts/60)) if(difmin < 15): await asyncio.sleep(ts) try: comment.upvote(weight, sfr.name) await asyncio.sleep(STEEM_MIN_VOTE_INTERVAL) # sleeps to account for STEEM_MIN_VOTE_INTERVAL except VotingInvalidOnArchivedPost: await ctx.send( 'Sadly one comment had to be skipped because it got too old.' \ 'Maybe the author can delete the comment and write a new one?') cursor.execute('UPDATE steemflagrewards SET queue = 0 WHERE comment == ?', (authorperm,)) db.commit() continue await ctx.send(f'Sucessfully voted on mention by {flagger} out of the queue.') if not follow_on: cat_string = '' for i in cats.split(', '): cat_string += CAT_DESCRIPTION[i] body = 'Steem Flag Rewards mention comment has been approved! Thank you for reporting' \ 'this abuse, @{}. {} This post was submitted via our Discord Community channel.' \ 'Check us out on the following link!\n[SFR Discord](https://discord.gg/7pqKmg5)'.format( flagger, cat_string) await asyncio.sleep(get_wait_time(sfr)) stm.post('', body, reply_identifier=authorperm, community='SFR', parse_body=True, author=sfr.name) await ctx.send('Commented on queued mention.') cursor.execute('UPDATE steemflagrewards SET queue = 0 WHERE comment == ?', (authorperm,)) db.commit() sfr.refresh() return
def rand_com(permalink): permlink = permalink.split("@") c = Comment(permlink[1]) comments = c.get_replies() unique_authors = [] unique_com = [] for com in comments: if com["author"] not in unique_authors: unique_authors.append(com["author"]) unique_com.append(com) num_com = len(unique_com) return unique_com[randint(0, num_com)]
def vote_contribution(contribution): """Votes on the contribution with a scaled weight (dependent on the contribution's category and weight). """ if "@amosbastian" in contribution.url: return weight = (float(contribution.weight) / max(constants.MAX_VOTE.values()) * 100.0) / constants.SCALER contribution = Comment(contribution.url) voters = [vote.voter for vote in contribution.get_votes()] if "amosbastian" not in voters: contribution.vote(weight, "amosbastian")
def get_votes(s, author, permlink): acc = Comment("@{}/{}".format(author, permlink), steem_instance=s) upvotes = 0 downvotes = 0 for vote in acc.get_votes(): if vote.rshares > 0: upvotes = upvotes + 1 else: downvotes = downvotes + 1 return upvotes, downvotes
def test_export(self, node_param): if node_param == "non_appbase": bts = self.bts content = bts.rpc.get_content(self.author, self.permlink) else: bts = self.appbase content = bts.rpc.get_discussion({'author': self.author, 'permlink': self.permlink}, api="tags") c = Comment(self.authorperm, steem_instance=bts) keys = list(content.keys()) json_content = c.json() for k in keys: if k not in "json_metadata" and k != 'reputation' and k != 'active_votes': self.assertEqual(content[k], json_content[k])