예제 #1
0
    def expire(self):
        """
        Expire a pending tip
        """
        lg.debug("> HkAction::expire()")

        # Move coins back into self.u_from account
        lg.info("HkAction::expire(): moving %s %s from %s to %s", self.coinval, self.coin.upper(), self.haikuberu.conf.service[self.service].username, self.u_from.username)

        # Move coins from dogetipbot back to a.u_from account
        b = user.HkUser(self.haikuberu, self.service, self.haikuberu.conf.service[self.service].username)
        b.sub_coin(coin = self.coin, amount = self.coinval)
        self.u_from.add_coin(coin = self.coin, amount = self.coinval)

        # Save transaction as expired
        self.haikuberu.db.execute("UPDATE action SET state = 'expired' WHERE action_id = %s ", (self.action_id))

        lg.debug("< HkAction::expire() DONE")
        return True
예제 #2
0
    def decline(self):
        lg.debug("> HkAction::decline()")

        actions = get_actions(command='givetip', to_user = self.u_from.username, state = 'pending', haikuberu = self.haikuberu)
        if actions:
            for a in actions:
                # Move coins back into a.u_from account
                lg.info("HkAction::decline(): moving %s %s from %s to %s", a.coinval, a.coin.upper(), 'dogetipbot', a.u_from.username)

                # Move coins from dogetipbot back to a.u_from account
                b = user.HkUser(self.haikuberu, 'reddit', 'dogetipbot')
                b.sub_coin(coin=a.coin, amount=a.coinval)
                a.u_from.add_coin(coin=a.coin, amount=a.coinval)

                # Save transaction as declined
                a.save('declined')

        # Save action to database
        self.save('failed')

        lg.debug("< HkAction::decline() DONE")
        return True
예제 #3
0
    def givetip(self, is_pending=False):

        # Debug
        lg.debug("> HkAction::givetip()")
        my_id = "NoMessageID"
        
        self.is_pending = is_pending
        
        # Return value assumes failure
        return_value = False
        
        # Set message ID (unique ID) if there is one
        if self.msg_id:
            my_id = self.msg_id

        # Check if action has been processed
        if check_action(command = self.command, msg_id = my_id, haikuberu = self.haikuberu, is_pending = is_pending, service = self.service):
            # Found action in database, returning
            lg.warning("HkAction::givetip(): duplicate action %s (msg.id %s), ignoring", self.command, my_id)
            return False

        # Validate action
        if not self.validate(is_pending = is_pending):
            # Couldn't validate action, returning
            return False

        # Sending to a user
        if self.u_to:
            # Pending check
            if is_pending:
                # This is accept() of pending transaction, so move coins from pending account to receiver
                lg.info("HkAction::givetip(): moving %f %s from %s to %s...", self.coinval, self.coin.upper(), 'dogetipbot', self.u_to.username)
                b = user.HkUser(self.haikuberu, self.service, self.haikuberu.conf.service[self.service].username)
                b.sub_coin(coin=self.coin, amount=self.coinval)
                self.u_to.add_coin(coin=self.coin, amount=self.coinval)
            else:
                # This is not accept() of pending transaction, so move coins from tipper to receiver
                lg.info("HkAction::givetip(): moving %f %s from %s to %s...", self.coinval, self.coin.upper(), self.u_from.username, self.u_to.username)
                self.u_from.sub_coin(coin=self.coin, amount=self.coinval)
                self.u_to.add_coin(coin=self.coin, amount=self.coinval)

            # Transaction succeeded (save returns True on success)
            return_value = self.save('completed')

        elif self.addr_to:
            # Process tip to address
            try:
                lg.info("HkAction::givetip(): sending %f %s to %s...", self.coinval, self.coin, self.addr_to)
                
                # Send withdraw to blockchain
                self.txid = self.haikuberu.coins[self.coin].sendtoaddr(_userfrom=self.u_from.username, _addrto=self.addr_to, _amount=self.coinval)

                # Subtract coins from user account
                self.u_from.sub_coin(coin=self.coin, amount=self.coinval)

                # Transaction is pending until confirmed
                return_value = self.save('pending')
                
                # Put in unprocessed table for confirmation check
                self.haikuberu.db.execute("INSERT INTO unprocessed SET txid = '" + self.txid + "' ")

            except Exception as e:
                # Transaction failed
                self.save('failed')
                lg.error("HkAction::givetip(): sendtoaddr() failed")

        # Now send notifications
        self.tip_notification()
        
        # Done
        lg.debug("< HkAction::givetip() DONE")
        return None
예제 #4
0
    def __init__(self, haikuberu=None, msg=None, deleted_msg_id = None, deleted_created_utc=None):

        # Debug
        lg.debug("> HkAction::__init__() BEGIN INIT")

        # Make sure message and haikuberu object were passed
        if not bool(msg):
            raise Exception("HkAction::__init__: Message not set, this should never happen")

        if not bool(haikuberu):
            raise Exception("HkAction::__init__: Haikuberu obj not set, this should never happen")
        self.msg = json.loads(msg['body'])
        self.haikuberu = haikuberu

        # Queue ID
        self.queue_id = msg['id'] if 'id' in msg else ''
        self.queue_res_id = msg['reservation_id'] if 'reservation_id' in msg else ''


        # Error
        self.error = ''
        self.state = ''

        # Config variables
        self.config1 = None
        self.config2 = None
        self.config3 = None
        self.config4 = None
        self.config5 = None
        self.config6 = None
        self.config7 = None
        self.config8 = None
        self.config9 = None
        self.config10 = None
        
        # Action ID
        self.action_id = self.msg.get("action_id", None)
        
        # Command / type
        self.service = self.msg['service']
        self.service_id = hkservice.HkService(self.haikuberu).get_from_name(self.service)
        self.command = self.msg['type']
        self.u_from = self.msg['u_from']

        # Currency
        self.coin = 'dog'
        self.fiat = self.msg.get("fiat", None)
        self.coinval = self.msg.get('coin_val', None)
        self.fiatval = self.msg.get("fiatval", None)
        self.fiat = self.msg.get("fiat", None)

        # Reddit specific
        self.msg_id = self.msg.get("msgid", None)
        self.created_utc = self.msg.get("created_utc", None)
        self.verify = self.msg.get("verify", None)
        self.subreddit = self.msg.get('subreddit', None)
        self.fullname = self.msg.get('fullname', None)

        # Twitch specific
        self.channel = self.msg.get("channel", None)

        # Twitter specific
        self.tweet_id = self.msg.get("tweet_id", None)

        # Disqus specific
        self.post_id = self.msg.get("post_id", None)
        self.thread_id = self.msg.get("thread_id", None)

        # Set configuration field values
        if self.service == 'reddit':
            self.config1 = self.msg_id
            self.config2 = self.fullname
            self.config3 = self.subreddit
            self.config4 = self.msg.get("msg_link", None)
            self.config5 = self.msg.get("verify", None)
        elif self.service == 'twitch':
            self.config1 = self.channel
        elif self.service == 'twitter':
            self.config1 = self.tweet_id
        elif self.service == 'disqus':
            self.config1 = self.post_id
            self.config2 = self.thread_id

        # Address
        self.addr_to = self.msg.get("addr_to", None)
        self.u_to = self.msg.get('u_to', None)
        self.u_to_service = self.msg.get('u_to_service', None)

        # To and from user objects
        self.u_to = user.HkUser(haikuberu, self.service, self.u_to) if bool(self.u_to) else None
        self.u_from = user.HkUser(haikuberu, self.service, self.u_from)

        if self.coinval == 'all':
            if self.u_from.is_registered():
                self.coinval = self.u_from.get_balance(self.coin)
            else:
                self.coinval = 0

        # Sanity check
        if not bool(self.service):
            raise Exception("HkAction::__init__: Service not set in message")

        if not bool(self.command):
            raise Exception("HkAction::__init__: Type of command not set in message")

        if not bool(self.u_from):
            raise Exception("HkAction::__init__: u_from not set in message")
        if self.command in ['givetip', 'withdraw']:
            if not (bool(self.u_to) ^ bool(self.addr_to)):
                raise Exception("HkAction::__init__(command=%s): u_to xor addr_to must be set" % (self.command))

        # Convert coinval and fiat to decimal, if necesary
        if self.coinval and type(self.coinval) == unicode and self.coinval.replace('.', '').isnumeric():
            self.coinval = Decimal(self.coinval)
        if self.fiatval and type(self.fiatval) == unicode and self.fiatval.replace('.', '').isnumeric():
            self.fiatval = Decimal(self.fiatval)

        # Truncate precisoin
        if self.coinval:
            self.coinval = Decimal(str(self.coinval).replace(',',''))
            lg.debug("HkAction::init() Converting coinval to decimal %s", self.coinval)
            self.coinval = Decimal(Decimal(trunc(self.coinval * 100000000)) / 100000000)

        lg.debug("< HkAction::__init__() DONE")
예제 #5
0
    def validate(self, is_pending=False):
        """
        Validate an action
        """
        lg.debug("> HkAction::validate()")

        if self.command in ['givetip', 'withdraw']:
            # Fiat yo
            self.fiat = 'usd'
            
            if self.coinval == None:
                self.coinval = 0
            
            self.fiatval = self.haikuberu.coin_value('dog', 'usd') * self.coinval

            # Final check - is this a to_addr transaction and is the address owned by dogetipbot?
            if self.addr_to:
                # Address validation
                try:
                    if not addressvalidate.is_dogecoin_address(self.addr_to):
                        raise ValueError("Not an address")
                except ValueError:
                    self.save('failed', 'addr_invalid')
                    self.tip_notification()
                    return False
                
                sqlcheck = "SELECT user_id from address where address = %s "
                mysqlrow = self.haikuberu.db.execute(sqlcheck,(self.addr_to)).fetchone()
                lg.debug('HkAction::validate(): Checking if user is sending to a dogetipbot address')
                lg.debug(sqlcheck, (self.addr_to))
                if not mysqlrow:
                    lg.debug("HkAction::givetip(%s): external address, hit the blockchain",self.addr_to)
                else:
                    # Address is owned by dogetipbot, now figure out service/username
                    lg.debug("HkAction::givetip(%s): sneaky m**********r! found a user_id %s", self.addr_to, mysqlrow['user_id'])
                    user_id = mysqlrow['user_id']
                    sql = "SELECT username.username, service.service_name FROM username JOIN service ON service.service_ID = username.service_id where username.user_id = %s AND username.service_id = %s"
                    mysqlrow = self.haikuberu.db.execute(sql,(user_id, self.service_id)).fetchone()
                    if not mysqlrow:
                        lg.debug('HkAction::givetip(): Failed in a bad spot, no username/service found for user_id THIS SHOULDNT HAPPEN')
                    else:
                        self.u_to=user.HkUser(self.haikuberu, mysqlrow['service_name'], mysqlrow['username'])
                        lg.debug("HkAction::givetip(%s): sneaky m**********r! it's really %s from %s service",self.addr_to,mysqlrow['username'], mysqlrow['service_name'])

            # Check if u_from has registered
            if not self.u_from.is_registered():
                lg.debug("HkAction::validate(): %s", 'From User Not Registered')
                self.save('failed', 'not_registered')
                self.tip_notification()
                return False

            # Verify that u_from has coin address
            if not self.u_from.get_addr(coin=self.coin):
                lg.error("HkAction::validate(): user %s doesn't have %s address", self.u_from.username, self.coin.upper())
                self.save('failed')
                return False

            # Verify minimum transaction size
            txkind = 'givetip' if self.u_to else 'withdraw'
            if self.coinval < self.haikuberu.conf.coins[self.coin].minconf[txkind]:

                lg.debug("HkAction::validate(): tip below minimum amt CHEAP ASS")
                self.save('failed', 'tip_below_minimum')
                self.tip_notification()
                return False

            # Verify balance (unless it's a pending transaction being processed, in which case coins have been already moved to pending acct)
            if self.u_to and not is_pending:
                # Tip to user (requires less confirmations)
                balance_avail = self.u_from.get_balance(coin=self.coin)
                if(balance_avail < self.coinval):
                    lg.debug("HkAction::validate(): Not Enough Coins To send the tip")
                    self.save('failed', 'balance_too_low')
                    self.tip_notification()
                    return False

            elif self.addr_to:
                # Tip/withdrawal to address (requires more confirmations)
                balance_avail = self.u_from.get_balance(coin=self.coin)
                if balance_avail < self.coinval:
                    lg.debug("HkAction::validate():  Im pretty sure this is just a repetetive fail")
                    self.save('failed')
                    return False

            # Check if u_to has any pending coin tips from u_from
            if self.u_to and not is_pending:
                if check_action(command='givetip', state='pending', to_user=self.u_to.username, from_user=self.u_from.username, coin=self.coin, haikuberu=self.haikuberu, service=self.service):
                    lg.debug("HkAction::validate(): TIP FAILED")
                    self.save('failed')
                    return False

            # Check if u_to has registered, if applicable
            if self.u_to and not self.u_to.is_registered():
                # u_to not registered:
                # - move tip into pending account
                # - save action as 'pending'
                # - notify u_to to accept tip <<< LOL FIGURE OUT ON YOUR OWN
                b = user.HkUser(self.haikuberu, self.service, self.haikuberu.conf.service[self.service].username)

                # Move coins into pending account
                minconf = self.haikuberu.coins[self.coin].conf.minconf.givetip
                lg.info("HkAction::validate(): moving %s %s from %s to %s (minconf=%s)...", self.coinval, self.coin.upper(), self.u_from.username, self.haikuberu.conf.service[self.service].username, minconf)

                # move from user to dogetipbot
                self.u_from.get_balance(coin=self.coin)
                b.get_balance(coin=self.coin)
                self.u_from.sub_coin(coin=self.coin, amount=self.coinval)
                b.add_coin(coin=self.coin, amount=self.coinval)

                # Save action as pending
                self.save('pending')
                
                # Send pending notifications
                self.tip_notification()

                # Action saved as 'pending', return false to avoid processing it further
                return False

            # Validate addr_to, if applicable
            if self.addr_to:
                if not self.haikuberu.coins[self.coin].validateaddr(_addr=self.addr_to):
                    lg.debug("HkAction::validate(): address not valid")
                    self.save('failed', 'addr_invalid')
                    self.tip_notification()
                    return False

            # Validate motherfucking balance if its a withdraw and there is not user_to set
            if self.addr_to and not self.u_to:
                hotwallet_amt = self.haikuberu.coins['dog'].conn.getbalance()
                if (self.coinval > hotwallet_amt):
                    lg.debug("HkAction::validate(): HOT WALLET DEPLETED")
                    self.save('failed')
                    if self.haikuberu.conf.misc.notify.enabled:
                        self.haikuberu.notify(_msg="Transaction exceeded hot wallet balance. User affected: " + self.u_from.username + " " + str(self.coinval))
                    return False

        # Action is valid
        lg.debug("< HkAction::validate() DONE")
        return True
예제 #6
0
    def gold(self):
        lg.debug("HkAction::history()")

        if not self.u_from.is_registered():
            self.save('failed', 'not_registered')
            return self.error_notification('not_registered')
        
        # If there is a fiat issue, return
        if self.haikuberu.coin_value('dog', 'usd') <= 0:
            self.save('failed', 'fiat_error')
            self.error_notification('fiat_error')
            return self

        # Calculate the fiat and round to nearest 100
        self.coinval = trunc(4 / self.haikuberu.coin_value('dog', 'usd'))
        self.coinval -= self.coinval % 100
        
        self.fiatval = 4
        
        # Fiat sanity check
        if self.coinval < 10000:
            self.save('failed', 'fiat_error')
            self.error_notification('fiat_error')
            return self

        # Check if u_from has registered
        if not self.u_from.is_registered():
            self.save('failed', 'not_registered')
            self.error_notification('not_registered')
            return self
 
        print self.coinval
 
        # Check u_from balance
        balance_avail = self.u_from.get_balance(coin=self.coin)
        if(balance_avail < self.coinval):
            self.save('failed', 'balance_too_low')
            self.error_notification('balance_too_low')
            return self

        # Move coins
        self.u_from.sub_coin(self.coin, self.coinval)
        reddit_bot = user.HkUser(self.haikuberu, 'reddit', 'dogetipbot')
        reddit_bot.add_coin(self.coin, self.coinval)
        
        self.save('completed')
        
        # Base notification data
        data = {
            'type'          : 'gold_sent',
            'service'       : self.service,
            'command'       : self.command,
            'u_from'        : self.u_from.username,
            'u_to'          : self.u_to.username,
            'addr_from'     : self.u_from.get_addr('dog'),
            'coinval'       : self.coinval,
            'fiatval'       : self.fiatval,
            'config1'       : self.config1,
            'config2'       : self.config2,
            'config3'       : self.config3,
            'config4'       : self.config4,
            'config5'       : self.config5,
            'config6'       : self.config6,
            'config7'       : self.config7,
            'config8'       : self.config8,
            'config9'       : self.config9,
            'config10'      : self.config10,
        }
        self.haikuberu.push_messasge_out(json.dumps(data))
        self.notification.append(data.copy())
        
        if self.u_to and not self.u_to.is_registered():
            data['type'] = 'gold_received'
            self.haikuberu.push_messasge_out(json.dumps(data))
            self.notification.append(data.copy())        

        return self