Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Commit c73a674

Browse files
committed
finally clean up the one large cli4 routine. it needed to be split a long time ago
1 parent 1a6593c commit c73a674

File tree

1 file changed

+172
-155
lines changed

1 file changed

+172
-155
lines changed

cli4/cli4.py

Lines changed: 172 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -14,163 +14,14 @@
1414

1515
import CloudFlare
1616

17-
def dump_commands(cf):
17+
def dump_commands():
1818
"""dump a tree of all the known API commands"""
19+
cf = CloudFlare.CloudFlare()
1920
w = cf.api_list()
2021
sys.stdout.write('\n'.join(w) + '\n')
2122

22-
def cli4(args):
23-
"""Cloudflare API via command line"""
24-
25-
verbose = False
26-
output = 'json'
27-
raw = False
28-
dump = False
29-
method = 'GET'
30-
31-
usage = ('usage: cli4 '
32-
+ '[-V|--version] [-h|--help] [-v|--verbose] [-q|--quiet] [-j|--json] [-y|--yaml] '
33-
+ '[-r|--raw] '
34-
+ '[-d|--dump] '
35-
+ '[--get|--patch|--post|--put|--delete] '
36-
+ '[item=value|item=@filename|@filename ...] '
37-
+ '/command...')
38-
39-
try:
40-
opts, args = getopt.getopt(args,
41-
'VhvqjyrdGPOUD',
42-
[
43-
'version',
44-
'help', 'verbose', 'quiet', 'json', 'yaml',
45-
'raw',
46-
'dump',
47-
'get', 'patch', 'post', 'put', 'delete'
48-
])
49-
except getopt.GetoptError:
50-
exit(usage)
51-
for opt, arg in opts:
52-
if opt in ('-V', '--version'):
53-
exit('Cloudflare library version: %s' % (CloudFlare.__version__))
54-
if opt in ('-h', '--help'):
55-
exit(usage)
56-
elif opt in ('-v', '--verbose'):
57-
verbose = True
58-
elif opt in ('-q', '--quiet'):
59-
output = None
60-
elif opt in ('-j', '--json'):
61-
output = 'json'
62-
elif opt in ('-y', '--yaml'):
63-
if yaml is None:
64-
exit('cli4: install yaml support')
65-
output = 'yaml'
66-
elif opt in ('-r', '--raw'):
67-
raw = True
68-
elif opt in ('-d', '--dump'):
69-
dump = True
70-
elif opt in ('-G', '--get'):
71-
method = 'GET'
72-
elif opt in ('-P', '--patch'):
73-
method = 'PATCH'
74-
elif opt in ('-O', '--post'):
75-
method = 'POST'
76-
elif opt in ('-U', '--put'):
77-
method = 'PUT'
78-
elif opt in ('-D', '--delete'):
79-
method = 'DELETE'
80-
81-
if dump:
82-
cf = CloudFlare.CloudFlare()
83-
dump_commands(cf)
84-
exit(0)
85-
86-
digits_only = re.compile('^-?[0-9]+$')
87-
floats_only = re.compile('^-?[0-9.]+$')
88-
89-
# next grab the params. These are in the form of tag=value or =value or @filename
90-
params = None
91-
content = None
92-
files = None
93-
while len(args) > 0 and ('=' in args[0] or args[0][0] == '@'):
94-
arg = args.pop(0)
95-
if arg[0] == '@':
96-
if method != 'PUT':
97-
exit('cli4: %s - raw file upload only with PUT' % (filename))
98-
filename = arg[1:]
99-
try:
100-
if filename == '-':
101-
content = sys.stdin.read()
102-
else:
103-
with open(filename, 'r') as f:
104-
content = f.read()
105-
except IOError:
106-
exit('cli4: %s - file open failure' % (filename))
107-
continue
108-
tag_string, value_string = arg.split('=', 1)
109-
if value_string.lower() == 'true':
110-
value = True
111-
elif value_string.lower() == 'false':
112-
value = False
113-
elif value_string == '' or value_string.lower() == 'none':
114-
value = None
115-
elif value_string[0] is '=' and value_string[1:] == '':
116-
exit('cli4: %s== - no number value passed' % (tag_string))
117-
elif value_string[0] is '=' and digits_only.match(value_string[1:]):
118-
value = int(value_string[1:])
119-
elif value_string[0] is '=' and floats_only.match(value_string[1:]):
120-
value = float(value_string[1:])
121-
elif value_string[0] is '=':
122-
exit('cli4: %s== - invalid number value passed' % (tag_string))
123-
elif value_string[0] in '[{' and value_string[-1] in '}]':
124-
# a json structure - used in pagerules
125-
try:
126-
#value = json.loads(value) - changed to yaml code to remove unicode string issues
127-
if yaml is None:
128-
exit('cli4: install yaml support')
129-
value = yaml.safe_load(value_string)
130-
except ValueError:
131-
exit('cli4: %s="%s" - can\'t parse json value' % (tag_string, value_string))
132-
elif value_string[0] is '@':
133-
filename = value_string[1:]
134-
# a file to be uploaded - used in dns_records/import - only via POST
135-
if method != 'POST':
136-
exit('cli4: %s=%s - file upload only with POST' % (tag_string, filename))
137-
files = {}
138-
try:
139-
if filename == '-':
140-
files[tag_string] = sys.stdin
141-
else:
142-
files[tag_string] = open(filename, 'rb')
143-
except IOError:
144-
exit('cli4: %s=%s - file open failure' % (tag_string, filename))
145-
# no need for param code below
146-
continue
147-
else:
148-
value = value_string
149-
150-
if tag_string == '':
151-
# There's no tag; it's just an unnamed list
152-
if params is None:
153-
params = []
154-
try:
155-
params.append(value)
156-
except AttributeError:
157-
exit('cli4: %s=%s - param error. Can\'t mix unnamed and named list' %
158-
(tag_string, value_string))
159-
else:
160-
if params is None:
161-
params = {}
162-
tag = tag_string
163-
try:
164-
params[tag] = value
165-
except TypeError:
166-
exit('cli4: %s=%s - param error. Can\'t mix unnamed and named list' %
167-
(tag_string, value_string))
168-
169-
# what's left is the command itself
170-
if len(args) != 1:
171-
exit(usage)
172-
173-
command = args[0]
23+
def run_command(cf, method, command, params=None, content=None, files=None):
24+
"""run the command line"""
17425
# remove leading and trailing /'s
17526
if command[0] == '/':
17627
command = command[1:]
@@ -190,8 +41,6 @@ def cli4(args):
19041
hex_only = re.compile('^[0-9a-fA-F]+$')
19142
waf_rules = re.compile('^[0-9]+[A-Z]*$')
19243

193-
cf = CloudFlare.CloudFlare(debug=verbose, raw=raw)
194-
19544
m = cf
19645
for element in parts:
19746
if element[0] == ':':
@@ -302,10 +151,16 @@ def cli4(args):
302151
for x in e:
303152
sys.stderr.write('cli4: /%s - %d %s\n' % (command, x, x))
304153
exit('cli4: /%s - %d %s' % (command, e, e))
154+
except CloudFlare.exceptions.CloudFlareInternalError as e:
155+
exit('cli4: InternalError: /%s - %d %s' % (command, e, e))
305156
except Exception as e:
306157
exit('cli4: /%s - %s - api error' % (command, e))
307158

308159
results.append(r)
160+
return results
161+
162+
def write_results(results, output):
163+
"""dump the results"""
309164

310165
if len(results) == 1:
311166
results = results[0]
@@ -335,3 +190,165 @@ def cli4(args):
335190
if not results.endswith('\n'):
336191
sys.stdout.write('\n')
337192

193+
def do_it(args):
194+
"""Cloudflare API via command line"""
195+
196+
verbose = False
197+
output = 'json'
198+
raw = False
199+
dump = False
200+
method = 'GET'
201+
202+
usage = ('usage: cli4 '
203+
+ '[-V|--version] [-h|--help] [-v|--verbose] [-q|--quiet] [-j|--json] [-y|--yaml] '
204+
+ '[-r|--raw] '
205+
+ '[-d|--dump] '
206+
+ '[--get|--patch|--post|--put|--delete] '
207+
+ '[item=value|item=@filename|@filename ...] '
208+
+ '/command...')
209+
210+
try:
211+
opts, args = getopt.getopt(args,
212+
'VhvqjyrdGPOUD',
213+
[
214+
'version',
215+
'help', 'verbose', 'quiet', 'json', 'yaml',
216+
'raw',
217+
'dump',
218+
'get', 'patch', 'post', 'put', 'delete'
219+
])
220+
except getopt.GetoptError:
221+
exit(usage)
222+
for opt, arg in opts:
223+
if opt in ('-V', '--version'):
224+
exit('Cloudflare library version: %s' % (CloudFlare.__version__))
225+
if opt in ('-h', '--help'):
226+
exit(usage)
227+
elif opt in ('-v', '--verbose'):
228+
verbose = True
229+
elif opt in ('-q', '--quiet'):
230+
output = None
231+
elif opt in ('-j', '--json'):
232+
output = 'json'
233+
elif opt in ('-y', '--yaml'):
234+
if yaml is None:
235+
exit('cli4: install yaml support')
236+
output = 'yaml'
237+
elif opt in ('-r', '--raw'):
238+
raw = True
239+
elif opt in ('-d', '--dump'):
240+
dump = True
241+
elif opt in ('-G', '--get'):
242+
method = 'GET'
243+
elif opt in ('-P', '--patch'):
244+
method = 'PATCH'
245+
elif opt in ('-O', '--post'):
246+
method = 'POST'
247+
elif opt in ('-U', '--put'):
248+
method = 'PUT'
249+
elif opt in ('-D', '--delete'):
250+
method = 'DELETE'
251+
252+
if dump:
253+
dump_commands()
254+
exit(0)
255+
256+
digits_only = re.compile('^-?[0-9]+$')
257+
floats_only = re.compile('^-?[0-9.]+$')
258+
259+
# next grab the params. These are in the form of tag=value or =value or @filename
260+
params = None
261+
content = None
262+
files = None
263+
while len(args) > 0 and ('=' in args[0] or args[0][0] == '@'):
264+
arg = args.pop(0)
265+
if arg[0] == '@':
266+
# a file to be uploaded - used in workers/script - only via PUT
267+
filename = arg[1:]
268+
if method != 'PUT':
269+
exit('cli4: %s - raw file upload only with PUT' % (filename))
270+
try:
271+
if filename == '-':
272+
content = sys.stdin.read()
273+
else:
274+
with open(filename, 'r') as f:
275+
content = f.read()
276+
except IOError:
277+
exit('cli4: %s - file open failure' % (filename))
278+
continue
279+
tag_string, value_string = arg.split('=', 1)
280+
if value_string.lower() == 'true':
281+
value = True
282+
elif value_string.lower() == 'false':
283+
value = False
284+
elif value_string == '' or value_string.lower() == 'none':
285+
value = None
286+
elif value_string[0] is '=' and value_string[1:] == '':
287+
exit('cli4: %s== - no number value passed' % (tag_string))
288+
elif value_string[0] is '=' and digits_only.match(value_string[1:]):
289+
value = int(value_string[1:])
290+
elif value_string[0] is '=' and floats_only.match(value_string[1:]):
291+
value = float(value_string[1:])
292+
elif value_string[0] is '=':
293+
exit('cli4: %s== - invalid number value passed' % (tag_string))
294+
elif value_string[0] in '[{' and value_string[-1] in '}]':
295+
# a json structure - used in pagerules
296+
try:
297+
#value = json.loads(value) - changed to yaml code to remove unicode string issues
298+
if yaml is None:
299+
exit('cli4: install yaml support')
300+
value = yaml.safe_load(value_string)
301+
except ValueError:
302+
exit('cli4: %s="%s" - can\'t parse json value' % (tag_string, value_string))
303+
elif value_string[0] is '@':
304+
# a file to be uploaded - used in dns_records/import - only via POST
305+
filename = value_string[1:]
306+
if method != 'POST':
307+
exit('cli4: %s=%s - file upload only with POST' % (tag_string, filename))
308+
files = {}
309+
try:
310+
if filename == '-':
311+
files[tag_string] = sys.stdin
312+
else:
313+
files[tag_string] = open(filename, 'rb')
314+
except IOError:
315+
exit('cli4: %s=%s - file open failure' % (tag_string, filename))
316+
# no need for param code below
317+
continue
318+
else:
319+
value = value_string
320+
321+
if tag_string == '':
322+
# There's no tag; it's just an unnamed list
323+
if params is None:
324+
params = []
325+
try:
326+
params.append(value)
327+
except AttributeError:
328+
exit('cli4: %s=%s - param error. Can\'t mix unnamed and named list' %
329+
(tag_string, value_string))
330+
else:
331+
if params is None:
332+
params = {}
333+
tag = tag_string
334+
try:
335+
params[tag] = value
336+
except TypeError:
337+
exit('cli4: %s=%s - param error. Can\'t mix unnamed and named list' %
338+
(tag_string, value_string))
339+
340+
# what's left is the command itself
341+
if len(args) != 1:
342+
exit(usage)
343+
command = args[0]
344+
345+
cf = CloudFlare.CloudFlare(debug=verbose, raw=raw)
346+
results = run_command(cf, method, command, params, content, files)
347+
write_results(results, output)
348+
349+
def cli4(args):
350+
"""Cloudflare API via command line"""
351+
352+
do_it(args)
353+
exit(0)
354+

0 commit comments

Comments
 (0)