helpers.minerapi.MinerApi.command()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 19
nop 3
dl 0
loc 26
rs 8.5166
c 0
b 0
f 0
1
'''calls miner api'''
2
#based on https://github.com/tsileo/pycgminer
3
import socket
4
import json
5
6
class MinerApi(object):
7
    """cgminer api client"""
8
    def __init__(self, host='localhost', port=4028, timeout=2, retry_count=3):
9
        self.host = host
10
        self.port = port
11
        self.timeout = timeout
12
        self.retry_count = retry_count
13
        self.encoding = 'utf-8'
14
15
    def command(self, command, arg=None):
16
        socket.setdefaulttimeout(self.timeout)
17
        retries_remaining = self.retry_count
18
        while retries_remaining > 0:
19
            try:
20
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
21
                sock.connect((self.host, self.port))
22
                payload = {"command": command}
23
                if arg is not None:
24
                    payload['parameter'] = arg
25
                sock.send(bytes(json.dumps(payload), self.encoding))
26
                #for some reason on linux, cannot shutdown write yet
27
                #s.shutdown(socket.SHUT_WR)
28
                received = self._receive(sock)
29
                sock.shutdown(socket.SHUT_RDWR)
30
            except Exception as ex:
31
                retries_remaining -= 1
32
                if retries_remaining <= 0:
33
                    return dict({'STATUS': [{'STATUS': 'error', 'description': "{0}:{1}".format(self.host, ex)}]})
34
            else:
35
                # remove null byte in first character and add missing comma in stats command
36
                # fix lcd command
37
                # fix alternate miner software that puts \n in Miner Type
38
                return json.loads(received[:-1].replace('}{', '},{').replace('[,', '[').replace('\n', ''))
39
            finally:
40
                sock.close()
41
42
    def _receive(self, sock, max_bytes=4096):
43
        fullresponse = ''
44
        while True:
45
            more = sock.recv(max_bytes)
46
            if not more:
47
                break
48
            fullresponse += more.decode(self.encoding)
49
        return fullresponse
50
51
    def __getattr__(self, attr):
52
        '''a pattern that converts an attribute into a miner command.
53
        Examples: stats, pools
54
        '''
55
        def out(arg=None):
56
            return self.command(attr, arg)
57
        return out
58