summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid McMackins II <contact@mcmackins.org>2015-08-27 21:14:44 -0500
committerDavid McMackins II <contact@mcmackins.org>2015-08-27 21:14:44 -0500
commit6d30861c1eac59572fadfb9deec5c9afcf47e283 (patch)
tree97fbe05365b7abe46f10d898f200a820dfc4c935
parent4105693691124b9b08a15b3db4551972f212fc9f (diff)
Change to plugin-based system
-rw-r--r--README28
-rwxr-xr-xbterfetch25
-rwxr-xr-xcccfetch25
-rw-r--r--cfetch/__init__.py (renamed from coinfetch.py)6
-rw-r--r--cfetch/plugins/btce.py (renamed from plugins/btc-e.py)2
-rw-r--r--cfetch/plugins/bter.py (renamed from plugins/bter.py)2
-rw-r--r--cfetch/plugins/ccc.py (renamed from plugins/ccc.py)2
-rwxr-xr-xcoinfetch53
-rw-r--r--coinfetchapi.py134
-rw-r--r--setup.py15
10 files changed, 86 insertions, 206 deletions
diff --git a/README b/README
index 5037312..b4bc124 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-coinfetch
+Coinfetch
=========
See [INSTALL](INSTALL) for installation instructions.
@@ -36,15 +36,29 @@ Example: `$ coinfetch -a bter usd doge`
The above example will be the same as calling `coinfetch usd doge` in version
2.x, which used the BTer API. The default API is BTC-E.
+Installing Plugins
+------------------
+
+Plugins are read from a number of directories. Currently, these are:
+
+- `cfetch/plugins` located in this source repository and installed to the
+system after installation.
+- `/usr/share/coinfetch/plugins` on Unix-like operating systems.
+- The `.coinfetch/plugins` directory in the user's home directory.
+
+Any file ending in `.py` will be loaded using Python standard `import`
+logic. No functions will be executed by `coinfetch` directly. You must execute
+them at the global level if needed. See the default plugins in `cfetch/plugins`
+for examples of simple working plugins.
+
Note
----
-Version 5.x is currently in development. This will change the program from a
-static API/CLI to a plugin-based system with an API for external applications
-as well as the familiar CLI. The advantage of this new design is to allow
-hackers to add new APIs to Coinfetch without having to submit upstream
-requests. Officially-supported ticker APIs will stay in this repository to keep
-things easy for existing Coinfetch users.
+Version 5.x changes the program from a static API/CLI to a plugin-based system
+with an API for external applications as well as the familiar CLI. The
+advantage of this new design is to allow hackers to add new APIs to Coinfetch
+without having to submit upstream requests. Officially-supported ticker APIs
+will stay in this repository to keep things easy for existing Coinfetch users.
BTer's ticker (as of this update) does not seem to be updating often enough to
have accurate data. Version 4.1.x adds the CryptoCoin Charts (ccc) API which
diff --git a/bterfetch b/bterfetch
deleted file mode 100755
index b272391..0000000
--- a/bterfetch
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env python3
-##
-## coinfetch - Cryptocurrency price fetcher
-## Copyright (C) 2015 Delwink, LLC
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Affero General Public License as published by
-## the Free Software Foundation, version 3 only.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU Affero General Public License for more details.
-##
-## You should have received a copy of the GNU Affero General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-from sys import argv
-from coinfetchapi import *
-
-try:
- coinfetch(['--api=bter'] + argv[1:])
-except UsageException as e:
- print_usage(e)
diff --git a/cccfetch b/cccfetch
deleted file mode 100755
index d0bf3ce..0000000
--- a/cccfetch
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env python3
-##
-## coinfetch - Cryptocurrency price fetcher
-## Copyright (C) 2015 Delwink, LLC
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Affero General Public License as published by
-## the Free Software Foundation, version 3 only.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU Affero General Public License for more details.
-##
-## You should have received a copy of the GNU Affero General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-from sys import argv
-from coinfetchapi import *
-
-try:
- coinfetch(['--api=ccc'] + argv[1:])
-except UsageException as e:
- print_usage(e)
diff --git a/coinfetch.py b/cfetch/__init__.py
index 1570c28..33c33d2 100644
--- a/coinfetch.py
+++ b/cfetch/__init__.py
@@ -15,8 +15,9 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
+from importlib.machinery import SourceFileLoader
from os import listdir
-from os.path import dirname, exists, expanduser, isdir, join, realpath
+from os.path import basename, dirname, exists, expanduser, isdir, join, realpath
from requests import get
__version__ = '5.0.0'
@@ -112,8 +113,7 @@ def load(path):
if f.endswith('.py'):
load(join(path, f))
else:
- with open(path) as plugin:
- exec(plugin.read(), globals(), locals())
+ SourceFileLoader('plugin', path).load_module()
## Loads all default plugins.
def load_default_plugins():
diff --git a/plugins/btc-e.py b/cfetch/plugins/btce.py
index fc9b141..e3d6be0 100644
--- a/plugins/btc-e.py
+++ b/cfetch/plugins/btce.py
@@ -15,7 +15,7 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
-from coinfetch import register_ticker, Ticker
+from cfetch import register_ticker, Ticker
register_ticker('btce', 'The BTC-E ticker',
Ticker('https://btc-e.com/api/3/ticker/'))
diff --git a/plugins/bter.py b/cfetch/plugins/bter.py
index 7a62368..8bfbe8a 100644
--- a/plugins/bter.py
+++ b/cfetch/plugins/bter.py
@@ -15,7 +15,7 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
-from coinfetch import register_ticker, Ticker
+from cfetch import register_ticker, Ticker
class BterTicker(Ticker):
def get_pair_data(self, response, pair=None):
diff --git a/plugins/ccc.py b/cfetch/plugins/ccc.py
index 6da59e4..3f9ffde 100644
--- a/plugins/ccc.py
+++ b/cfetch/plugins/ccc.py
@@ -15,7 +15,7 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
-from coinfetch import register_ticker, Ticker
+from cfetch import register_ticker, Ticker
class CccTicker(Ticker):
def __init__(self, path, kind='price'):
diff --git a/coinfetch b/coinfetch
index c38f7d0..ec9b7fa 100755
--- a/coinfetch
+++ b/coinfetch
@@ -16,10 +16,53 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
-from sys import argv
-from coinfetchapi import *
+from argparse import Action, ArgumentParser
+from cfetch import __version__, get_ticker, get_registered_tickers
+from cfetch import load_default_plugins
+
+__title__ = 'coinfetch'
+__author__ = 'David McMackins II'
+__version_info__ = '''{} {}
+Copyright (C) 2015 Delwink, LLC
+License AGPLv3: GNU AGPL version 3 only <http://gnu.org/licenses/agpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Written by {}'''.format(__title__, __version__, __author__)
+
+class VersionAction(Action):
+ def __call__(self, parser, values, namespace, option_string):
+ print(__version_info__)
+ exit(0)
+
+cli = ArgumentParser(__title__)
+
+cli.add_argument('-a', '--api', default='btce', help='uses an API by name')
+cli.add_argument('-k', '--kind', help='specifies which kind of rate to get')
+cli.add_argument('-v', '--version', action=VersionAction,
+ help='show version information and exit', nargs=0)
+
+cli.add_argument('amount', default=1, help='amount of the original currency',
+ nargs='?', type=int)
+cli.add_argument('src', help='currency from which to convert')
+cli.add_argument('dest', help='currency to which to convert')
+
+args = cli.parse_args()
+
+load_default_plugins()
try:
- coinfetch(argv[1:])
-except UsageException as e:
- print_usage(e)
+ print('%.8f' %get_ticker(args.api).get_rate(args.src, args.dest, args.amount))
+except KeyError:
+ print('The API {} is not available. Currently installed APIs:'.format(args.api))
+
+ tickers = get_registered_tickers()
+ tickers.sort()
+ for api, desc in tickers:
+ print(api + '\t- ' + desc)
+
+ exit(10)
+except ValueError:
+ pair = '/'.join([args.src, args.dest])
+ print('The pair {} was not found using the {} API.'.format(pair, args.api))
+ exit (11)
diff --git a/coinfetchapi.py b/coinfetchapi.py
deleted file mode 100644
index 0ea809f..0000000
--- a/coinfetchapi.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#! /usr/bin/env python3
-##
-## coinfetchapi - API module for coinfetch
-## Copyright (C) 2015 Delwink, LLC
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Affero General Public License as published by
-## the Free Software Foundation, version 3 only.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU Affero General Public License for more details.
-##
-## You should have received a copy of the GNU Affero General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-from requests import get
-from getopt import getopt
-from sys import stderr
-
-__version__ = '4.1.1'
-
-USAGE_INFO = '''
-USAGE: coinfetch [OPTIONS] [AMOUNT] FROM TO
-
-coinfetch will print the solution for x in the following equation:
-
- AMOUNT * FROM = x * TO
-
-OPTIONS:
- -h, --help Prints this help message.
- -v, --version Outputs version information and exits.
- -a, --api=Y Uses the API specified by Y.
- -k, --kind=Z Gets the Z kind of exchange rate.
-
-Supported APIs:
- btce BTC-E, the default API.
- bter BTer, the legacy API.
- ccc CryptoCoin Charts.
-
-Kinds:
- avg Average rate, the default.
- high The high rate.
- low The low rate.
- last The last exchange amount.
-
-Examples:
- coinfetch -k high btc usd # gets the high rate for Bitcoin to USD
- coinfetch -a bter usd doge # gets the average Dogecoin to USD conversion
-'''
-
-class UsageException(Exception):
- pass
-
-def print_usage(e):
- print(USAGE_INFO)
- exit(int(str(e)))
-
-def _keypair(api, r, pair):
- if api in ('btce'):
- return r.json()[pair]
- elif api in ('bter', 'ccc'):
- return r.json()
-
- raise ValueError('API %s not supported.' %api)
-
-def get_rate(coin_a, coin_b, amt, api, kind):
- if api == 'btce':
- url = 'https://btc-e.com/api/3/ticker/'
- elif api == 'bter':
- url = 'http://data.bter.com/api/1/ticker/'
- elif api == 'ccc':
- url = 'http://api.cryptocoincharts.info/tradingPair/'
- if kind == 'avg':
- kind = 'price'
- else:
- raise ValueError('kind %s not supported with API %s' %(kind, api))
- else:
- raise ValueError('API %s not supported.' %api)
-
- pair = '%s_%s' %(coin_a, coin_b)
-
- r = get(url + pair)
-
- try:
- res = _keypair(api, r, pair)
- return float(res[kind]) * amt
- except (KeyError, TypeError):
- try:
- pair = '%s_%s' %(coin_b, coin_a)
- r = get(url + pair)
-
- res = _keypair(api, r, pair)
- return (float(res[kind]) ** -1) * amt
- except TypeError as e:
- raise ValueError('currency pair not found: %s' %str(e))
-
-def coinfetch(args):
- api = 'btce'
- kind = 'avg'
- opts, args = getopt(args, "hva:k:", ['help', 'version', 'api=', 'kind='])
-
- for key, value in opts:
- if key in ('-h', '--help'):
- raise UsageException(0)
- elif key in ('-v', '--version'):
- print('''coinfetch 4.1.1
-Copyright (C) 2015 Delwink, LLC
-License AGPLv3: GNU AGPL version 3 only <http://gnu.org/licenses/agpl.html>.
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law.
-
-Written by David McMackins II''')
- exit(0)
- elif key in ('-a', '--api'):
- api = value
- elif key in ('-k', '--kind'):
- kind = value
-
- bump = 1 if len(args) == 3 else 0
- amt = float(args[0]) if len(args) == 3 else 1.0
-
- try:
- print('%.8f' %get_rate(args[bump], args[1+bump], amt, api, kind))
- except IndexError:
- raise UsageException(1)
- except KeyError as e:
- print('coinfetch: currency pair not found: %s' %str(e), file=stderr)
- exit(2)
- except ValueError as e:
- print('coinfetch: %s' %str(e), file=stderr)
- exit(3)
diff --git a/setup.py b/setup.py
index ef6ca41..ba7382d 100644
--- a/setup.py
+++ b/setup.py
@@ -1,22 +1,29 @@
import re
+from os.path import dirname, realpath
from setuptools import setup
version = ''
-with open('coinfetchapi.py', 'r') as f:
+with open('cfetch/__init__.py', 'r') as f:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
f.read(), re.MULTILINE).group(1)
setup(
name = 'coinfetch',
version = version,
- scripts = ['coinfetch', 'bterfetch', 'cccfetch'],
- py_modules = ['coinfetchapi'],
+ scripts = ['coinfetch'],
+ packages = ['cfetch'],
+
+ package_dir = {
+ 'cfetch': 'cfetch'
+ },
install_requires = ['requests'],
package_data = {
- '': ['README']
+ '': ['README'],
+ 'cfetch': ['plugins/*.py']
},
+ include_package_data=True,
author = 'Delwink, LLC',
author_email = 'support@delwink.com',