def run(filename): b = Blockchain() # automatically resume from where we left off # previous + last + 1 start_block = get_previous_block_num(get_last_line(filename)) + 2 upstream_blk = b.get_current_block() checkin_count = 0 print("Our local block: {}".format(start_block)) print("The Upstream block: {}".format(b.get_current_block_num())) print("Progress: {}%\n".format( progress(start_block, b.get_current_block_num()))) with open(filename, 'a+') as file: checkin_ts = time.time() for block in b.stream_from(start_block=start_block, full_blocks=True): if checkin_ts + 10 < time.time(): pdone = progress(int(block['block_id'][:8], base=16), b.get_current_block_num()) dl_rate = checkin_count / 10 print("Rate: {}blk/sec, Progress: {}%".format(dl_rate, pdone)) checkin_ts = time.time() checkin_count = 0 file.write(json.dumps(block, sort_keys=True) + '\n') checkin_count += 1
def run(): blockchain = Blockchain() head_block = blockchain.get_current_block_num() start_block = head_block - (int(sys.argv[1])) stream = blockchain.stream_from(start_block=start_block) block_count = int(sys.argv[1]) current_block = start_block stats = {} operations = 0 counter = 0 print("Starting from block {} for {} blocks\n".format( start_block, block_count)) for post in stream: if post['block'] != current_block: counter += 1 print("Block {}/{} {:.2f}%".format(counter, block_count, counter / block_count * 100)) current_block = post['block'] elif post['block'] == start_block + block_count: break operation = post['op'][0] if operation not in stats: stats[operation] = 1 else: stats[operation] += 1 operations += 1 print("operations {}\n".format(operations)) for operation in stats: print(operation, stats[operation])
def get_start_block(start_block:int = None, blockchain: Blockchain=None): start_block = None try: if isinstance(start_block, int) and start_block < 0: start_block = blockchain.get_current_block_num() - start_block except Exception: logger.exception('service error') start_block = None logger.debug('get_start_block', start_block=start_block) return start_block
def run(): blockchain = Blockchain() id = blockchain.get_current_block_num() global current_id if id != current_id: block = blockchain.get_current_block() thread = threading.Thread(target=parse_next_block, args=(block, )) print("Start new thread", thread.name) thread.start() current_id = id threading.Timer(1, run).start()
def run(): # Global variables for creating threads steem = Steem(['https://api.steemit.com']) blockchain = Blockchain(steem) head_block = blockchain.get_current_block_num() block_count = int(sys.argv[1]) amount_of_threads = int(sys.argv[2]) blocks_per_thread = int(block_count / amount_of_threads) start_block = head_block - block_count threads = [] # Calculate start_block and end_block for each thread for thread_id in range(0, amount_of_threads): thread = myThread(thread_id, start_block, start_block + blocks_per_thread - 1, blocks_per_thread, blockchain) thread.start() threads.append(thread) start_block = start_block + blocks_per_thread # Wait for all the threads to finish for t in threads: t.join()
def run(): start = time.clock() blockchain = Blockchain() head_block = blockchain.get_current_block_num() - int(sys.argv[1]) block_count = int(sys.argv[1]) amount_of_threads = int(sys.argv[2]) n = int(block_count / amount_of_threads) start = head_block - block_count threads = [] queueLock = threading.Lock() workQueue = queue.Queue(amount_of_threads) for x in range(0, amount_of_threads): thread = myThread(x, start, start + n - 1, n, blockchain, workQueue, queueLock) thread.start() threads.append(thread) start = start + n print() for t in threads: t.join() merged_data = {} while not workQueue.empty(): data = workQueue.get() for key in data: if key not in merged_data: merged_data[key] = data[key] else: merged_data[key] += data[key] print(merged_data)
class Steem_node(): def __init__(self, acount, number): self.tag = 'vote' self.account = account self.number = number self.nodes = [ 'https://api.steemit.com', 'https://rpc.buildteam.io', 'https://rpc.steemviz.com' ] self.steem = Steem(nodes=self.nodes) self.b = Blockchain(self.steem) self.timestamp = None self.block = self.b.get_current_block_num() print('Booted\nConnected to: {}'.format(self.nodes[0])) def send_sms(self, memo): print(twilio_api.send_sms(self.number, memo)) # Convert rshares to dollar value # Author: emrebeyler # Source: https://goo.gl/dV7yVa def convert_rshares(self, rshares): reward_fund = self.steem.get_reward_fund() reward_balance, recent_claims = (reward_fund["reward_balance"], reward_fund["recent_claims"]) base_price = self.steem.get_current_median_history_price()["base"] fund_per_share = Amount(reward_balance).amount / float(recent_claims) payout = float(rshares) * fund_per_share * Amount(base_price).amount return payout def process_vote(self, vote): print(vote) voter = vote['voter'] author = vote['author'] permlink = vote['permlink'] weight = vote['weight'] # Verify that utopian-io is the voter and that is votes on account if voter == 'utopian-io' and author == account: print(f"\nVoter: {voter}\nAuthor: {author}\nPermlink: {permlink}" + f"\nWeight: {weight}\n{self.timestamp}\n") # Construct post from the permlink to retrieve vote rshares post = Post(f'@{self.account}/{permlink}', self.steem) # Look for utopian in active_votes active_votes = post['active_votes'] for vote in active_votes: if vote['voter'] == 'utopian-io': payout = self.convert_rshares(vote['rshares']) # Construct sms url = f"http://steemit.com/@{self.account}/{permlink}" body = (f"Upvote from Utopian-io for ${payout:.2f}\n" + f"\n{url}\n\nBlock: {self.block}" + f"\n{self.timestamp}") self.send_sms(body) def run(self): print(self.block) while True: try: # stream full blocks stream = self.b.stream_from(start_block=self.block, full_blocks=True) # process each block indiviudally for block in stream: self.timestamp = block['timestamp'] print(f'{self.timestamp} Block: {self.block}', end='\r') # go over each transaction indivually, process if tag is # met and update index for transaction in block['transactions']: if transaction['operations'][0][0] == self.tag: transfer = transaction['operations'][0][1] self.process_vote(transfer) self.block += 1 except Exception as e: # common exception for api.steemit.com # when the head block is reached s = ("TypeError('an integer is" " required (got type NoneType)',)") if repr(e) == s: time.sleep(3)
def scrape_operations(mongo): """Fetch all operations from last known block forward.""" settings = Settings(mongo) blockchain = Blockchain(mode="irreversible") last_block = settings.last_block() # handle batching _batch_size = 100 _head_block_num = blockchain.get_current_block_num() batch_dicts = [] history = blockchain.history(start_block=last_block, ) def custom_merge(*args): return list(set(filter(bool, flatten(args)))) def schedule_batch(_batch_dicts): """Send a batch to background worker, and reset _dicts container""" _batch = merge_with(custom_merge, *_batch_dicts) if _batch: batch_update_async.delay(_batch) log.info('\n> Fetching operations, starting with block %d...' % last_block) for operation in history: # handle comments if operation['type'] in ['comment', 'delete_comment']: post_identifier = "@%s/%s" % (operation['author'], operation['permlink']) if operation['type'] == 'delete_comment': delete_comment(mongo, post_identifier) else: with suppress(TypeError): upsert_comment( mongo, '%s/%s' % (operation['author'], operation['permlink'])) # if we're close to blockchain head, enable batching recent_blocks = 20 * 60 * 24 * 1 # 1 days worth of blocks if last_block > _head_block_num - recent_blocks: batch_dicts.append(parse_operation(operation)) # insert operation with suppress(DuplicateKeyError): transform = compose(strip_dot_from_keys, json_expand, typify) mongo.Operations.insert_one(transform(operation)) # if this is a new block, checkpoint it, and schedule batch processing if operation['block_num'] != last_block: print("last block:", last_block) last_block = operation['block_num'] settings.update_last_block(last_block - 1) if last_block % 10 == 0: _head_block_num = blockchain.get_current_block_num() if last_block % _batch_size == 0: schedule_batch(batch_dicts) batch_dicts = [] if last_block % 100 == 0: log.info("#%s: (%s)" % (last_block, blockchain.steem.hostname))
"[Normal Process] SneakPeek Bot comment already present. Ignore and go to next iteration" ) t_ignore = 1 break if (t_ignore == 1): continue #newpid = os.fork() print("[Normal Process] CAT (Func-MAIN()): %s" % cat) # Threading is required in order to make sure # that main loop doesn't miss a single block on the blockchain # while processing the current match. # Time processing traces added nthread = printposts(cat, comment) nthread.start() except: print("[Exception] Error Occurred @ Block No: ", blck.get_current_block_num()) exc_type, exc_value, exc_traceback = sys.exc_info() print("[Exception] Type : ", exc_type) print("[Exception] Value : ", exc_value) #Enough information present in Type and Value, incase further information is required then use following print("[Exception] Traceback : ") traceback.print_tb(exc_traceback) # Filter tags for Alerts Settings # [Normal Process] # [All Trace] # [Future] # [Exception]
}) def last_block(self): return self._settings.find_one().get('last_block', 1) def update_last_block(self, block_num): return self._settings.update_one({}, {"$set": { 'last_block': block_num }}) settings = Settings(mongo) blockchain = Blockchain() BLOCK_NUM = settings.last_block() or blockchain.get_current_block_num() print(BLOCK_NUM) # BLOCK_NUM = 26052441 # print(BLOCK_NUM) # POST 26052437 def fix_legacy_json(json): # Coordinates if 'location' in json and isinstance(json['location'], dict): if json['location'].keys() >= {'name', 'lat', 'lng'}: json['location'] = { 'geometry': { 'type': 'Point', 'coordinates':
from steem.post import Post from steem.instance import set_shared_steemd_instance from steem.steemd import Steemd from steem.amount import Amount from steem.blockchain import Blockchain #steemd_nodes = ['https://api.steemit.com'] steemd_nodes = ['https://rpc.buildteam.io'] #worked best set_shared_steemd_instance(Steemd(nodes=steemd_nodes)) steem = Steem(nodes=steemd_nodes) blockchain = Blockchain() timeframe = 24 * 60 * 60 last_block = blockchain.get_current_block_num() print( 'Current Block:', str(last_block), ) trail_24h_block = int(last_block - (timeframe / 3)) print( '24-hours-ago block:', str(trail_24h_block), ) boosters = [ 'votebuster', 'smartsteem', 'mrswhale', 'adriatik',
class Requests: def __init__(self, private_posting_key): self.s = Steem(keys=[private_posting_key]) self.b = Blockchain(steemd_instance=self.s) self.api = Api() self.settings = self.api.settings() def get_current_block_num(self): return self.b.get_current_block_num() def find_match(self, name, type, tournament_id=None, round=0): if type == "Ranked:": json_data = {"match_type": type} elif type == "Tournament": json_data = { "match_type": type, "settings": { "tournament_id": tournament_id, "round": round } } else: json_data = {"match_type": type} self.s.custom_json('sm_find_match', json_data, required_posting_auths=[name]) def find_match_transaction(self, player, old_trx): #TODO add break condition, e.g. 5 minutes or validity block while True: try: block_num = self.b.get_current_block_num() for r in self.api.get_from_block(block_num): if r["type"] == "find_match": if r["id"] != old_trx: if r["player"] == player: print(r["id"]) return r["id"] except: print("Error while trying to get current block") def enter_tournament(self, id, name): json_data = {"tournament_id": id, "signed_pw": ""} self.s.custom_json('sm_enter_tournament', json_data, required_posting_auths=[name]) def tournament_checkin(self, id, name): json_data = {"tournament_id": id, "signed_pw": ""} self.s.custom_json('sm_tournament_checkin', json_data, required_posting_auths=[name]) def submit_team(self, trx_id, team, name): """ Submits a Steem Monsters team for the given match search transaction :param trx_id: search transaction id :param team: list of UID's corresponding to Monsters (Summoner at index 0, Remaining team 1-n :param name: player name """ secret = self.generate_key() hash = self.generate_team_hash(team[0], team[1:], secret) json_data = { "trx_id": trx_id, "team_hash": hash, "summoner": team[0], "monsters": team[1:], "secret": secret } self.s.custom_json('sm_submit_team', json_data, required_posting_auths=[name]) def generate_key(self, length=10): return ''.join( choice(string.ascii_letters + string.digits) for i in range(length)) def generate_team_hash(self, summoner, monsters, secret): m = hashlib.md5() m.update((summoner + ',' + ','.join(monsters) + ',' + secret).encode("utf-8")) team_hash = m.hexdigest() return team_hash def open_card_pack(self, player, edition): """ Opens a card pack and prints the transaction details Parameters: player (String): Name of the player edition (int): open pack of edition n, e.g. 1 for beta """ self.s.custom_json("sm_open_pack", {"edition": edition}, required_posting_auths=[player]) while True: for r in self.api.get_from_block(self.b.get_current_block_num()): if r["type"] == "open_pack": if r["player"] == player: print(r) return r["id"] def claim_reward(self, name, quest_id, type): json_data = {"type": type, "quest_id": quest_id} self.s.custom_json('sm_claim_reward', json_data, required_posting_auths=[name]) def start_quest(self, name, type): json_data = {"type": type} self.s.custom_json('sm_start_quest', json_data, required_posting_auths=[name])
class YoBlockchainFollower(YoBaseService): service_name = 'blockchain_follower' def __init__(self, **kwargs): super().__init__(**kwargs) # init blockchain steemd_url = self.yo_app.config.steemd_url self.steemd = steem.steemd.Steemd(nodes=[steemd_url]) self.blockchain = Blockchain(steemd_instance=self.steemd) self.start_block = self.yo_app.config.steemd_start_block self.last_block_num_handled = 0 # init ops handlers self.op_map = defaultdict(list) self.op_map.update({ 'vote': [self.handle_vote], 'account_update': [self.handle_account_update], 'transfer': [self.handle_send, self.handle_receive], 'custom_json': [self.handle_follow, self.handle_resteem], 'withdraw_vesting': [self.handle_power_down], 'comment': [self.handle_mention, self.handle_comment] }) start_block = self.get_start_block() self.ops_func = self.blockchain.stream_from( start_block=start_block, batch_operations=True) self.ops = lambda: self.execute_sync(next, self.ops_func) def get_start_block(self): start_block = None try: if isinstance(self.start_block, int) and self.start_block < 0: start_block = self.blockchain.get_current_block_num() - self.start_block except Exception: self.log.exception('service error') start_block = None self.log.debug('get_start_block', start_block=start_block) return start_block async def store_notification(self, notifications): return await self.db.create_notifications(notifications) # pylint gets confused about these for some reason # pylint: disable=no-member async def handle_vote(self, op): vote_info = op['op'][1] self.log.info( 'handle_vote', permlink=vote_info['permlink'], author=vote_info['author'], voter=vote_info['voter'], weight=vote_info['weight']) return [ dict( trx_id=op['trx_id'], from_username=vote_info['voter'], to_username=vote_info['author'], json_data=json.dumps(vote_info), notify_type=VOTE, priority_level=Priority.LOW.value) ] async def handle_follow(self, op): if op['op'][1]['id'] != 'follow': self.log.debug('handle_follow noop') return [] op_data = op['op'][1] follow_data = json.loads(op_data['json']) if follow_data[0] != 'follow': return [] follower = follow_data[1]['follower'] following = follow_data[1]['following'] if len(op_data['required_posting_auths']) != 1: self.log.error('inavlid follow op, got %d posting auths, expected 1', op_data['required_posting_auths']) return [] if op_data['required_posting_auths'][0] != follower: self.log.error('invalid follow op, follower must be signer') return [] self.log.debug('handle_follow', follower=follower, following=following) return [ dict( trx_id=op['trx_id'], from_username=follower, to_username=following, json_data=json.dumps(follow_data[1]), notify_type=FOLLOW, priority_level=Priority.LOW.value) ] async def handle_account_update(self, op): op_data = op['op'][1] self.log.debug('handle_account_update', account=op_data['account']) return [ dict( trx_id=op['trx_id'], to_username=op_data['account'], json_data=json.dumps(op_data), notify_type=ACCOUNT_UPDATE, priority_level=Priority.LOW.value) ] async def handle_send(self, op): op_data = op['op'][1] send_data = { 'amount': op_data['amount'], 'from': op_data['from'], 'memo': op_data['memo'], 'to': op_data['to'], } self.log.debug( 'handle_send', _from=send_data['from'], amount=send_data['amount'], to=send_data['to']) return [ dict( trx_id=op['trx_id'], to_username=send_data['from'], json_data=json.dumps(send_data), notify_type=SEND_STEEM, priority_level=Priority.LOW.value) ] async def handle_receive(self, op): op_data = op['op'][1] receive_data = { 'amount': op_data['amount'], 'from': op_data['from'], 'memo': op_data['memo'], 'to': op_data['to'], } self.log.debug( 'handle_receive', to=receive_data['to'], amount=receive_data['amount'], _from=receive_data['from']) return [ dict( trx_id=op['trx_id'], to_username=receive_data['to'], from_username=receive_data['from'], json_data=json.dumps(receive_data), notify_type=RECEIVE_STEEM, priority_level=Priority.LOW.value) ] async def handle_power_down(self, op): op_data = op['op'][1] self.log.debug( 'handle_power_down', account=op_data['account'], amount=op_data['vesting_shares']) return [ dict( trx_id=op['trx_id'], to_username=op_data['account'], json_data=json.dumps(op_data), notify_type=POWER_DOWN, priority_level=Priority.LOW.value) ] async def handle_mention(self, op): comment_data = op['op'][1] haystack = comment_data['body'] + '\n' data = { 'author': comment_data['author'], 'permlink': comment_data['permlink'], } notifications = [] for match in set(re.findall(MENTION_PATTERN, haystack)): self.log.debug('handle_mention', author=data['author'], mentioned=match) notifications.append( dict( trx_id=op['trx_id'], to_username=match, from_username=data['author'], json_data=json.dumps(data), notify_type=MENTION, priority_level=Priority.LOW.value)) return notifications async def handle_comment(self, op): self.log.debug('handle_comment', op=['op'][0]) op_data = op['op'][1] if op_data['parent_author'] == '': # top level post return [] parent_id = '@' + op_data['parent_author'] + '/' + op_data['parent_permlink'] parent = steem.post.Post(parent_id) note_type = COMMENT_REPLY if parent.is_comment() else POST_REPLY self.log.debug( 'handle_comment', note_type=note_type, author=op_data['author'], parent_id=parent_id) return [ dict( trx_id=op['trx_id'], to_username=op_data['parent_author'], from_username=op_data['author'], json_data=json.dumps(op_data), notify_type=note_type, priority_level=Priority.LOW.value) ] async def handle_resteem(self, op): op_data = op['op'][1] resteem_data = json.loads(op_data['json']) if resteem_data[0] != 'reblog': self.log.debug('handle_resteem noop') return [] account = resteem_data[1]['account'] author = resteem_data[1]['author'] permlink = resteem_data[1]['permlink'] if len(op_data['required_posting_auths']) != 1: self.log.error('inavlid resteem op, got %d posting auths, expected 1', op_data['required_posting_auths']) return [] if op_data['required_posting_auths'][0] != account: self.log.error('invalid resteem op, account must be signer') return [] self.log.debug( 'handle_resteem', account=account, author=author, permlink=permlink) return [ dict( trx_id=op['trx_id'], from_username=account, to_username=author, json_data=json.dumps(resteem_data[1]), notify_type=RESTEEM, priority_level=Priority.LOW.value) ] # pylint: enable=no-member async def notify(self, blockchain_op): """ Handle notification for a particular op """ op_type = blockchain_op['op'][0] futures = [handler(blockchain_op) for handler in self.op_map[op_type]] if futures: self.log.debug( 'operation triggering handlers', op_type=op_type, handlers=futures) return await asyncio.gather(*futures) else: self.log.debug('skipping operation', op_type=op_type) return [] async def ops_iter(self): start_block = self.get_start_block() ops_func = self.blockchain.stream_from( start_block=start_block, batch_operations=True) while True: ops = await self.execute_sync(next, ops_func) yield ops async def main_task(self): self.log.debug('main task executed') async for ops in self.ops_iter(): block_num = ops[0]['block'] self.log.debug('main task', op_in_block=len(ops), block_num=block_num) unstored_notifications = await asyncio.gather( *[self.notify(op) for op in ops]) combined_notifications = list( itertools.chain(*itertools.chain(*unstored_notifications))) logger.debug( 'main_task', block_num=block_num, op_count=len(ops), unstored_count=sum(map(len, unstored_notifications)), combined_notifications=len(combined_notifications)) resp = await self.store_notification(combined_notifications) if resp: self.last_block_num_handled = block_num
class Upvotebot(): def __init__(self): self.node_index = 0 self.nodes = [ 'https://api.steemit.com', 'https://rpc.buildteam.io', 'https://rpc.steemviz.com' ] self.steemPostingKey = os.environ.get('steemPostingKey') self.steem = Steem(wif=self.steemPostingKey, nodes=self.nodes) self.b = Blockchain(self.steem, mode='head') self.block = self.b.get_current_block_num() self.upvote_list = [] self.trail_list = [] self.day = None self.hour = None self.timestamp = None self.db = database.Database() # Voting is done via Steemconnect with the steemconnect plugin from # @emre: https://github.com/emre/steemconnect-python-client # Set client_id and client_sercret # Sign up at: https://v2.steemconnect.com/dashboard # # To perform a vote the access_token is fetched from the DB and checked # to not be expired, if so it is renewed and stored inside the DB. # Votes are then removed from the queue and their log is updated. # When a vote fails it gets added to the error database for manual review. def vote(self, voter, author, permlink, weight, type): result = self.db.get_user_auth(voter) access_token, refresh_token, expire_on = result[0] dt = datetime.now() c = Client( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, access_token=access_token, ) try: # Verify access_token if dt > expire_on: access_token = self.refresh_token(refresh_token) result = c.refresh_access_token( refresh_token, "login,vote" # scopes ) access_token = result['access_token'] refresh_token = result['refresh_token'] expires_in = result['expires_in'] self.db.update_authentication_tokens( voter, access_token, refresh_token, expires_in, self.timestamp, ) print('Updated access token\n') # Perform vote if not self.is_already_voted(voter, author, permlink): vote = Vote(voter, author, permlink, weight) result = c.broadcast([vote.to_operation_structure()]) # Log vote if 'error' in result: message = result['error_description'] self.db.add_to_error_log( voter, author, permlink, weight, type, message, self.timestamp, ) else: message = 'Succes' if type == 'vote': self.db.update_log( voter, permlink, message, 'vote_log', ) elif type == 'trail': self.db.update_log( voter, permlink, message, 'trail_log', ) print(f"Voter: {voter}\nAuthor: {author}\n" + f"Permlink: {permlink}\nWeight: {weight}\n" + "Upvote succes\n") except Exception as error: print(voter, author, permlink, weight, error) self.db.add_to_error_log( voter, author, permlink, weight, type, error, self.timestamp, ) # Trails with a delay of 0 are immediatly voted upon. Else the expire_on # time of the vote is calculated and added to the queue. The weight of # vote is relative between the weight of the vote casted by the voter that # is being trailed and the trailer who has set a custom relative weight. def add_trail_to_queue(self, trail, author, permlink, weight): for voter in self.db.get_trail_voters(trail): voter, voter_weight, limit, delay = voter vote_log = self.db.get_trail_log(voter, trail, self.timestamp) upvote_weight = weight / 100 * voter_weight / 100 print(f"\nTrail: {trail}\nVoter: {voter}\nAuthor: {author}\n" + f"Weight: {upvote_weight}\nLimit: {limit}\nDelay: {delay}\n") if delay != 0: self.db.add_trail_to_queue( trail, author, voter, upvote_weight, limit, delay, permlink, self.timestamp, ) elif len(vote_log) < limit: self.db.add_to_trail_log( author, voter, permlink, upvote_weight, self.timestamp, ) self.vote(voter, author, permlink, weight, type) # The time for when a vote is to be made is calculated from the current # block time + the delay. If the delay is 0 an immediate vote is performed. # Votes get added to the queue and log def add_to_queue(self, author, permlink): for vote in self.db.get_votes(author): voter, weight, limit, delay = vote vote_log = self.db.get_vote_log(voter, author, self.timestamp) print(f"\nVoter: {voter}\nWeight: {weight}\nLimit: " + f"{limit}\nDelay: {delay}") if delay != 0: self.db.add_to_queue( author, voter, weight, limit, delay, permlink, self.timestamp, ) elif len(vote_log) < limit: self.db.add_to_vote_log( author, voter, permlink, weight, self.timestamp, ) self.vote(voter, author, permlink, weight, type) # Go thourgh all the active votes and look if the voter has already # voted on this post. def is_already_voted(self, voter, author, permlink): try: identifier = f"@{author}/{permlink}" post = Post(identifier, self.steem) active_votes = post['active_votes'] for vote in active_votes: if vote['voter'] == voter: return 1 return 0 except Exception as error: return 0 # Posts are verified to be the initial post and not an update def is_new_post(self, author, permlink): identifier = f"@{author}/{permlink}" post = Post(identifier, self.steem) created = post['created'] last_update = post['last_update'] if created != last_update: return 0 else: return 1 # Comment is checked to be of the post type and not a comment to a post. # Posts are then added to queue def process_comment(self, comment): parent_author = comment['parent_author'] author = comment['author'] if parent_author == '' and author in self.upvote_list: permlink = comment['permlink'] if self.is_new_post(author, permlink): print(f'\n\n{self.timestamp} Block: {self.block}') print(f"New post\nAuthor: {author}") self.add_to_queue(author, permlink) # Votes are checked for their voter and if the voter is being trailed def process_vote(self, vote): trail = vote['voter'] if trail in self.trail_list: author = vote['author'] permlink = vote['permlink'] weight = vote['weight'] print(f"\n\nTrail: {trail}\nAuthor: {author}\nPermlink: " + f"{permlink}\nWeight: {weight}\n") self.add_trail_to_queue(trail, author, permlink, weight) # Each block the queue is fetched and checked for votes that have reached # their maturity time. def process_queue(self): dt = datetime.strptime(self.timestamp, '%Y-%m-%dT%H:%M:%S') result = self.db.get_queue() if len(result) > 0: for vote in result: id, voter, author, permlink, weight, type, expire_on = vote if dt > expire_on: self.vote(voter, author, permlink, weight, type) self.db.remove_from_queue(id) # Stream block indefinitely, process each block for comments # Stream is set to head mode def run(self): stream = self.b.stream_from( start_block=self.block, full_blocks=True, ) while True: try: for block in stream: # Set block time and process queue self.timestamp = block['timestamp'] print(f'{self.timestamp} Block: {self.block}', end='\r') self.process_queue() # Fetch author to be upvoted list self.upvote_list = [] for author in self.db.get_authors(): author = re.sub( '[^A-Za-z0-9^-]+', '', author[0].lower(), ) self.upvote_list.append(author) # Fetch trails to be tracked self.trail_list = [] for trail in self.db.get_trails(): trail = re.sub( '[^A-Za-z0-9^-]+', '', trail[0].lower(), ) self.trail_list.append(trail) # Look at each single transaxtion for transaction in block['transactions']: transaction_type = transaction['operations'][0][0] if transaction_type == 'comment': comment = transaction['operations'][0][1] self.process_comment(comment) elif transaction_type == 'vote': vote = transaction['operations'][0][1] self.process_vote(vote) self.block += 1 except Exception as e: print(e) # common exception for api.steemit.com # when the head block is reached s = ("TypeError('an integer is" " required (got type NoneType)',)") if repr(e) == s: time.sleep(1) else: stream = self.b.stream_from( start_block=self.block, full_blocks=True, ) continue
print(len(resteems)) print("================================================================\n") comments_detail = steem.get_content_replies(author_adj, postdetails[3]) print(len(comments_detail)) # MAIN if __name__ == "__main__": while 1: try: for comment in steem.stream_comments(): #match = re.search(r'(?i)(!)StatsBot(!*)', comment['body']) #if match is None: # continue #else: #print("[Normal_Traces] StateBot Summoned. Initiating the process") if (comment.is_main_post()): continue else: url_string = comment['url'].split("#") print('https://steemit.com%s' %(url_string[0])) thread_one = print_stats(url_string[0], comment['author']) thread_one.start() break except Exception as e: print("[Exception] Error Occurred @ Block No: ", BlockInfo.get_current_block_num()) exc_type, exc_value, exc_traceback = sys.exc_info() print("[Exception] Type : ", exc_type) print("[Exception] Value : ", exc_value) print("[Exception] Traceback : ") traceback.print_tb(exc_traceback) break