wandbox.Wandbox.GetPermlink()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nop 1
dl 0
loc 8
rs 10
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
            def is_limit(e):
180
                if e is None:
181
                    return False
182
                if e.response is None:
183
                    return False
184
                return e.response.status_code in [400]
185
186
            retries -= 1
187
            if is_retry(e) and retries > 0:
188
                try:
189
                    print(e.message)
190
                except Exception:
191
                    pass
192
                print('wait {0}sec...'.format(retry_wait))
193
                sleep(retry_wait)
194
                return Wandbox.Call(action, retries, retry_wait)
195
            elif is_limit(e) and retries > 0:
196
                try:
197
                    print(e.message)
198
                except Exception:
199
                    pass
200
                limit_wait = 10
201
                print('wait {0}min'.format(limit_wait), end='', flush=True)
202
                for x in range(limit_wait):
203
                    print('.', end='', flush=True)
204
                    sleep(60)
205
                print('.')
206
                return Wandbox.Call(action, retries, retry_wait)
207
            else:
208
                raise
209
        except Exception:
210
            raise
211
212
213
if __name__ == '__main__':
214
    with Wandbox() as w:
215
        w.compiler('gcc-head')
216
        w.options('warning,gnu++1y')
217
        w.compiler_options('-Dx=hogefuga\n-O3')
218
        w.code('#include <iostream>\nint main() { int x = 0; std::cout << "hoge" << std::endl; }')
219
        print(w.run())
220