summaryrefslogtreecommitdiff
path: root/cfetch/__init__.py
blob: 9c5df6a151508122548513460b5afcd3d2f7e981 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
##
##  coinfetch - plugin-based cryptocurrency price converter
##  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 importlib.machinery import SourceFileLoader
from os import listdir
from os.path import basename, dirname, exists, expanduser, isdir, join, realpath
from requests import get

__version__ = '5.0.0'

## A cryptocurrency exchange rate ticker.
class Ticker():
    ## Constructor for this class.
    #  @param path The URL prefix for this ticker.
    #  @param kind Which type of exchange rate to fetch.
    def __init__(self, path, kind='avg'):
        self.path = path
        self.kind = kind

    ## Defines how a currency pair is defined in the request URL.
    #  @param a The first currency.
    #  @param b The second currency.
    #  @return A pair string to be used in the request URL.
    def get_pair(self, a, b):
        return '{}_{}'.format(a, b)

    ## Extracts the exchange rate data from the server response.
    #  @param response Original response from the ticker server.
    #  @param The coin pair as a list/tuple.
    #  @return The data for the selected pair.
    def get_pair_data(self, response, pair):
        return response.json()[self.get_pair(pair[0], pair[1])]

    ## Calculates the exchange rate between two currencies.
    #  @param a The first currency.
    #  @param b The second currency.
    #  @param amt The number quantity of 'a' currency.
    def get_rate(self, a, b, amt=1):
        r = get(self.path + self.get_pair(a, b))

        try:
            res = self.get_pair_data(r, (a, b))
            return float(res[self.kind]) * amt
        except (KeyError, TypeError):
            try:
                r = get(self.path + self.get_pair(b, a)) # reverse order

                res = self.get_pair_data(r, (b, a))
                return (float(res[self.kind]) ** -1) * amt
            except (KeyError, TypeError) as e:
                raise ValueError(str(e)) # currency pair not found

_INDEX = {
    'description': 0,
    'value': 1
}

_PATH = [
    dirname(realpath(__file__)),
    '/usr/share/coinfetch',
    '/usr/local/share/coinfetch',
    join(expanduser('~'), '.coinfetch')
]

_tickers = {}

## Adds a directory to the configuration path.
#  @param path The directory to be added.
def add_to_path(path):
    _PATH.append(path)

## Gets the registered tickers and their descriptions.
#  @return A list of tuples containing the ticker name and description.
def get_registered_tickers():
    lst = []

    for key in _tickers:
        lst.append((key, _tickers[key][_INDEX['description']]))

    return lst

## Gets a particular ticker object.
#  @param key Name of the desired ticker.
#  @return The Ticker object specified by 'key'.
def get_ticker(key):
    return _tickers[key][_INDEX['value']]

## Registers a new ticker API.
#  @param name Name of this ticker.
#  @param description A brief description of this ticker.
#  @param obj An instance of the ticker's implementation class.
def register_ticker(name, description, obj):
    _tickers[name] = (description, obj)

## Loads a plugin or directory of plugins.
#  @param path Path to the plugin file or a directory containing plugins.
def load(path):
    if isdir(path):
        for f in listdir(path):
            if f.endswith('.py'):
                load(join(path, f))
    else:
        SourceFileLoader('plugin', path).load_module()

## Loads all default plugins.
def load_default_plugins():
    for d in _PATH:
        plugindir = join(d, 'plugins')
        if exists(plugindir):
            load(plugindir)

## Clears the list of loaded plugins.
def unload_plugins():
    global _tickers
    _tickers = {}