diff --git a/modules/bitcoin.py b/modules/bitcoin.py new file mode 100644 index 0000000..51cd5da --- /dev/null +++ b/modules/bitcoin.py @@ -0,0 +1,57 @@ +#!/usr/bin/python3 +""" +bitcoin.py - bitcoin currency conversion +author: mutantmonkey +""" + +import decimal +import web + + +def bitcoin(phenny, input): + amount = input.group(2) + currency = input.group(3) + + if not amount or not currency: + phenny.say("You need to need to specify an amount and a currency, " + "like .bitcoin 1 EUR") + return + + if currency == 'BTC': + from_btc = True + currency = input.group(4) + else: + from_btc = False + + if not currency: + currency = 'USD' + currency = currency.strip()[:3] + + try: + amount = decimal.Decimal(amount) + except decimal.InvalidOperation: + phenny.say("Please specify a valid decimal amount to convert.") + return + + try: + data = web.get('http://data.mtgox.com/api/2/BTC{}/money/ticker'.format( + web.quote(currency))) + except web.HTTPError: + phenny.say("Sorry, I don't know how to convert those right now.") + return + + data = web.json(data) + rate = decimal.Decimal(data['data']['last_local']['value']) + + if from_btc: + amount2 = amount * rate + amount2 = round(amount2, 2) + currency2 = data['data']['last_local']['currency'].strip()[:3] + else: + amount2 = amount / rate + amount2 = round(amount2, 8) + currency2 = 'BTC' + + phenny.say("{amount} {currency}".format(amount=amount2, + currency=currency2)) +bitcoin.rule = (['bitcoin'], r'(\d+)\s(\w+)(\s\w+)?') diff --git a/modules/test/test_bitcoin.py b/modules/test/test_bitcoin.py new file mode 100644 index 0000000..d4f7d2b --- /dev/null +++ b/modules/test/test_bitcoin.py @@ -0,0 +1,85 @@ +""" +test_bitcoin.py - tests for the bitcoin +author: mutantmonkey +""" + +import unittest +from mock import MagicMock, Mock +from modules.bitcoin import bitcoin + + +class TestCalc(unittest.TestCase): + def makegroup(*args): + args2 = [] + list(args) + def group(x): + if x > 0 and x <= len(args2): + return args2[x - 1] + else: + return None + return group + + def setUp(self): + self.phenny = MagicMock() + + def test_negative(self): + input = Mock(group=self.makegroup('1', 'USD')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertRegex(out, r'[\d\.]+ BTC') + + def test_usd(self): + input = Mock(group=self.makegroup('1', 'USD')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertRegex(out, r'[\d\.]+ BTC') + + def test_eur(self): + input = Mock(group=self.makegroup('1', 'EUR')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertRegex(out, r'[\d\.]+ BTC') + + def test_xzz(self): + input = Mock(group=self.makegroup('1', 'XZZ')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertNotRegex(out, r'[\d\.]+ BTC') + + def test_btc(self): + input = Mock(group=self.makegroup('1', 'BTC')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertRegex(out, r'\d+\.\d{2} USD') + + def test_btcusd(self): + input = Mock(group=self.makegroup('1', 'BTC', 'USD')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertRegex(out, r'\d+\.\d{2} USD') + + def test_eurbtc(self): + input = Mock(group=self.makegroup('1', 'BTC', 'EUR')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertRegex(out, r'\d+\.\d{2} EUR') + + def test_xzzbtc(self): + input = Mock(group=self.makegroup('1', 'BTC', 'XZZ')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertNotRegex(out, r'[\d\.]+ BTC') + + def test_invalid(self): + input = Mock(group=self.makegroup('.-1', 'USD')) + bitcoin(self.phenny, input) + + out = self.phenny.say.call_args[0][0] + self.assertNotRegex(out, r'[\d\.]+ BTC') diff --git a/modules/test/test_weather.py b/modules/test/test_weather.py index 89c5be8..f8e2e56 100644 --- a/modules/test/test_weather.py +++ b/modules/test/test_weather.py @@ -69,4 +69,3 @@ class TestWeather(unittest.TestCase): self.phenny.say.called_once_with('#phenny', "No NOAA data available for that location.") -