Beispiel #1
0
 def __init__(self):
     self.msg = Msg(default.logfilename,
                    default.logpath,
                    default.msgmode)
     self.db = axdb.AXdb(default.dbuser,
                         default.dbpass,
                         default.dbname)
     self.steem = SimpleSteem()
     self.react = Reaction()
Beispiel #2
0
 def __init__(self):
     self.steem = SimpleSteem(client_id=default.client_id,
                              client_secret=default.client_secret,
                              callback_url=default.callback_url,
                              screenmode=default.msgmode)
     self.msg = Msg(default.logfilename,
                    default.logpath,
                    default.msgmode)
     self.response = None
     self.post_one = ""
     self.post_two = ""
     self.vote_cut = 0
Beispiel #3
0
 def __init__(self, botname="settings"):
     bot = importlib.import_module("." + botname, "protestbot")
     self.cfg = bot.Config()
     self.steem = SimpleSteem(mainaccount=self.cfg.protester_account,
                              keys=self.cfg.keys,
                              screenmode="verbose",
                              logpath="/home/dragon/")
     self.abuser_of_power = self.cfg.abuser_of_power
     self.protester_account = self.cfg.protester_account
     self.replies = []
     self.the_abused = []
     self.db = BotDB()
     self.db.initialize_database()
     self.db.initialize_abused_database()
     self.db.initialize_upvoted_database()
Beispiel #4
0
 def __init__(self, debug=False, mode="verbose", botname="settings"):
     ''' Uses simplesteem and screenlogger from
         https://github.com/ArtoLabs/SimpleSteem
         https://github.com/ArtoLabs/ScreenLogger
     '''
     bot = importlib.import_module("." + botname, "delegatorbot")
     self.debug = debug
     self.cfg = bot.Config()
     self.msg = Msg(self.cfg.logfilename, self.cfg.logpath, mode)
     self.db = BotDB(self.cfg.dbusername, self.cfg.dbpass, self.cfg.dbname,
                     self.cfg.dbtable, self.cfg.dbposttable,
                     self.cfg.delegatortable)
     self.steem = SimpleSteem(mainaccount=self.cfg.mainaccount,
                              keys=self.cfg.keys,
                              screenmode=mode)
     self.voteweight = 0
     self.bidbot = None
Beispiel #5
0
 def __init__(self):
     self.msg = Msg(default.logfilename, 
                     default.logpath, 
                     default.msgmode)
     self.db = axdb.AXdb(default.dbuser, 
                         default.dbpass, 
                         default.dbname)
     self.steem = SimpleSteem()
     self.react = Reaction()
Beispiel #6
0
class AXverify:
    def __init__(self):
        self.steem = SimpleSteem(client_id=default.client_id,
                                 client_secret=default.client_secret,
                                 callback_url=default.callback_url,
                                 screenmode=default.msgmode)
        self.msg = Msg(default.logfilename,
                       default.logpath,
                       default.msgmode)
        self.response = None
        self.post_one = ""
        self.post_two = ""
        self.vote_cut = 0

    def vote_on_it(self, voter, author, post, weight):
        """ Use the tokens in the database to vote on
        a post. If the vote fails, renews the token
        and tries again.
        """
        db = axdb.AXdb(default.dbuser,
                       default.dbpass,
                       default.dbname)
        if db.get_user_token(voter) is not False:
            accesstoken = db.dbresults[0][1]
            refreshtoken = db.dbresults[0][2]
        else:
            return False
        # If the vote fails then we renew the token
        if not self.sc_vote(voter, author, post, weight, accesstoken):
            print("Renewing token for " + voter)
            newtoken = self.renew_token(voter, refreshtoken)
            if newtoken is not False:
                return self.sc_vote(voter, author, post, weight, newtoken)
            else:
                self.msg.error_message("A NEW TOKEN COULD NOT BE CREATED")
                return False

    def sc_vote(self, voter, author, post, weight, token):
        """ Takes the given token and initializes SteemConnect
        to make a vote. Analyzes the result and prints the
        outcome to screen as well as returns a boolean result.
        """
        self.steem.connect.sc = None
        self.steem.connect.steemconnect(
            token)
        result = self.steem.connect.vote(
            voter,
            author,
            post,
            int(weight))
        try:
            result['error']
        # We use a broad exception clause to "catch" everything
        # that is not an error
        except:
            # The vote was successful
            print(str(voter) + " has voted on "
                  + str(post) + " "
                  + str(weight) + "%")
            return True
        else:
            self.msg.error_message(str(result))
            return False

    def renew_token(self, accountname, refreshtoken):
        """ If the access token has expired
        use the refresh token to get a new accss token.
        """
        if self.steem.verify_key(
                acctname="", tokenkey=refreshtoken):
            db.update_token(self.steem.username,
                            self.steem.accesstoken,
                            self.steem.refreshtoken)
            return self.steem.accesstoken
        else:
            return False

    def get_vote_value(self, acctname, voteweight=100,
                       votepower=0):
        """ Voteweight and votepower are entered 
        as a percentage value (1 to 100)
        If the default is used for votepower (0) 
        it is set by the system at the time
        the account last voted.
        """
        self.steem.check_balances(acctname)
        if votepower == 0:
            votepower = self.steem.votepower
        self.votevalue = self.steem.current_vote_value(
            lastvotetime=self.steem.lastvotetime,
            steempower=self.steem.steempower,
            voteweight=int(voteweight),
            votepower=int(votepower))
        self.voteweight = voteweight
        self.votepower = votepower
        return self.steem.rshares

    def verify_post(self, account1, account2):
        """ Gets only the most recent post, gets the 
        timestamp and finds the age of the post in days.
        Is the post too old? Did account2 
        vote on the post already?
        """
        identifier = self.steem.recent_post(account1)
        if identifier is False or identifier is None:
            self.msg.error_message("No post for " + account1)
            return False
        else:
            permlink = self.steem.util.permlink(identifier)
            votes = self.steem.vote_history(permlink[1], account1)
            for v in votes:
                if v['voter'] == account2:
                    self.msg.error_message(account2 +
                                           " has aready voted on " + permlink[1])
                    return False
        return permlink[1]

    def eligible_posts(self, account1, account2):
        """ Verify the posts of both accounts
        """
        post = self.verify_post(account1, account2)
        if post is False or post is None:
            self.msg.message(account1
                             + " does not have an eligible post.")
            return False
        else:
            self.post_one = post
        post = self.verify_post(account2, account1)
        if post is False or post is None:
            self.msg.message(account2
                             + " does not have an eligible post.")
            return False
        else:
            self.post_two = post
        return True

    def eligible_votes(self, account1, account2,
                       percentage, ratio, flag):
        """ If the flag is raised use the full voting 
        power to make the comparison rather
        than the current voting power. 
        If ratio was not acheived return false 
        Otherwise display approximate 
        upvote matches
        """
        if flag == 1:
            vpow = 100
        else:
            vpow = 0
        v1 = self.get_vote_value(account1, percentage, vpow)
        v2 = self.get_vote_value(account2, 100, vpow)
        v3 = ((v1 / v2) * 100) / float(ratio)
        v3a = round(v3, 2)
        exceeds = False
        if v3a < 1:
            v3 = 1
            exceeds = True
        if v3a > 100:
            v3 = 100
            exceeds = True
        self.msg.message(account2 + " needs to vote "
                         + str(v3a) + "% in order to meet " + account1)
        self.vote_cut = v3
        v4 = self.get_vote_value(account2, v3, vpow)
        v1s = self.steem.rshares_to_steem(v1)
        v4s = self.steem.rshares_to_steem(v4)
        if exceeds and flag != 2:
            if v3 == 1:
                v5 = v4 - v1
                v5s = self.steem.rshares_to_steem(v5)
                self.response = (account2 + "'s vote of " + str(v4s)
                                 + " will be larger than " + account1
                                 + "'s vote by: " + str(v5s))
                self.msg.message(self.response)
            if v3 == 100:
                v5 = v1 - v4
                v5s = self.steem.rshares_to_steem(v5)
                self.response = (account1 + "'s vote of " + str(v1s)
                                 + " will be larger than " + account2
                                 + "'s vote by: " + str(v5s))
                self.msg.message(self.response)
            return False
        else:
            self.msg.message(account1 + " will upvote $" + str(v1s)
                             + " and " + account2 + " will upvote $" + str(v4s))
            return True
Beispiel #7
0
class AXverify:



    def __init__(self):
        self.msg = Msg(default.logfilename, 
                        default.logpath, 
                        default.msgmode)
        self.steem = SimpleSteem()
        self.response = None



    def get_vote_value (self, acctname, voteweight=100, 
                        votepower=0):
        ''' Voteweight and votepower are entered 
        as a percentage value (1 to 100)
        If the default is used for votepower (0) 
        it is set by the system at the time
        the account last voted.
        '''
        self.steem.check_balances(acctname)
        if votepower == 0:
            votepower = self.steem.votepower
        self.votevalue = self.steem.current_vote_value(
                    self.steem.lastvotetime, 
                    self.steem.steempower, 
                    voteweight, 
                    votepower)
        self.voteweight = voteweight
        self.votepower = votepower
        return self.steem.rshares



    def verify_post (self, account1, account2, mode):
        ''' Gets only the most recent post, gets the 
        timestamp and finds the age of the post in days.
        Is the post too old? Did account2 
        vote on the post already?
        '''
        permlink = self.steem.get_post_info(account1)
        if not permlink:
            self.msg.error_message("No post for " + account1)
            return False
        else:
            votes = self.steem.vote_history(account1, permlink)
            for v in votes:
                if v['voter'] == account2:
                    self.msg.message(account2 + 
                        " has aready voted on " + permlink)
                    return False
        return True



    def eligible_posts (self, account1, account2, mode):
        ''' Verify the posts of both accounts
        '''
        if not self.verify_post(account1, account2, mode):
            return False
        if not self.verify_post(account2, account1, mode):
            return False
        return True



    def eligible_votes (self, account1, account2, 
                        percentage, ratio, mode, flag):
        ''' If the flag is raised use the full voting 
        power to make the comparison rather
        than the current voting power. 
        If ratio was not acheived return false 
        Otherwise display approximate 
        upvote matches
        '''
        if flag == 1:
            vpow = 100
        else:
            vpow = 0
        v1 = self.get_vote_value(account1, percentage, vpow, mode)
        v2 = self.get_vote_value(account2, 100, vpow, mode)
        v3 = ((v1 / v2) * 100) / float(ratio)
        v3a = round(v3, 2)
        exceeds = False
        if v3a < 1:
            v3 = 1
            exceeds = True
        if v3a > 100:
            v3 = 100
            exceeds = True
        self.msg.message(account2 + " needs to vote " 
                + str(v3a) + "% in order to meet " + account1)
        v4 = self.get_vote_value(account2, v3, vpow, mode)
        v1s = self.steem.rshares_to_steem(v1)
        v4s = self.steem.rshares_to_steem(v4)
        if exceeds:
            if v3 == 1:
                v5 = v4 - v1
                v5s = self.steem.rshares_to_steem(v5)
                self.response = (account2 + "'s vote of " + str(v4s) 
                                + " will be larger than " + account1 
                                + "'s vote by: " + str(v5s))
                self.msg.message(self.response)
            if v3 == 100:
                v5 = v1 - v4
                v5s = self.steem.rshares_to_steem(v5)
                self.response = (account1 + "'s vote of " + str(v1s) 
                                + " will be larger than " + account2 
                                + "'s vote by: " + str(v5s))
                self.msg.message(self.response)
            return False
        else:
            self.msg.message(account1 + " will upvote $" + str(v1s) 
                    + " and " + account2 + " will upvote $" + str(v4s))
            return True
Beispiel #8
0
 def __init__(self):
     self.msg = Msg(default.logfilename, 
                     default.logpath, 
                     default.msgmode)
     self.steem = SimpleSteem()
     self.response = None
Beispiel #9
0
class DelegatorBot():
    '''
    Main class holds functions for running the bot
    '''
    def __init__(self, debug=False, mode="verbose", botname="settings"):
        ''' Uses simplesteem and screenlogger from
            https://github.com/ArtoLabs/SimpleSteem
            https://github.com/ArtoLabs/ScreenLogger
        '''
        bot = importlib.import_module("." + botname, "delegatorbot")
        self.debug = debug
        self.cfg = bot.Config()
        self.msg = Msg(self.cfg.logfilename, self.cfg.logpath, mode)
        self.db = BotDB(self.cfg.dbusername, self.cfg.dbpass, self.cfg.dbname,
                        self.cfg.dbtable, self.cfg.dbposttable,
                        self.cfg.delegatortable)
        self.steem = SimpleSteem(mainaccount=self.cfg.mainaccount,
                                 keys=self.cfg.keys,
                                 screenmode=mode)
        self.voteweight = 0
        self.bidbot = None

    def get_replies_to_stop(self):
        ''' To have the delegation bot stop following
        someone and thus stop upvoting their posts
        they simply have to type STOP (in all caps)
        in a reply to the delegation bots own reply.
        '''
        c = 0
        # Get the bots history from the blockchain
        h = self.steem.get_my_history(limit=1000)
        if h is False or h is None:
            return False
        # iterate through the history
        for a in h:
            # Is it a comment (reply)?
            if a[1]['op'][0] == "comment":
                # Is it -not- from the bot?
                if not (a[1]['op'][1]['author'] == self.cfg.mainaccount):
                    # Does it contain the word STOP?
                    if re.match(r'STOP', a[1]['op'][1]['body']):
                        self.msg.error_message(a[1]['op'][1]['author'] +
                                               " said STOP in this post: \n" +
                                               a[1]['op'][1]['permlink'])
                        # Get the reply's identifier
                        ident = self.steem.util.identifier(
                            a[1]['op'][1]['author'], a[1]['op'][1]['permlink'])
                        # Unfollow
                        if not self.debug and self.steem.unfollow(
                                a[1]['op'][1]['author']):
                            # Reply to user with confirmation
                            self.steem.reply(
                                ident, "@" + self.cfg.mainaccount +
                                " has stopped " + "following you.")
                            c += 1
        self.msg.message(str(c) + " stop messages received")
        return True

    def process_delegators(self):
        ''' The delegation bot will follow and upvote
        those who have delegated. Delegating less than
        the minimum amount will cause the bot to unfollow
        '''
        # Create the table if it doesn't already exist
        self.db.initialize_delegators()
        # set variables
        followed = 0
        unfollowed = 0
        delegators = {}
        # Get blockchain global variables
        self.steem.global_props()
        # Get bot's history from the blockchain
        h = self.steem.get_my_history(limit=1000)
        if h is False or h is None:
            return False
        for i in h:
            # if the field is the delegate_vesting_shares
            # field than get the name
            # of the delegator and the sp delegated and
            # store it in the 'delegators' dictionary
            if i[1]['op'][0] == "delegate_vesting_shares":
                d = i[1]['op'][1]['delegator']
                vests = float(i[1]['op'][1]['vesting_shares'].replace(
                    " VESTS", ""))
                if d != self.cfg.mainaccount:
                    delegators[d] = vests
        # get all known delegators from the database
        self.db.get_delegators()
        # iterate through new delegators
        for d, vests in delegators.items():
            sp = self.steem.util.vests_to_sp(vests)
            found = False
            follow = False
            unfollow = False
            # iterate through known delegators
            if self.db.dbresults is not None and self.db.dbresults is not False:
                for row in self.db.dbresults:
                    if d == row[1]:
                        # new delegator is already known indicating a possible change
                        found = True
                        # has it been changed?
                        if float(vests) != float(row[2]):
                            self.db.update_delegator(d, vests)
                            self.msg.message(d + " changed delegation to " +
                                             str(vests) + " VESTS (" +
                                             str(sp) + " SP)")
                            # is it above or lower than minimum needed ?
                            if sp >= self.cfg.minimum_delegation:
                                follow = True
                            else:
                                unfollow = True
            # This is really a new delegator
            if found is False:
                # Add them to the database
                self.db.add_delegator(d, vests)
                self.msg.message("New delegation from " + d + " of " +
                                 str(vests) + " VESTS (" + str(sp) + " SP)")
                # Did they send more then the minimum?
                if sp >= self.cfg.minimum_delegation:
                    follow = True
            # Follow
            if follow:
                followed += 1
                if self.debug is False:
                    self.steem.follow(d)
            # Unfollow
            elif unfollow:
                unfollowed += 1
                if self.debug is False:
                    self.steem.unfollow(d)
        self.msg.message(
            str(followed) + " followed, " + str(unfollowed) + " unfollowed")
        return True

    def daily_report(self):
        ''' A report that is generated daily showing a list of current
        delegators, a list of the posts that were upvoted the day before,
        and instructions on how to get upvotes from the bot by delegating.
        '''
        # Create the table if it doesn't already exist
        self.db.initialize_bot_posts()
        # Get the date
        now = datetime.now()
        # Create the title for the report
        title = ("The @" + self.cfg.mainaccount + " Daily Report for " +
                 str(now.strftime("%B")) + " " + str(now.day) + ", " +
                 str(now.year))
        self.msg.message("Creating " + title)
        # Start the body of the report
        body = ("# @" + self.cfg.mainaccount +
                " wants to upvote *YOUR* posts! \n" + "@" +
                self.cfg.mainaccount + ", is an upvote bot run by @" +
                self.cfg.owner + ". Read more " + "below about what @" +
                self.cfg.mainaccount + " does and how you can use it.")
        # Fetch the bot's current upvote value at 100% voting power
        my_vote_value = self.steem.current_vote_value(
            accountname=self.cfg.mainaccount,
            voteweight=100,
            votepoweroverride=100)
        # Add the vote value to the report
        body += ("\n\n___\n### My current upvote value at 100% is: $" +
                 str(my_vote_value) + "\n___\n\n")
        # Add The list of delegators
        del_list = self.daily_report_delegators()
        if del_list is not False and del_list is not None:
            body += del_list
        # The link to delegate to the bot
        body += ('[Delegate now](' + self.cfg.delegationlink +
                 ') to get an upvote like these people.')
        body += (
            '\n\nBy delegating ' + str(self.cfg.minimum_delegation) +
            ' SP or more @' + self.cfg.mainaccount +
            ' will start following you within 45 minutes and upvoting all of your posts too!'
        )
        # Create the permlink from the title
        permlink = re.sub(r' ', '-', title)
        permlink = re.sub(r'[^A-Za-z0-9\-]', '', permlink)
        permlink = permlink.lower()
        # Add a list of all posts that received an upvote
        up_list = self.daily_report_upvote_list()
        if up_list is not False and up_list is not None:
            body += up_list
        # Add the template footer to the report
        footer = self.daily_report_footer()
        if footer is not False and footer is not None:
            body += footer
        # Check debug status
        if self.debug is False:
            self.msg.message("Posting, please wait... ")
            # post the daily report to the blockchain
            if self.steem.post(title, body, permlink, self.cfg.post_tags):
                identifier = self.steem.util.identifier(
                    self.cfg.mainaccount, permlink)
                # Add it to the database
                self.db.add_bot_post(self.cfg.post_tags[0], identifier)
                self.msg.message("Created report " + identifier)
                return identifier
            else:
                return False
        else:
            # If debug is on just print it out to the screen
            print(body)
        return True

    def daily_report_upvote_list(self):
        ''' Creates a list of everyone that has received an upvote
        from the bot in the last 24 hours
        '''
        # get the number of upvotes in the last 24 hours
        numofposts = self.db.upvote_stats(1)
        if (self.db.dbresults is not None and self.db.dbresults is not False
                and numofposts > 0):
            # Create the list header
            upvote_list = ("\n### @" + self.cfg.mainaccount + " upvoted " +
                           str(numofposts) +
                           " posts yesterday. They were:<br>\n")
            # display each post upvoted and the percentage they got
            for post in self.db.dbresults:
                upvote_list = (upvote_list + "https://steemit.com/" + post[1] +
                               "\nThis post was voted at " + str(post[3]) +
                               "%\n\n")
            return str(upvote_list)
        else:
            self.msg.error_message("\nThe database of posts is empty\n")
            return False

    def daily_report_delegators(self):
        ''' Creates a list of the bot's delegators
        '''
        # Get the number of delegators from the database
        numofdelegators = self.db.get_delegators()
        # Are there delegators?
        if (self.db.dbresults is not None and self.db.dbresults is not False
                and numofdelegators > 0):
            # Add the delegator count to the report
            delegator_list = ("\n\n## @" + self.cfg.mainaccount + " has " +
                              str(numofdelegators) +
                              " delegators. They are:\n\n")
            # Get the blockchain global variables
            self.steem.global_props()
            # Iterate through all the delegators and display how much they've delegated
            for d in self.db.dbresults:
                sp = int(self.steem.util.vests_to_sp(float(d[2])))
                # Those who delegate more will have their names made bigger
                if sp > 1000:
                    title_size = "##"
                elif sp > 500:
                    title_size = "###"
                elif sp > self.cfg.minimum_delegation + 5:
                    title_size = "####"
                else:
                    title_size = ""
                delegator_list = (delegator_list + title_size + " @" + d[1] +
                                  " has delegated " + str(sp) + " SP\n")
            # Thank you!
            delegator_list += "## Thank You Delegators! "
            return delegator_list
        else:
            self.msg.error_message("\nThe database of delegators is empty\n")
            return False

    def daily_report_footer(self):
        ''' opens the post_template.txt file and returns it populated with 
        values from settings.py
        '''
        # The directory we're in
        dir_path = os.path.dirname(os.path.realpath(__file__))
        # Does the file exist?
        if os.path.exists(dir_path + "/post_template.txt"):
            # Can we open it?
            with open(dir_path + "/post_template.txt", 'rb') as f:
                try:
                    # split the file up into a list of lines (byte list)
                    footer = f.read().splitlines()
                except:
                    f.close()
                    self.msg.error_message(
                        "\nCould not open post_template.txt!\n")
                    return False
                else:
                    f.close()
                    # Convert, format and return
                    return ((self.make_newlines(footer)).format(
                        self.cfg.footer_top_pic_url, self.cfg.mainaccount,
                        self.cfg.footer_info_url, self.cfg.reply_image,
                        self.cfg.footer_info_url, self.cfg.minimum_delegation,
                        self.cfg.delegationlink,
                        self.cfg.footer_delegate_button_url,
                        self.cfg.allowed_tags, self.cfg.mainaccount,
                        self.cfg.owner, self.cfg.footer_bottom_pic_url,
                        self.cfg.discord_invite_url, self.cfg.website_url,
                        self.cfg.website_name))
        else:
            self.msg.error_message(
                "\nCould not find post_template.txt directory.\n")
            return False

    def make_newlines(self, byte_text_list=None):
        ''' Converts a list of bytes into
        one string and adds the newline character
        '''
        newtext = ''
        # decode the byte list into a string list
        try:
            ls = [i.decode() for i in byte_text_list]
        except Exception as e:
            self.msg.error_message("Byte list error: " + str(e))
            return ""
        # concatenate that list adding newlines
        if len(ls) > 0:
            for line in ls:
                newtext += str(line) + '\n'
        return newtext

    def run_bot(self):
        ''' Runs through the list of those it is following and upvotes
        the most recent post. Vote weight is determined by an algorithm (see below)
        Note that someone does not need to be a delegator to receive
        upvotes, they simply need to be followed by the bot. Of course
        delegating causes the bot to follow someone, but you can also have
        the bot follow someone manually, thus granting them upvotes without delegating.
        '''
        # If the table does not exist create it
        self.db.initialize_bot_mem()
        # Get all the account names of all those the bot is following
        if self.debug:
            following = ["artopium"]
        else:
            following = self.steem.following(self.cfg.mainaccount)
        # Are we following anyone?
        if (following is not None and following is not False
                and len(following) > 0):
            self.msg.message("Following: " + str(len(following)))
            # Iterate through that list
            for f in following:
                self.msg.message('\n' + f)
                # Did we successfully vote?
                if self.debug is False:
                    identifier = self.run_bot_upvote(f)
                else:
                    identifier = "debug"
                if identifier is not False:
                    # Resteem the post
                    if self.debug is False:
                        self.steem.resteem(identifier)
                        # Reply to the post
                        self.run_bot_reply(identifier, f)
                else:
                    self.msg.message("No post found for " + f)
        else:
            self.msg.message("The bot is not following anyone.")
            return False
        return True

    def run_bot_upvote(self, followed):
        ''' upvotes the post if it's eligible
        '''
        # If the table does not exist create it
        self.db.initialize_bot_mem()
        if followed is False or followed is None:
            return False
        identifier = self.steem.recent_post(followed,
                                            self.cfg.post_max_days_old, 1)
        # Is there a post?
        if identifier is False or identifier is None:
            self.msg.message("Identifier is None")
            return False
        # Are they already in the database?
        if self.db.find_bot_mem(identifier) is not False:
            self.msg.message("Already voted for " + identifier)
            return False
        # Do they have the right tags? blognumber is assigned
        # During call to get recent_post
        if self.verify_tags(self.steem.blognumber):
            # Use the algorithm to adjust vote weight, assign it to
            # class variable so it can be accessed by run_bot_reply
            self.voteweight = self.adjust_vote_weight(followed)
            if self.debug:
                print("would've voted: " + identifier)
                v = True
            else:
                # Vote
                v = self.steem.vote(identifier, self.voteweight)
            # Does the blockchain say we already voted?
            if v == "already voted":
                self.msg.message("Already voted for " + identifier)
                # Add it to the database
                self.db.add_bot_mem(identifier, self.voteweight)
                return False
            elif v:
                self.msg.message(followed + " got a vote at " +
                                 str(self.voteweight) + "%")
                # Add it to the database
                self.db.add_bot_mem(identifier, self.voteweight)
                return identifier
            else:
                return False
        else:
            self.msg.message(followed + " does not have the right tag.")
            return False

    def run_bot_reply(self, identifier, followed):
        ''' Resteems a post after the bot has voted on it
        '''
        if identifier is None or followed is None:
            return False

        # The directory we're in
        dir_path = os.path.dirname(os.path.realpath(__file__))
        # Does the file exist?
        if os.path.exists(dir_path + "/reply_template.txt"):
            # Can we open it?
            with open(dir_path + "/reply_template.txt", 'rb') as bfile:
                try:
                    # split the file up into a list of lines (byte list)
                    reply = bfile.read().splitlines()
                except:
                    bfile.close()
                    self.msg.error_message(
                        "\nCould not open reply_template.txt!\n")
                    return False
                else:
                    dailyreport = self.db.get_recent_post()
                    bfile.close()
                    v = int(self.voteweight)
                    # format the tempalate
                    newtext = self.make_newlines(reply)
                    msg = newtext.format(followed, v, self.cfg.mainaccount,
                                         self.cfg.footer_info_url,
                                         self.cfg.reply_image,
                                         self.cfg.footer_info_url, dailyreport,
                                         self.cfg.alert_message)
                    if self.debug:
                        print(identifier)
                        print(msg)
                        return True
                    else:
                        self.steem.reply(identifier, msg)
                        return True
        else:
            self.msg.error_message(
                "\nCould not find reply_template.txt directory.\n")
            return False

    def adjust_vote_weight(self, account):
        ''' This algorithm takes an average of all the votes made in
        the last 3 days, then subtracts that from 3-days-worth of voting power;
        The remaining vote power determines the vote weight.
        '''
        if account is None or account is False:
            return 0
        if account == self.cfg.owner:
            return 100

        bal = self.steem.check_balances()
        votepower = round(
            (self.steem.votepower +
             self.steem.util.calc_regenerated(self.steem.lastvotetime)) / 100,
            2)
        total_vote_weight_used = 1
        # make sure vote power isn't too low
        if votepower > self.cfg.vote_power_threshold:
            numofposts = self.db.upvote_stats(3)
            for i in range(0, numofposts - 1):
                # for each post made we total the weight used, not the actual num of posts
                total_vote_weight_used += self.db.dbresults[i][3]
            # then we adjust based on the total weight used in the last 3 days
            # 800 is 80% of 1000, which is 10 votes at 100% per day (10 x 100)
            print(
                str(numofposts) + " previous posts in the last 3 days with " +
                str(total_vote_weight_used) + " total vote weight.")
            # 3 days of vote power would is 3000
            # to account for new users and surges in use the 3000 is
            # is multiplied by a user defined number
            adj = ((3000 * self.cfg.algorithm_scale) / total_vote_weight_used *
                   100)
            sec_since_last_vote = self.db.already_voted_today(account)
            minutes_since_last_vote = sec_since_last_vote / 60
            print("Base percentage: " + str(adj) + "%")
            # Caps the vote weight
            if adj > self.cfg.vote_weight_max:
                adj = self.cfg.vote_weight_max
                print("Adjusted to " + str(self.cfg.vote_weight_max))
            print("Minutes since last upvote: " + str(minutes_since_last_vote))
            # Check to see if the account is NVIP. If so let's give them the VIP amount
            if len(self.cfg.nvip_accounts) > 0:
                for nvip in self.cfg.nvip_accounts:
                    if account == nvip:
                        adj = self.cfg.nvip_vote_weight
                        print("NVIP account. Adjusted weight to: " + str(adj) +
                              "%")
            # Check to see if the account is VIP. If so let's give them the VIP amount
            if len(self.cfg.vip_accounts) > 0:
                for vip in self.cfg.vip_accounts:
                    if account == vip:
                        adj = self.cfg.vip_vote_weight
                        print("VIP account. Adjusted weight to: " + str(adj) +
                              "%")
            if sec_since_last_vote is not False and int(
                    sec_since_last_vote) < 86400:
                # if we voted them in the last 24 hours we scale the vote
                # based on how long ago the last vote was.
                # If it was less that 3 hours ago the weight is 3%
                if int(sec_since_last_vote
                       ) < self.cfg.reduced_vote_wait_time * 60 * 60:
                    adj = self.cfg.reduced_vote_weight
                else:
                    adj *= sec_since_last_vote / 86400
                print(
                    account +
                    " already got a vote in the last 24 hours. Adjusting vote further: "
                    + str(adj) + "%")
            else:
                if adj < self.cfg.vote_weight_min:
                    adj = self.cfg.vote_weight_min

            return adj
        else:
            return 10

    def verify_tags(self, blognumber):
        ''' Makes sure the post to be voted on has used the
        tags set in settings
        '''
        if blognumber is None:
            return False
        if self.steem.blog[blognumber]['comment']['json_metadata'] is not None:
            tags = json.loads(
                self.steem.blog[blognumber]['comment']['json_metadata'])
            if tags['tags'] is not None:
                for t in tags['tags']:
                    for a in self.cfg.allowed_tags:
                        if t == a:
                            return True
        else:
            self.msg.error_message("Blog comment was 'none'")
        return False

    def boost_post(self, daysback=0, denom="STEEM", amount=0.02):
        ''' boosts the payout of the daily report using bid bots
        '''
        if daysback < 0:
            self.msg.error_message("Invalid date to boost post")
            return False
        if denom != "STEEM" and denom != "SBD":
            self.msg.error_message("Invalid denomination to boost post")
            return False
        if amount < 0.01:
            self.msg.error_message("Invalid amount to boost post")
            return False
        # If the table doesn't exist create it
        self.db.initialize_bot_posts()
        # Get a daiy report from the past
        identifier = self.db.get_recent_post(daysback)
        if identifier is None or identifier is False:
            self.msg.message("No posts found")
            return False
        idkey = self.db.id
        ftag = self.db.firsttag
        # Make the whole url
        boostlink = ("https://steemit.com/" + ftag + "/" + identifier)
        # make sure we have enough in the coffers
        if self.ensure_balance(denom) is not False:
            self.msg.message("Boosting " + boostlink)
            # boost
            if self.debug is False:
                self.steem.transfer_funds(self.bidbot, amount, denom,
                                          boostlink)
            self.msg.message("Sent " + str(amount) + " " + denom + " to " +
                             self.bidbot)
            return True
        else:
            return False

    def ensure_balance(self, denom):
        ''' Does what it says. Ensures that the steem or sbd balance
        of the bot account has not reached below the minimums set in settings.
        Used when "boosting"
        '''
        # If the table doesn't exist create it
        self.db.initialize_bot_posts()
        # Check the bot's balances
        bal = self.steem.check_balances(self.cfg.mainaccount)
        # Check the reward pool
        #self.steem.reward_pool_balances()
        if (denom == "SBD"):
            print("Current SBD balance: " + str(bal[0]))
            self.bidbot = self.cfg.sbd_bidbot
            if float(bal[0]) > float(self.cfg.minimum_balance):
                return True
            else:
                self.msg.message(
                    ("Cannot boost posts because the current " +
                     "SBD balance is {}. The balance must " +
                     "be more than {} SBD").format(bal[0],
                                                   self.cfg.minimum_balance))
                return False
        elif (denom == "STEEM"):
            print("Current STEEM balance: " + str(bal[0]))
            self.bidbot = self.cfg.steem_bidbot
            if bal[1] > self.cfg.minimum_balance:
                return True
            else:
                self.msg.message(
                    ("Cannot boost posts because the current " +
                     "STEEM balance is {}. The balance must " +
                     "be more than {} STEEM").format(bal[1],
                                                     self.cfg.minimum_balance))
                return False
        else:
            return False

    def claim(self):
        ''' Claims the rewards of the bot's account
        '''
        return self.steem.claim_rewards()

    def balance(self):
        ''' Prints the current balance
        '''
        bal = self.steem.check_balances(self.cfg.mainaccount)
        self.msg.message('''
    __{}__
    {} SBD
    {} STEEM
    {} STEEM POWER'''.format(self.steem.mainaccount, bal[0], bal[1], bal[2]))
        return True
Beispiel #10
0
class AXtrans:
    def __init__(self):
        self.msg = Msg(default.logfilename,
                       default.logpath,
                       default.msgmode)
        self.db = axdb.AXdb(default.dbuser,
                            default.dbpass,
                            default.dbname)
        self.steem = SimpleSteem()
        self.react = Reaction()

    def parse_memo(self, **kwargs):
        """ Parses the memo message in a transaction
        for the appropriate action.
        """
        for key, value in kwargs.items():
            setattr(self, key, value)
        try:
            memo = self.memo.split(":")
        # A broad exception is used because any exception
        # should return false.
        except:
            return False
        self.memoid = sec.filter_token(memo[0])
        if len(memo) == 2:
            self.action = sec.filter_account(memo[1])
            return True
        elif len(memo) == 5:
            self.action = sec.filter_account(memo[1])
            self.percentage = sec.filter_number(memo[2])
            self.ratio = sec.filter_number(memo[3], 1000)
            self.duration = sec.filter_number(memo[4], 365)
            return True
        else:
            return False

    def send(self, to="artopium",
             amt="0.001 SBD",
             msg="test"):
        """ Sends the forwarded amount of SBD along
        with the reaction message
        """
        r = amt.split(" ")
        if self.steem.transfer_funds(to, float(r[0]),
                                     r[1], msg):
            self.msg.message(("Transaction committed. Sent {} "
                              "{} to {} with the memo: "
                              "{}").format(r[0], r[1], to, msg))

    def act(self, acct1, acct2, rstatus, sendto):
        """ Decides how to react baed on the action
        present in the memo message
        """
        if not self.db.get_user_token(self.memofrom):
            self.react.ignore(
                ("@{} is not a current member of "
                 + " https://steemax.trade !!Join now!! "
                 + "using SteemConnect.").format(self.memofrom))
        elif self.action == "start":
            self.react.start(acct1,
                             acct2,
                             self.memofrom,
                             rstatus,
                             self.memoid)
        elif self.action == "cancel":
            self.react.cancel(self.memofrom,
                              self.memoid)
        elif self.action == "accept":
            self.react.accept(acct1,
                              acct2,
                              self.memofrom,
                              rstatus,
                              self.memoid)
        elif self.action == "barter":
            self.react.barter(acct1,
                              acct2,
                              self.memoid,
                              self.memofrom,
                              rstatus,
                              self.percentage,
                              self.ratio,
                              self.duration)
        else:
            self.react.ignore("Invalid action.")
        if self.react.reaction == "refund":
            self.sendto = self.memofrom
        else:
            self.sendto = sendto

    def parse_history_record(self, record, lasttrans):
        """ Parses the blockchain record for transdactions
        sent to @steem-ax 
        """
        if (record[1]['op'][0] == 'transfer'
            and datetime.strptime(
                record[1]['timestamp'],
                '%Y-%m-%dT%H:%M:%S')
                > lasttrans
            and re.match(r'^[0-9]{32}',
                         record[1]['op'][1]['memo'])
            and record[1]['op'][1]['to']
                == self.steem.mainaccount):
            return True
        else:
            return False

    def fetch_history(self):
        """ Processes the transaction history. 
        The memo message is parsed for a valid 
        command and performs the 
        directed action.
        """
        rt = self.db.get_most_recent_trans()
        for a in self.steem.get_my_history():
            if self.parse_history_record(a, rt):
                if self.parse_memo(memofrom=a[1]['op'][1]['from'],
                                   memo=a[1]['op'][1]['memo'],
                                   amount=a[1]['op'][1]['amount'],
                                   trxid=a[1]['trx_id'],
                                   txtime=a[1]['timestamp']):
                    if self.db.verify_memoid(self.memofrom, self.memoid):
                        self.act(self.db.dbresults[0][0],
                                 self.db.dbresults[0][1],
                                 int(self.db.dbresults[0][2]),
                                 self.db.sendto)
                    else:
                        self.react.ignore("Invalid Memo ID.")
                        self.sendto = self.memofrom
                else:
                    self.react.ignore("Invalid Memo.")
                    self.sendto = self.memofrom
                self.send(self.sendto,
                          self.amount,
                          self.react.returnmsg)
                self.db.add_trans(self.trxid,
                                  self.memofrom,
                                  self.amount,
                                  self.memoid,
                                  self.react.reaction,
                                  self.txtime)
Beispiel #11
0
class AXtrans:
    def __init__(self):
        self.msg = Msg(default.logfilename, default.logpath, default.msgmode)
        self.db = axdb.AXdb(default.dbuser, default.dbpass, default.dbname)
        self.steem = SimpleSteem()
        self.react = Reaction()

    def parse_memo(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)
        # Ew this is dirty and came from
        # strangers! Must be sanitized!
        try:
            memo = self.memo.split(":")
        except:
            return False
        self.memoid = memo[0] or None
        if re.match(r'^[A-Za-z0-9\:]$', self.memoid):
            return False
        if len(memo) == 2:
            self.action = memo[1] or None
            return True
        elif len(memo) == 5:
            self.action = memo[1] or None
            self.percentage = memo[2] or None
            self.ratio = memo[3] or None
            self.duration = memo[4] or None
            return True
        else:
            return False

    def send(self, to="artopium", amt="0.001 SBD", msg="test"):
        r = amt.split(" ")
        if self.steem.transfer_funds(to, float(r[0]), r[1], msg):
            self.msg.message(("Transaction committed. Sent {} "
                              "{} to {} with the memo: "
                              "{}").format(r[0], r[1], to, msg))

    def act(self, acct1, acct2, rstatus, sendto):
        if not self.db.get_user_token(self.memofrom):
            self.react.ignore(("{} is not a current member of " +
                               " https://steemax.trade! Join now " +
                               "using SteemConnect.").format(self.memofrom))
        elif (self.action == "start"):
            self.react.start(acct1, acct2, self.memofrom, rstatus, self.memoid)
        elif (self.action == "cancel"):
            self.react.cancel(self.memofrom, self.memoid)
        elif (self.action == "accept"):
            self.react.accept(acct1, acct2, self.memofrom, rstatus,
                              self.memoid)
        elif (self.action == "barter"):
            self.react.barter(acct1, acct2, self.memoid, self.memofrom,
                              rstatus, self.percentage, self.ratio,
                              self.duration)
        else:
            self.react.ignore("Invalid action.")
        if self.react.reaction == "refund":
            self.sendto = self.memofrom
        else:
            self.sendto = sendto

    def parse_history_record(self, record, lasttrans):
        if (record[1]['op'][0] == 'transfer' and datetime.strptime(
                record[1]['timestamp'], '%Y-%m-%dT%H:%M:%S') > lasttrans
                and re.match(r'^[0-9]{32}', record[1]['op'][1]['memo'])
                and record[1]['op'][1]['to'] == self.steem.mainaccount):
            return True
        else:
            return False

    def fetch_history(self):
        ''' Processes the transaction history. 
        The memo message is parsed for a valid 
        command and performs the 
        directed action.
        '''
        rt = self.db.get_most_recent_trans()
        for a in self.steem.get_my_history():
            if self.parse_history_record(a, rt):
                if self.parse_memo(memofrom=a[1]['op'][1]['from'],
                                   memo=a[1]['op'][1]['memo'],
                                   amount=a[1]['op'][1]['amount'],
                                   trxid=a[1]['trx_id'],
                                   txtime=a[1]['timestamp']):
                    if self.db.verify_memoid(self.memofrom, self.memoid):
                        self.act(self.db.dbresults[0][0],
                                 self.db.dbresults[0][1],
                                 int(self.db.dbresults[0][2]), self.db.sendto)
                    else:
                        self.react.ignore("Invalid Memo ID.")
                        self.sendto = self.memofrom
                else:
                    self.react.ignore("Invalid Memo.")
                    self.sendto = self.memofrom

                self.send(self.sendto, self.amount, self.react.returnmsg)
                self.db.add_trans(self.trxid, self.memofrom, self.amount,
                                  self.memoid, self.react.reaction,
                                  self.txtime)
Beispiel #12
0
class ProtestBot:
    def __init__(self, botname="settings"):
        bot = importlib.import_module("." + botname, "protestbot")
        self.cfg = bot.Config()
        self.steem = SimpleSteem(mainaccount=self.cfg.protester_account,
                                 keys=self.cfg.keys,
                                 screenmode="verbose",
                                 logpath="/home/dragon/")
        self.abuser_of_power = self.cfg.abuser_of_power
        self.protester_account = self.cfg.protester_account
        self.replies = []
        self.the_abused = []
        self.db = BotDB()
        self.db.initialize_database()
        self.db.initialize_abused_database()
        self.db.initialize_upvoted_database()

    def get_all_posts_and_replies(self, friends=False):
        print("     __ Retrieving abuser's history __\n\n")
        h = self.steem.get_my_history(account=self.abuser_of_power, limit=1000)
        if h is False or h is None:
            return None
        for a in h:
            if a[1]['op'][0] == "comment":
                ident = None
                if friends:
                    if (a[1]['op'][1]['author'] != self.abuser_of_power):
                        permlink = a[1]['op'][1]['permlink']
                        author = a[1]['op'][1]['author']
                        ident = self.steem.util.identifier(author, permlink)
                else:
                    if (a[1]['op'][1]['author'] == self.abuser_of_power):
                        permlink = a[1]['op'][1]['permlink']
                        ident = self.steem.util.identifier(
                            self.abuser_of_power, permlink)
                if ident is not None:
                    duplicate_found = False
                    for r in self.replies:
                        if r == ident:
                            duplicate_found = True
                    if not duplicate_found:
                        if not self.db.already_posted(ident):
                            self.replies.append(ident)
                            print("\n__ *new post* __")
                            print(ident)

    def find_downvoted_authors(self):
        print("     __ Retrieving list of the abused __\n\n")
        h = self.steem.get_my_history(account=self.abuser_of_power, limit=1000)
        if h is False or h is None:
            return None
        for a in h:
            if a[1]['op'][0] == "vote":
                if (a[1]['op'][1]['voter'] == self.abuser_of_power):
                    if (a[1]['op'][1]['weight'] < 0):
                        author = a[1]['op'][1]['author']
                        permlink = a[1]['op'][1]['permlink']
                        ident = self.steem.util.identifier(author, permlink)
                        duplicate_found = False
                        for b in self.the_abused:
                            if b == author:
                                duplicate_found = True
                        if not duplicate_found:
                            self.the_abused.append(ident)
                            print("\n__ *newly abused* __")
                            print(ident)

    def upvote_the_downvoted(self):
        if self.the_abused is not None and len(self.the_abused) > 0:
            for a in self.the_abused:
                if not self.db.already_upvoted(a):
                    if self.cfg.weight < 0:
                        w = self.cfg.weight * -1
                    else:
                        w = self.cfg.weight
                    self.steem.vote(a, weight=w)
                    self.db.add_upvote(a)
                    print("Upvoted {} by {}%".format(a, w))

    def send_memos_to_the_downvoted(self):
        if self.ensure_balance():
            self.find_downvoted_authors()
            if self.the_abused is not None and len(self.the_abused) > 0:
                pmsg = self.memo_temp()
                for a in self.the_abused:
                    self.steem.transfer_funds(a, 0.001, "STEEM", pmsg)
                    print("Sent memo to " + a)
            else:
                print("No one has been downvoted!")

    def ensure_balance(self):
        bal = self.steem.check_balances(self.protester_account)
        print("Current STEEM balance: " + str(bal[1]))
        if float(bal[1]) > 0.0001:
            return True
        else:
            return False

    def reply_to_abuser_posts(self, friends=False):
        self.get_all_posts_and_replies(friends)
        pmsg = self.protest_temp()
        for r in self.replies:
            if self.steem.reply(r, pmsg):
                if not friends and self.cfg.downvote:
                    self.steem.vote(r, weight=self.cfg.weight)
            self.db.add_reply(r)

    def post_to_profile(self):
        pmsg = self.protest_temp()
        permlink = re.sub(r' ', '-', self.cfg.title)
        permlink = re.sub(r'[^A-Za-z0-9\-]', '', permlink)
        permlink = permlink.lower()
        self.steem.post(title, pmsg, permlink, self.cfg.tags)

    def template(self, filename):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        if os.path.exists(dir_path + "/" + filename):
            with open(dir_path + "/" + filename, 'r') as f:
                try:
                    msg = f.read()
                except:
                    f.close()
                    print("\nCould not open post_template.txt!\n")
                    return None
                else:
                    f.close()
                    return msg
        return None

    def protest_temp(self):
        msg = self.template(self.cfg.protest_template)
        pmsg = msg.format(self.abuser_of_power, self.abuser_of_power,
                          self.protester_account, self.protester_account,
                          self.protester_account, self.protester_account,
                          self.protester_account, self.protester_account,
                          self.protester_account, self.abuser_of_power)
        return pmsg

    def memo_temp(self):
        msg = self.template(self.cfg.memo_template)
        return msg.format(self.abuser_of_power, self.abuser_of_power)
Beispiel #13
0
class AXtrans:



    def __init__(self):
        self.msg = Msg(default.logfilename, 
                        default.logpath, 
                        default.msgmode)
        self.db = axdb.AXdb(default.dbuser, 
                            default.dbpass, 
                            default.dbname)
        self.steem = SimpleSteem()
        self.react = Reaction()



    def parse_memo(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)
        # Ew this is dirty and came from 
        # strangers! Must be sanitized!
        try:
            memo = self.memo.split(":")
        except:
            return False
        self.memoid = memo[0] or None
        if re.match(r'^[A-Za-z0-9\:]$', self.memoid):
            return False
        if len(memo) == 2:
            self.action = memo[1] or None
            return True
        elif len(memo) == 5:
            self.action = memo[1] or None
            self.percentage = memo[2] or None
            self.ratio = memo[3] or None
            self.duration = memo[4] or None
            return True
        else:
            return False



    def send(self, to="artopium", 
                    amt="0.001 SBD", 
                    msg="test"):
        r = amt.split(" ")
        if self.steem.transfer_funds(to, float(r[0]), 
                                    r[1], msg):
            self.msg.message(("Transaction committed. Sent {} "
                            "{} to {} with the memo: "
                            "{}").format(r[0], r[1], to, msg))



    def act(self, acct1, acct2, rstatus, sendto):
        if not self.db.get_user_token(self.memofrom):
            self.react.ignore(
                ("{} is not a current member of "
                + " https://steemax.trade! Join now "
                + "using SteemConnect.").format(self.memofrom))
        elif (self.action == "start"):
            self.react.start(acct1, 
                            acct2, 
                            self.memofrom, 
                            rstatus,
                            self.memoid)
        elif (self.action == "cancel"):
            self.react.cancel(self.memofrom, 
                            self.memoid)
        elif (self.action == "accept"):
            self.react.accept(acct1, 
                            acct2, 
                            self.memofrom, 
                            rstatus,
                            self.memoid)
        elif (self.action == "barter"):
            self.react.barter(acct1, 
                            acct2, 
                            self.memoid, 
                            self.memofrom, 
                            rstatus, 
                            self.percentage, 
                            self.ratio, 
                            self.duration)
        else:
            self.react.ignore("Invalid action.")
        if self.react.reaction == "refund":
            self.sendto = self.memofrom
        else:
            self.sendto = sendto



    def parse_history_record(self, record, lasttrans):
        if (record[1]['op'][0] == 'transfer'
                and datetime.strptime(
                    record[1]['timestamp'], 
                    '%Y-%m-%dT%H:%M:%S')  
                > lasttrans
                and re.match(r'^[0-9]{32}', 
                    record[1]['op'][1]['memo'])
                and record[1]['op'][1]['to'] 
                == self.steem.mainaccount):
            return True
        else:
            return False



    def fetch_history(self):
        ''' Processes the transaction history. 
        The memo message is parsed for a valid 
        command and performs the 
        directed action.
        '''
        rt = self.db.get_most_recent_trans()
        for a in self.steem.get_my_history():
            if self.parse_history_record(a, rt):
                if self.parse_memo(memofrom=a[1]['op'][1]['from'], 
                                memo=a[1]['op'][1]['memo'], 
                                amount=a[1]['op'][1]['amount'], 
                                trxid=a[1]['trx_id'], 
                                txtime=a[1]['timestamp']):
                    if self.db.verify_memoid(self.memofrom, self.memoid):
                        self.act(self.db.dbresults[0][0],
                                self.db.dbresults[0][1],
                                int(self.db.dbresults[0][2]),
                                self.db.sendto)
                    else:
                        self.react.ignore("Invalid Memo ID.")
                        self.sendto = self.memofrom
                else:
                    self.react.ignore("Invalid Memo.")
                    self.sendto = self.memofrom

                self.send(self.sendto, 
                                self.amount, 
                                self.react.returnmsg)
                self.db.add_trans(self.trxid, 
                                self.memofrom, 
                                self.amount, 
                                self.memoid, 
                                self.react.reaction, 
                                self.txtime)