Passed
Push — master ( 157197...45eeb8 )
by Dave
01:00
created

backend.fcmservice.BaseService.__init__()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nop 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
import os
2
import datetime
3
import json
4
from helpers.telegramhelper import sendalert, sendphoto
5
from messaging.schema import MinerSchema, PoolSchema, AvailablePoolSchema, MinerCurrentPoolSchema
6
from messaging.messages import Message, MessageSchema
7
from domain.mining import Miner, Pool, MinerCurrentPool, AvailablePool
8
from domain.rep import PoolRepository
9
import domain.minerpool
10
from backend.fcmcache import CacheKeys
11
import backend.fcmutils as utils
12
13
class ServiceName:
14
    '''names of infrastructure services'''
15
    messagebus = 'rabbit'
16
    cache = 'redis'
17
    database = 'mysql'
18
    email = 'gmail'
19
    telegram = 'telegram'
20
21
class InfrastructureService:
22
    '''configuration for a dependency'''
23
    def __init__(self, name, connection, host, port, user, password):
24
        self.name = name
25
        self.connection = connection
26
        self.host = host
27
        self.port = port
28
        self.user = user
29
        self.password = password
30
31
class BaseService():
32
    '''Every service will share reference to configuration and cache'''
33
    def __init__(self, config, cache):
34
        self.homedirectory = os.path.dirname(__file__)
35
        self.initmessaging()
36
        self.configuration = config
37
        self.cache = cache
38
39
    def initmessaging(self):
40
        '''start up messaging'''
41
        self._schemamsg = MessageSchema()
42
43
    def getconfigfilename(self, configfilename):
44
        '''get the contents of a config file'''
45
        return os.path.join(self.homedirectory, configfilename)
46
47
    def serialize(self, entity):
48
        '''serialize any entity
49
        only need schema, message class not needed
50
        '''
51
        if isinstance(entity, Miner):
52
            return utils.serialize(entity, MinerSchema())
53
54
        if isinstance(entity, Pool):
55
            return utils.serialize(entity, PoolSchema())
56
        return None
57
58
    def createmessageenvelope(self):
59
        '''create message envelope'''
60
        return Message(timestamp=datetime.datetime.utcnow(), sender=self.component)
61
62
    def serializemessageenvelope(self, msg):
63
        '''serialize message envelope'''
64
        return self._schemamsg.dumps(msg).data
65
66
    def deserializemessageenvelope(self, body):
67
        '''serialize message envelope'''
68
        return self._schemamsg.load(json.loads(utils.safestring(body))).data
69
70
71
class Configuration(object):
72
    def __init__(self, config):
73
        self.__config = config
74
75
    def get(self, key):
76
        if not key in self.__config:
77
            return None
78
        return self.__config[key]
79
80
    def is_enabled(self, key):
81
        lookupkey = '{0}.enabled'.format(key)
82
        if not lookupkey in self.__config:
83
            return False
84
        value = self.__config[lookupkey]
85
        if isinstance(value, str):
86
            return value == 'true' or value == 'True'
87
        return value
88
89
class PoolService(BaseService):
90
    #def __init__(self, configuration, cache):
91
    #    super(PoolService, self).__init__()
92
93
    def get_all_pools(self):
94
        '''configured pools'''
95
        pools = PoolRepository().readpools(self.getconfigfilename('config/pools.conf'))
96
        return pools
97
98
    def findpool(self, minerpool):
99
        '''find a pool in list'''
100
        if minerpool is None:
101
            return None
102
        for pool in self.get_all_pools():
103
            if minerpool.currentpool == pool.url and minerpool.currentworker.startswith(pool.user):
104
                return pool
105
        return None
106
107
    def knownpools(self):
108
        dknownpools = self.cache.gethashset(CacheKeys.knownpools)
109
        if dknownpools:
110
            return utils.deserializelist_withschema(AvailablePoolSchema(), list(dknownpools.values()))
111
        return None
112
113
    def getpool(self, miner: Miner):
114
        '''get pool from cache'''
115
        valu = self.cache.trygetvaluefromcache(miner.name + '.pool')
116
        if valu is None:
117
            return None
118
        entity = MinerCurrentPool(miner, **utils.deserialize(MinerCurrentPoolSchema(), valu))
119
        return entity
120
121
    def add_pool(self, minerpool: domain.minerpool.MinerPool):
122
        '''see if pool is known or not, then add it'''
123
        knownpool = self.cache.getfromhashset(CacheKeys.knownpools, minerpool.pool.key)
124
        if not knownpool:
125
            val = utils.jsonserialize(AvailablePoolSchema(), minerpool.pool)
126
            self.cache.putinhashset(CacheKeys.knownpools, minerpool.pool.key, val)
127
128
    def putpool(self, pool: Pool):
129
        '''put pool in cache'''
130
        if pool and pool.name:
131
            valu = self.serialize(pool)
132
            self.cache.tryputcache('pool.{0}'.format(pool.name), valu)
133
134
    def update_pool(self, key, pool: AvailablePool):
135
        self.cache.hdel(CacheKeys.knownpools, key)
136
        knownpool = self.__cache.getfromhashset(CacheKeys.knownpools, pool.key)
137
        if not knownpool:
138
            val = utils.jsonserialize(AvailablePoolSchema(), pool)
139
            self.cache.putinhashset(CacheKeys.knownpools, pool.key, val)
140
141
    def save_pool(self, pool: Pool):
142
        sch = PoolSchema()
143
        pools = PoolRepository()
144
        pools.add(pool, self.getconfigfilename('config/pools.conf'), sch)
145
146
        #update the known pools
147
        for known in self.knownpools():
148
            if pool.is_same_as(known):
149
                oldkey = known.key
150
                known.named_pool = pool
151
                #this changes the pool key!
152
                known.user = pool.user
153
                #update the known pool (with new key)
154
                self.update_pool(oldkey, known)
155
156
class Telegram(object):
157
    def __init__(self, config, service):
158
        self.configuration = config
159
        self.service = service
160
161
    def sendmessage(self, message):
162
        if self.configuration.is_enabled('telegram'):
163
            sendalert(message, self.service)
164
165
    def sendphoto(self, file_name):
166
        if os.path.isfile(file_name) and os.path.getsize(file_name) > 0:
167
            if self.configuration.is_enabled('telegram'):
168
                sendphoto(file_name, self.service)
169