예제 #1
0
 def test_http_error_create_temp_message(self, mock_soundcloud):
     soundcloud = SoundCloudAPI()
     mock_soundcloud.return_value.post.side_effect = requests.exceptions.HTTPError('error')
     soundcloud.send_message(to_user_id='123577402', message="test")
     res = StuckMessage.objects.all()
     self.assertEqual(len(res), 1)
     self.assertEqual(res[0].user_id, '123577402')
예제 #2
0
    def test_already_existing_mention(self, mock_soundcloud):
        next_href = 'https://api.soundcloud.com/e1/me/activities.json?' + \
                    'limit=1&cursor=41d51698-0e80-0000-68c4-d0a603b982a9'
        results = [
            {
                'collection': [soundcloud_mention_fixture[0]],
                'next_href': next_href
            }, {
                'collection': [soundcloud_mention_fixture[1]],
                'next_href': next_href
            }, {
                'collection': [soundcloud_mention_fixture[2]],
                'next_href': next_href
            }
        ]
        m1 = MagicMock()
        m1.obj = results[0]
        m2 = MagicMock()
        m2.obj = results[1]
        m3 = MagicMock()
        m3.obj = results[2]
        mocks = [m1, m2, m3]
        mock_soundcloud.return_value.get.side_effect = mocks

        soundcloud = SoundCloudAPI()
        soundcloud.create_mentions()
        mentions = Mention.objects.all()
        self.assertEqual(len(mentions), 2)
        mock_soundcloud.return_value.get.side_effect = mocks
        soundcloud.create_mentions()
        self.assertEqual(len(mentions), 2)
예제 #3
0
파일: run_bot.py 프로젝트: bontaq/dogebot
    def handle(self, *args, **options):
        soundcloud = SoundCloudAPI()
        processor = Processor()
        logger.info('beginning update')

        logger.info('beginning update soundcloud')
        soundcloud.update_soundcloud()
        logger.info('finished updating soundcloud')

        logger.info('beginning process messages')
        processor.process_messages()
        logger.info('finished process messages')

        logger.info('beginning process mentions')
        processor.process_mentions()
        logger.info('finished process mentions')

        logger.info('beginning process transactions')
        processor.process_transactions()
        logger.info('finished process transactions')

        logger.info('beginning process deposits')
        processor.process_deposits()
        logger.info('finished process deposits')

        logger.info('clearing stuck messages')
        processor.clear_stuck_messages()

        logger.info('completed update')
예제 #4
0
 def test_disable_send_message_to_self(self, mock_soundcloud):
     # Soundcloud doesn't allow sending messages to yourself, it's messing
     # with people trying to tip the bot
     mock_soundcloud.return_value.post.side_effect = Exception('should not be called')
     soundcloud = SoundCloudAPI()
     soundcloud.user_id = '77871924'
     res = soundcloud.send_message(to_user_id='77871924', message="hey there")
     self.assertIsNone(res)
예제 #5
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_unregistered_withdrawl(user_id):
    soundcloud = SoundCloudAPI()
    msg = "You tried to withdraw without registering, reply with 'register' to register."
    try:
        soundcloud.send_message(user_id, msg)
        logger.info('Notified %s that they are not registered, can not withdraw', user_id)
    except Exception as e:
        logger.exception(e)
예제 #6
0
 def test_new_conversation(self, mock_convos, mock_soundcloud):
     mock_convos.return_value = soundcloud_conversation_fixture
     soundcloud = SoundCloudAPI()
     soundcloud.create_conversations()
     conversations = Conversation.objects.all()
     self.assertEqual(len(conversations), 3)
     self.assertEqual(conversations[0].convo_id, '77871924:6924356')
     self.assertEqual(conversations[0].user_name, 'Bonbontaq')
     self.assertEqual(conversations[0].user_id, '6924356')
예제 #7
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_history(user):
    soundcloud = SoundCloudAPI()
    msg = build_history(user)
    msg = "Here is a history of your transactions: \n" + msg
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Notified %s of history', user.user_id)
    except Exception as e:
        logger.exception(e)
예제 #8
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_from_user_not_registered(from_user_id):
    soundcloud = SoundCloudAPI()
    msg = ("You tried to tip someone but have not registered.  Respond with "
           "'register' if you would like to register.")
    try:
        soundcloud.send_message(from_user_id, msg)
        logger.info('Notified %s that they are not registered', from_user_id)
    except Exception as e:
        logger.exception(e)
예제 #9
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_bad_balance_withdrawl(user, amt):
    soundcloud = SoundCloudAPI()
    msg = "You tried to withdraw {amt}, but your balance is only {balance}".format(
        amt=amt.quantize(Decimal("0.00")),
        balance=user.balance.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Notified %s of insufficient funds address', user.user_id)
    except Exception as e:
        logger.exception(e)
예제 #10
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_invalid_address(user, address):
    soundcloud = SoundCloudAPI()
    msg = ("The address you tried to send doge to was invalid.\n"
           "address recieved: {addr}").format(
               addr=address)
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Notified %s of invalid address', user.user_id)
    except Exception as e:
        logger.exception(e)
예제 #11
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_already_registered(user):
    soundcloud = SoundCloudAPI()
    msg = "You've already registered, your deposit address is:\n{address}\nand " \
          "your balance is: {balance}".format(
              address=user.deposit_address,
              balance=user.balance.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Reply: already registered: %s %s', user.user_name, user.user_id)
    except Exception as e:
        logger.exception(e)
예제 #12
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_from_user_tip_refunded(from_user, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    msg = ("You tried to tip {to_user}, but they did not accept in time.  "
           "{amt} doge has been refunded to you").format(
               to_user=to_user['username'],
               amt=amt.quantize(Decimal('0.00')))
    try:
        soundcloud.send_message(to_user['id'], msg)
    except Exception as e:
        logger.exception(e)
예제 #13
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_balance(user):
    soundcloud = SoundCloudAPI()
    msg = "Your balance is: {balance} doges".format(
        balance=user.balance.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Reply: balance: %s %s %s',
                    user.user_name,
                    user.user_id,
                    user.balance.quantize(Decimal("0.00")))
    except Exception as e:
        logger.exception(e)
예제 #14
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_successful_deposit(user, deposit):
    soundcloud = SoundCloudAPI()
    msg = ("Your deposit of {amt} doges was recieved. \n"
           "Your balance is now {balance} doges.").format(
               amt=deposit.amount,
               balance=user.balance.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(user.user_id, msg)

        logger.info('Notified %s of deposit', user.user_id)
    except Exception as e:
        logger.exception(e)
예제 #15
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_notify_of_refund(from_user, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    msg = ("The tip you tried to send to {to_user} of {amt} doges "
           "has been refunded to you").format(
               to_user=to_user['username'],
               amt=amt.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(from_user.user_id, msg)
        logger.info('Notified %s of refund to %s', from_user.user_id, to_user_id)
    except Exception as e:
        logger.exception(e)
예제 #16
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_notify_from_user_pending_tip(from_user_id, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    from_user = soundcloud.get_soundcloud_user(user_id=from_user_id)
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    msg = ("You sent {to_user} a tip of {amt}, they aren't currently registered but I'll "
           "let you know if they accept the tip.").format(
               to_user=to_user['username'],
               amt=amt.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(from_user['id'], msg)
    except Exception as e:
        logger.exception(e)
예제 #17
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_successful_withdrawl(user, amt, address):
    soundcloud = SoundCloudAPI()
    msg = ("Successfully withdrew {amt} doges.\n"
           "Sent to: {addr}\n"
           "New balance: {balance}").format(
               amt=amt.quantize(Decimal("0.00")),
               addr=address,
               balance=user.balance.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Notified %s of successful withdraw', user.user_id)
    except Exception as e:
        logger.exception(e)
예제 #18
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_help(user_id):
    soundcloud = SoundCloudAPI()
    msg = ("Dogebot let's you tip users dogecoins. \n"
           "commands: \n"
           "register - receive an address you can deposit doges to\n"
           "balance - your current balance\n"
           "withdraw [amount] [address] - send doges to an external address\n"
           "history - shows tips you have given & received, deposits & withdraws\n"
           "help - this command")
    try:
        soundcloud.send_message(user_id, msg)
        logger.info('Notified %s of commands', user_id)
    except Exception as e:
        logger.exception(e)
예제 #19
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_bad_balance(from_user_id, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    from_user = User.objects.get(user_id=from_user_id)
    msg = ("You tried to send a tip of {amt} doges to {user}, but your balance is {balance} doges").format(
        amt=amt.quantize(Decimal("0.00")),
        user=to_user['username'],
        balance=from_user.balance.quantize(Decimal("0.00"))
    )
    try:
        soundcloud.send_message(from_user_id, msg)
        logger.info('Notified %s that they do not have sufficient balance', from_user_id)
    except Exception as e:
        logger.exception(e)
예제 #20
0
    def test_get_conversations(self, mock_soundcloud):
        results = soundcloud_conversation_fixture
        m1 = MagicMock()
        m1.obj = results[0]
        m2 = MagicMock()
        m2.obj = results[1]
        m3 = MagicMock()
        m3.obj = results[2]
        mocks = [m1, m2, m3]
        mock_soundcloud.return_value.get.return_value = mocks

        soundcloud = SoundCloudAPI()
        res = [r for r in soundcloud.get_conversations()]
        self.assertEqual(len(res), 3)
예제 #21
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_welcome(user):
    soundcloud = SoundCloudAPI()
    msg = ("Welcome to dogebot, your deposit address is:\n{address}\n"
           "commands: \n"
           "balance - your current balance\n"
           "withdraw [amount] [address] - send doges to an external address\n"
           "history - shows tips you have given & received, deposits & withdraws\n"
           "help - this command").format(
        address=user.deposit_address
    )
    try:
        soundcloud.send_message(user.user_id, msg)
        logger.info('Reply: welcomed: %s %s %s', user.user_name, user.user_id, user.deposit_address)
    except Exception as e:
        logger.exception(e)
예제 #22
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_notify_of_tip(from_user_id, to_user_id):
    soundcloud = SoundCloudAPI()
    from_user = soundcloud.get_soundcloud_user(user_id=from_user_id)
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    msg = "{from_user} would like to send you a dogecoin tip, reply with 'accept' to " \
          "register and accept this tip.".format(
              from_user=from_user['username']
          )
    try:
        soundcloud.send_message(to_user['id'], msg)
        logger.info('Reply: asked user to register.  from_user: %s, to_user: %s',
                    from_user,
                    to_user)
    except Exception as e:
        logger.exception(e)
예제 #23
0
 def test_duplicate_message(self, mock_messages, mock_soundcloud):
     mock_messages.return_value = soundcloud_message_fixture
     soundcloud = SoundCloudAPI()
     convo = G(Conversation, user_id='1')
     soundcloud.create_messages(convo)
     messages = Message.objects.all()
     self.assertEqual(len(messages), 3)
     for m in messages:
         self.assertEqual(m.conversation, convo)
         self.assertEqual(m.user_id, '1')
     m1 = messages[0]
     m2 = messages[1]
     m3 = messages[2]
     self.assertEqual(m1.message, 'hey\n')
     self.assertEqual(m2.message, 'back atcha')
     self.assertEqual(m3.message, 'hi dogebot <3')
예제 #24
0
 def test_get_mentions(self, mock_soundcloud):
     results = [
         {
             'collection': [soundcloud_mention_fixture[0]],
             'next_href': 'https://api.soundcloud.com/e1/me/activities.json?limi2t=1&cursor=41d51698-0e80-0000-68c4-d0a603b982a9'
         }, {
             'collection': [],
             'next_href': ''
         }
     ]
     m1 = MagicMock()
     m1.obj = results[0]
     m2 = MagicMock()
     m2.obj = results[1]
     mocks = [m1, m2]
     mock_soundcloud.return_value.get.side_effect = mocks
     soundcloud = SoundCloudAPI()
     res = [r for r in soundcloud.get_new_mentions()]
     self.assertEqual(len(res), 1)
예제 #25
0
    def test_already_existing_mention(self, mock_soundcloud):
        next_href = 'https://api.soundcloud.com/e1/me/activities.json?' + \
                    'limit=1&cursor=41d51698-0e80-0000-68c4-d0a603b982a9'
        results = [{
            'collection': [soundcloud_mention_fixture[0]],
            'next_href': next_href
        }, {
            'collection': [soundcloud_mention_fixture[1]],
            'next_href': next_href
        }, {
            'collection': [soundcloud_mention_fixture[2]],
            'next_href': next_href
        }]
        m1 = MagicMock()
        m1.obj = results[0]
        m2 = MagicMock()
        m2.obj = results[1]
        m3 = MagicMock()
        m3.obj = results[2]
        mocks = [m1, m2, m3]
        mock_soundcloud.return_value.get.side_effect = mocks

        soundcloud = SoundCloudAPI()
        soundcloud.create_mentions()
        mentions = Mention.objects.all()
        self.assertEqual(len(mentions), 2)
        mock_soundcloud.return_value.get.side_effect = mocks
        soundcloud.create_mentions()
        self.assertEqual(len(mentions), 2)
예제 #26
0
    def test_create_mentions(self, mock_soundcloud):
        next_href = 'https://api.soundcloud.com/e1/me/activities.json?' + \
                    'limit=1&cursor=41d51698-0e80-0000-68c4-d0a603b982a9'
        results = [
            {
                'collection': [soundcloud_mention_fixture[0]],
                'next_href': next_href
            }, {
                'collection': [soundcloud_mention_fixture[1]],
                'next_href': next_href
            }, {
                'collection': [soundcloud_mention_fixture[2]],
                'next_href': next_href
            }
        ]
        m1 = MagicMock()
        m1.obj = results[0]
        m2 = MagicMock()
        m2.obj = results[1]
        m3 = MagicMock()
        m3.obj = results[2]
        mocks = [m1, m2, m3]
        mock_soundcloud.return_value.get.side_effect = mocks

        soundcloud = SoundCloudAPI()
        soundcloud.create_mentions()
        mentions = Mention.objects.all()
        self.assertEqual(len(mentions), 2)

        self.assertEqual(mentions[0].from_user_name, '666robobo777')
        self.assertEqual(mentions[0].from_user_id, '123577402')
        self.assertEqual(mentions[0].message, '@dogebot: tip 10')
        self.assertFalse(mentions[0].processed)

        self.assertEqual(mentions[1].from_user_name, '666robobo777')
        self.assertEqual(mentions[1].from_user_id, '123577402')
        self.assertEqual(mentions[1].message, '@dogebot: tip 20')
        self.assertFalse(mentions[1].processed)
예제 #27
0
    def test_create_mentions(self, mock_soundcloud):
        next_href = 'https://api.soundcloud.com/e1/me/activities.json?' + \
                    'limit=1&cursor=41d51698-0e80-0000-68c4-d0a603b982a9'
        results = [{
            'collection': [soundcloud_mention_fixture[0]],
            'next_href': next_href
        }, {
            'collection': [soundcloud_mention_fixture[1]],
            'next_href': next_href
        }, {
            'collection': [soundcloud_mention_fixture[2]],
            'next_href': next_href
        }]
        m1 = MagicMock()
        m1.obj = results[0]
        m2 = MagicMock()
        m2.obj = results[1]
        m3 = MagicMock()
        m3.obj = results[2]
        mocks = [m1, m2, m3]
        mock_soundcloud.return_value.get.side_effect = mocks

        soundcloud = SoundCloudAPI()
        soundcloud.create_mentions()
        mentions = Mention.objects.all()
        self.assertEqual(len(mentions), 2)

        self.assertEqual(mentions[0].from_user_name, '666robobo777')
        self.assertEqual(mentions[0].from_user_id, '123577402')
        self.assertEqual(mentions[0].message, '@dogebot: tip 10')
        self.assertFalse(mentions[0].processed)

        self.assertEqual(mentions[1].from_user_name, '666robobo777')
        self.assertEqual(mentions[1].from_user_id, '123577402')
        self.assertEqual(mentions[1].message, '@dogebot: tip 20')
        self.assertFalse(mentions[1].processed)
예제 #28
0
def send_tip_success(from_user_id, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    from_user = soundcloud.get_soundcloud_user(user_id=from_user_id)
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    quantized_amt = amt.quantize(Decimal("0.00"))

    tip_receiver_msg = "{username} has sent you a tip of {amt} doge".format(
        username=from_user['username'], amt=quantized_amt)
    tip_sender_msg = "You successfully tipped {amt} doge to {username}".format(
        username=to_user['username'], amt=quantized_amt)
    try:
        soundcloud.send_message(to_user['id'], tip_receiver_msg)
    except Exception as e:
        logger.exception(e)
    try:
        soundcloud.send_message(from_user['id'], tip_sender_msg)
    except Exception as e:
        logger.exception(e)
예제 #29
0
def send_notify_from_user_pending_tip(from_user_id, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    from_user = soundcloud.get_soundcloud_user(user_id=from_user_id)
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    msg = (
        "You sent {to_user} a tip of {amt}, they aren't currently registered but I'll "
        "let you know if they accept the tip.").format(
            to_user=to_user['username'], amt=amt.quantize(Decimal("0.00")))
    try:
        soundcloud.send_message(from_user['id'], msg)
    except Exception as e:
        logger.exception(e)
예제 #30
0
def send_notify_of_tip(from_user_id, to_user_id):
    soundcloud = SoundCloudAPI()
    from_user = soundcloud.get_soundcloud_user(user_id=from_user_id)
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    msg = "{from_user} would like to send you a dogecoin tip, reply with 'accept' to " \
          "register and accept this tip.".format(
              from_user=from_user['username']
          )
    try:
        soundcloud.send_message(to_user['id'], msg)
        logger.info(
            'Reply: asked user to register.  from_user: %s, to_user: %s',
            from_user, to_user)
    except Exception as e:
        logger.exception(e)
예제 #31
0
파일: tasks.py 프로젝트: bontaq/dogebot
def send_tip_success(from_user_id, to_user_id, amt):
    soundcloud = SoundCloudAPI()
    from_user = soundcloud.get_soundcloud_user(user_id=from_user_id)
    to_user = soundcloud.get_soundcloud_user(user_id=to_user_id)
    quantized_amt = amt.quantize(Decimal("0.00"))

    tip_receiver_msg = "{username} has sent you a tip of {amt} doge".format(
        username=from_user['username'],
        amt=quantized_amt
    )
    tip_sender_msg = "You successfully tipped {amt} doge to {username}".format(
        username=to_user['username'],
        amt=quantized_amt
    )
    try:
        soundcloud.send_message(to_user['id'], tip_receiver_msg)
    except Exception as e:
        logger.exception(e)
    try:
        soundcloud.send_message(from_user['id'], tip_sender_msg)
    except Exception as e:
        logger.exception(e)
예제 #32
0
 def handle(self, *args, **options):
     soundcloud = SoundCloudAPI()
     soundcloud.update_soundcloud()
     soundcloud.create_conversations()
예제 #33
0
 def test_get_user(self, mock_soundcloud):
     soundcloud = SoundCloudAPI()
     mock_soundcloud.return_value.get.return_value = MagicMock(
         obj=soundcloud_resolve_user_fixture)
     res = soundcloud.get_soundcloud_user(user_id='doge')
     self.assertEqual(res['username'], 'dogebot')
예제 #34
0
 def test_get_user(self, mock_soundcloud):
     soundcloud = SoundCloudAPI()
     mock_soundcloud.return_value.get.return_value = MagicMock(obj=soundcloud_resolve_user_fixture)
     res = soundcloud.get_soundcloud_user(user_id='doge')
     self.assertEqual(res['username'], 'dogebot')
예제 #35
0
 def test_conversation_from_system(self, mock_soundcloud):
     soundcloud = SoundCloudAPI()
     soundcloud.create_conversation(soundcloud_conversation_fixture[2])
     convo = Conversation.objects.get(user_name='system')
     self.assertEqual(convo.user_id, 'system')
예제 #36
0
class Processor():
    def __init__(self):
        self.wallet = WalletAPI()
        self.soundcloud = SoundCloudAPI()

    def register_user(self, message):
        """Try to create a User with a deposit address, returns a User and created if it was
        successful"""

        user, created = User.objects.get_or_create(
            user_name=message.user_name,
            user_id=message.user_id,
        )
        if created:
            user.deposit_address = self.wallet.get_new_address()
            user.save()
        return user, created

    def handle_created_user(self, user, created, text):
        """Welcomes user or lets them know they've already registed"""

        if created:
            tasks.send_welcome.delay(user)
            logger.info('user created, username: %s, id: %s, message: %s',
                        user.user_name, user.user_id, text)
        else:
            tasks.send_already_registered.delay(user)
            logger.info(
                'user tried to reregister, username: %s, id: %s, message: %s',
                user.user_name, user.user_id, text)

    def handle_withdrawl(self, amt, address, user):
        """Transfers funds to an outside address"""

        if amt == 'all' or user.balance >= amt:
            amt_to_send = user.balance if amt == 'all' else amt
            result = self.wallet.send_amount(address, amt_to_send)
            if result:
                user.balance -= amt_to_send
                user.save()
                wallet_transaction = WalletTransaction(user=user,
                                                       is_withdrawl=True,
                                                       amount=amt_to_send,
                                                       txid=result,
                                                       to_address=address)
                wallet_transaction.save()
                tasks.send_successful_withdrawl.delay(user, amt_to_send,
                                                      address)
                logger.info(wallet_transaction)
        else:
            raise BadBalance()

    def process_messages(self):
        """Everything to do with messages: registery, get_balance, withdrawl, and history"""

        for message in Message.objects.filter(processed=False):
            text = message.message
            if SCParser.is_register(text) or SCParser.is_accept(text):
                user, created = self.register_user(message)
                self.handle_created_user(user, created, text)
                message.processed = True
                message.save()
            elif SCParser.is_get_balance(text):
                user = User.objects.get(user_id=message.user_id)
                try:
                    tasks.send_balance.delay(user)
                    message.processed = True
                    message.save()
                except Exception as e:
                    logger.exception(e)
            elif SCParser.is_withdrawl(text):
                amt, address = SCParser.parse_withdrawl(text)
                try:
                    user = User.objects.get(user_id=message.user_id)
                    self.handle_withdrawl(amt, address, user)
                except InvalidAddress:
                    tasks.send_invalid_address.delay(user, address)
                except BadBalance:
                    tasks.send_bad_balance_withdrawl.delay(user, amt)
                except User.DoesNotExist:
                    tasks.send_unregistered_withdrawl.delay(message.user_id)
                message.processed = True
                message.save()
            elif SCParser.is_history(text):
                user = User.objects.get(user_id=message.user_id)
                tasks.send_history.delay(user)
                message.processed = True
                message.save()
            elif SCParser.is_help(text):
                tasks.send_help.delay(message.user_id)
                message.processed = True
                message.save()

    def is_user(self, user_id):
        return User.objects.filter(user_id=user_id).exists()

    def transfer_funds(self, from_user, to_user, amt):
        """Transfer funds between users in the network

        :param from_user: User
        :param to_user: User
        :param amt: Decimal
        """
        from_user.balance -= amt
        from_user.save()
        # because some oddballs like to tip themselves
        to_user = User.objects.get(id=to_user.id)
        to_user.balance += amt
        to_user.save()
        trans = Transaction(from_user=from_user,
                            to_user=to_user,
                            amount=amt,
                            pending=False,
                            accepted=True)
        trans.save()
        logger.info('Moved coin: %s', trans)
        return trans

    def handle_to_user_not_registered(self, from_user_id, to_user_id, amt):
        """Creates pending transaction and subtracts tip amount from from_user"""

        from_user = User.objects.get(user_id=from_user_id)
        if from_user.balance >= amt:
            trans = Transaction(
                from_user=User.objects.get(user_id=from_user_id),
                to_user_temp_id=to_user_id,
                amount=amt,
                pending=True,
                accepted=False,
            )
            trans.save()
            logger.info('Created pending transaction: %s', trans)
            from_user.balance -= amt
            from_user.save()
        else:
            raise BadBalance()

    def process_mentions(self):
        """Goes through unprocessed mentions and manages those which are tips"""

        for mention in Mention.objects.filter(processed=False):
            if SCParser.is_mention_tip(mention.message):
                from_user_id = mention.from_user_id
                to_user_id = mention.to_user_id
                amt_to_send = SCParser.parse_mention_tip(mention.message)
                try:
                    self.process_tip(from_user_id, to_user_id, amt_to_send)
                    tasks.send_tip_success.delay(from_user_id, to_user_id,
                                                 amt_to_send)
                except FromUserNotRegistered:
                    tasks.send_from_user_not_registered.delay(from_user_id)
                except ToUserNotRegistered:
                    try:
                        self.handle_to_user_not_registered(
                            from_user_id, to_user_id, amt_to_send)
                        tasks.send_notify_from_user_pending_tip.delay(
                            from_user_id, to_user_id, amt_to_send)
                        tasks.send_notify_of_tip.delay(from_user_id,
                                                       to_user_id)
                    except BadBalance:
                        tasks.send_bad_balance.delay(from_user_id, to_user_id,
                                                     amt_to_send)
                except BadBalance:
                    tasks.send_bad_balance.delay(from_user_id, to_user_id,
                                                 amt_to_send)
            mention.processed = True
            mention.save()

    def process_tip(self, from_user_id, to_user_id, amt):
        """Handles a mention-based tip, from_user to_user"""

        try:
            from_user = User.objects.get(user_id=from_user_id)
        except User.DoesNotExist:
            raise FromUserNotRegistered()

        try:
            to_user = User.objects.get(user_id=to_user_id)
        except User.DoesNotExist:
            raise ToUserNotRegistered()

        if from_user.balance < amt:
            raise BadBalance()

        self.transfer_funds(from_user, to_user, amt)

    def process_transactions(self):
        """Go through pending transactions and see if the recipient has accepted, then complete transaction.
        If the request is over 3 days old return funds and inform the tipper."""

        now = datetime.now(pytz.utc)
        for transaction in Transaction.objects.filter(pending=True):
            if (now - transaction.timestamp
                ).total_seconds() > settings.TIP_EXPIRY:
                transaction.from_user.balance += transaction.amount
                transaction.pending = False
                transaction.from_user.save()
                transaction.save()
                logger.info(
                    'Refunded pending tip, from_user: %s, to_user: %s, amt: %s',
                    transaction.from_user.user_id, transaction.to_user_temp_id,
                    transaction.amount.quantize(Decimal('0.00')))
                tasks.send_notify_of_refund.delay(transaction.from_user,
                                                  transaction.to_user_temp_id,
                                                  transaction.amount)
            else:
                try:
                    to_user = User.objects.get(
                        user_id=transaction.to_user_temp_id)
                    to_user.balance += transaction.amount
                    to_user.save()
                    transaction.to_user = to_user
                    transaction.pending = False
                    transaction.accepted = True
                    transaction.save()
                    logger.info(
                        'Completed pending tip, from_user: %s, to_user: %s, amt: %s',
                        transaction.from_user.user_id, to_user.user_id,
                        transaction.amount.quantize(Decimal('0.00')))
                    tasks.send_tip_success.delay(transaction.from_user.user_id,
                                                 to_user.user_id,
                                                 transaction.amount)
                except User.DoesNotExist:
                    pass

    def process_deposits(self):
        """Check for latest deposits and credits user account"""

        try:
            last_transaction = WalletTransaction.objects.latest('timestamp')
        except WalletTransaction.DoesNotExist:
            last_transaction = None

        new_deposits = self.wallet.get_new_deposits(last_transaction)
        for deposit in new_deposits:
            if WalletTransaction.objects.filter(txid=deposit.txid).exists():
                logger.warning('Tried to recreate a deposit, %s', deposit)
            else:
                try:
                    user = User.objects.get(deposit_address=deposit.to_address)
                    user.balance += deposit.amount
                    user.save()
                    deposit.user = user
                    deposit.pending = False
                    deposit.save()
                    tasks.send_successful_deposit.delay(user, deposit)
                except User.DoesNotExist:
                    logger.error('User could not be found for deposit to %s',
                                 deposit.to_address)

    def clear_stuck_messages(self):
        for m in StuckMessage.objects.all():
            self.soundcloud.send_message(to_user_id=m.user_id,
                                         message=m.message)
            # if the message fails again, another StuckMessage will be created, so always
            # delete the old one.
            m.delete()
예제 #37
0
 def test_conversation_from_system(self, mock_soundcloud):
     soundcloud = SoundCloudAPI()
     soundcloud.create_conversation(soundcloud_conversation_fixture[2])
     convo = Conversation.objects.get(user_name='system')
     self.assertEqual(convo.user_id, 'system')
예제 #38
0
 def __init__(self):
     self.wallet = WalletAPI()
     self.soundcloud = SoundCloudAPI()