Passed
Push — master ( 89e842...fde1fa )
by srz
07:01 queued 11s
created

wandbox.Wandbox.Call()   B

Complexity

Conditions 8

Size

Total Lines 26
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 23
nop 3
dl 0
loc 26
rs 7.3333
c 0
b 0
f 0
1
#!/usr/bin/env python
2
#
3
# wandbox.py
4
#
5
6
"""
7
Wandbox API for Python
8
"""
9
10
import requests
11
import json
12
13
from time import sleep
14
from requests.exceptions import HTTPError as RHTTPError
15
from requests.exceptions import ConnectionError as RConnectionError
16
from requests.exceptions import ConnectTimeout as RConnectTimeout
17
18
#
19
#
20
class Wandbox:
21
    """wandbox api class"""
22
23
    #api_url = 'http://melpon.org/wandbox/api'
24
    api_url = 'https://wandbox.org/api'
25
    timeout_ = (3.0, 60.0 * 5)
26
27
    def __init__(self):
28
        self.reset()
29
30
    def __enter__(self):
31
        return self
32
33
    def __exit__(self, exc_type, exc_value, traceback):
34
        self.reset()
35
        return False
36
37
    @staticmethod
38
    def GetCompilerList():
39
        """
40
        get compiler list
41
        """
42
        response = requests.get(Wandbox.api_url + '/list.json', timeout=3.0)
43
        response.raise_for_status()
44
        return response.json()
45
46
    def get_compiler_list(self):
47
        """
48
        get compiler list
49
        .. deprecated:: 0.3.4
50
        """
51
        return Wandbox.GetCompilerList()
52
53
    @staticmethod
54
    def GetPermlink(link):
55
        """
56
        get wandbox permanet link
57
        """
58
        response = requests.get(Wandbox.api_url + '/permlink/' + link, timeout=3.0)
59
        response.raise_for_status()
60
        return response.json()
61
62
    @property
63
    def timeout(self):
64
        return self.timeout_
65
66
    @timeout.setter
67
    def timeout(self, v):
68
        self.timeout_ = v
69
70
    def get_permlink(self, link):
71
        """
72
        get wandbox permanet link
73
        .. deprecated:: 0.3.4
74
        """
75
        return Wandbox.GetPermlink(link)
76
77
    def run(self):
78
        """
79
        excute on wandbox
80
        """
81
        headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
82
        payload = json.dumps(self.parameter)
83
        response = requests.post(self.api_url + '/compile.json', data=payload, headers=headers, timeout=self.timeout_)
84
        response.raise_for_status()
85
        try:
86
            return response.json()
87
        except json.decoder.JSONDecodeError as e:
88
            response.status_code = 500
89
            raise RHTTPError(e, response=response)
90
91
    def code(self, code):
92
        """
93
        set main source code
94
        """
95
        self.parameter.update({'code': code})
96
97
    def add_file(self, filename, code):
98
        """
99
        append file
100
        """
101
        if 'codes' in self.parameter:
102
            self.parameter['codes'].append({'file': filename, 'code': code})
103
        else:
104
            self.parameter.update({'codes': [{'file': filename, 'code': code}]})
105
106
    def compiler(self, name):
107
        """
108
        set compiler name
109
        """
110
        self.parameter.update({'compiler': name})
111
112
    def options(self, options_str):
113
        """
114
        set wandbox options
115
        """
116
        self.parameter.update({'options': options_str})
117
118
    def stdin(self, input_str):
119
        """
120
        set stdin buffer
121
        """
122
        self.parameter.update({'stdin': input_str})
123
124
    def compiler_options(self, options_str):
125
        """
126
        set wandbox defined compiler options
127
        """
128
        self.parameter.update({'compiler-option-raw': options_str})
129
130
    def add_compiler_options(self, options_str):
131
        """
132
        set compiler options
133
        """
134
        if 'compiler-option-raw' not in self.parameter:
135
            self.compiler_options(options_str)
136
        else:
137
            option = self.parameter['compiler-option-raw']
138
            option += '\n'
139
            option += options_str
140
            self.parameter.update({'compiler-option-raw': option})
141
142
    def runtime_options(self, options_str):
143
        """
144
        set runtime options
145
        """
146
        self.parameter.update({'runtime-option-raw': options_str})
147
148
    def permanent_link(self, enable):
149
        """
150
        wandbox permanet link to enable
151
        """
152
        self.parameter.update({'save': enable})
153
154
    def dump(self):
155
        """
156
        dump parameters
157
        """
158
        print(self.parameter)
159
160
    def reset(self):
161
        """
162
        reset parametes
163
        """
164
        self.parameter = {'code': ''}
165
166
    @staticmethod
167
    def Call(action, retries, retry_wait):
168
        try:
169
            return action()
170
        except (RHTTPError, RConnectionError, RConnectTimeout) as e:
171
172
            def is_retry(e):
173
                if e is None:
174
                    return False
175
                if e.response is None:
176
                    return False
177
                return e.response.status_code in [500, 502, 503, 504]
178
179
            retries -= 1
180
            if is_retry(e) and retries > 0:
181
                try:
182
                    print(e.message)
183
                except:
184
                    pass
185
                print('wait {0}sec...'.format(retry_wait))
186
                sleep(retry_wait)
187
                return Wandbox.Call(action, retries, retry_wait)
188
            else:
189
                raise
190
        except:
191
            raise
192
193
194
if __name__ == '__main__':
195
    with Wandbox() as w:
196
        w.compiler('gcc-head')
197
        w.options('warning,gnu++1y')
198
        w.compiler_options('-Dx=hogefuga\n-O3')
199
        w.code('#include <iostream>\nint main() { int x = 0; std::cout << "hoge" << std::endl; }')
200
        print(w.run())
201