-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathschema-dump.py
More file actions
executable file
·174 lines (143 loc) · 4.97 KB
/
schema-dump.py
File metadata and controls
executable file
·174 lines (143 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Use recently documented XML-RPC API to dump
Roundup data schema in human readable form.
Works with demo tracker using:
http://admin:admin@localhost:8917/demo/xmlrpc
Future development may cover:
[ ] unreadable dump formats
[ ] access to local database
[ ] lossless dump/restore cycle
[ ] data dump and filtering with preserved
Works in Python 2 as well.
"""
from __future__ import print_function
__license__ = "Public Domain"
__version__ = "1.1"
__authors__ = [
"anatoly techtonik <techtonik@gmail.com>"
"John Rouillard <rouilj@users.sourceforge.net>"
]
import os
import pprint
import sys
import textwrap
try:
import urllib.parse as url_parser # python 3
except ImportError:
import urlparse as url_parser # python 2
from argparse import ArgumentParser
from roundup.anypy import xmlrpc_
sname = os.path.basename(sys.argv[0])
usage = """\
usage: %s [options] URL
URL is XML-RPC endpoint for your tracker, such as:
http://localhost:8917/demo/xmlrpc
options:
--pprint (default)
--json
--yaml
--raw
-h --help
--version
""" % sname
def format_pprint(var):
return pprint.pformat(var)
def format_json(var):
jout = pprint.pformat(var)
jout = jout.replace('"', "\\'") # " to \'
jout = jout.replace("'", '"') # ' to "
jout = jout.replace('\\"', "'") # \" to '
return jout
def format_yaml(var):
out = pprint.pformat(var)
out = out.replace('{', ' ')
out = out.replace('}', '')
out = textwrap.dedent(out)
out = out.replace("'", '')
out = out.replace(' [[', '\n [')
out = out.replace(']]', ']')
out = out.replace('],', '')
out = out.replace(']', '')
out2 = []
for line in out.splitlines():
if '[' in line:
line = ' ' + line.lstrip(' [')
line = line.replace('>', '')
line = line.replace('roundup.hyperdb.', '')
# expandtabs(16) with limit=1
n, v = line.split(', <')
if len(n) > 14:
indent = 0
else:
indent = 14 - len(n)
line = line.replace(', <', ': '+' '*indent)
line.split(",")
out2.append(line)
out = '\n'.join(out2)
return out
class SpecialTransport():
"""Mixin for http/https transports to implement new send_content with
CSRF prevention headers to both of them.
"""
def send_content(self, connection, request_body):
connection.putheader("Referer", "%s://%s%s%s/" % (
self.components.scheme,
self.components.hostname,
':' + str(self.components.port) if self.components.port else '',
self.components.path))
connection.putheader("Origin", "%s://%s%s" % (
self.components.scheme, self.components.hostname,
':' + str(self.components.port) if self.components.port else ''))
connection.putheader("X-Requested-With", "XMLHttpRequest")
connection.putheader("Content-Type", "text/xml")
connection.putheader("Content-Length", str(len(request_body)))
connection.endheaders()
if request_body:
connection.send(request_body)
class SpecialHttpTransport(SpecialTransport, xmlrpc_.client.Transport,
object):
"""SpecialTransport must be first to use its send_content. Explicit
object inheritance required for python2 apparently."""
def __init__(self, url):
self.components = url_parser.urlparse(url)
# works both python2 (with object inheritance) and python3
super(SpecialHttpTransport, self).__init__(self)
class SpecialHttpsTransport(SpecialTransport, xmlrpc_.client.SafeTransport,
object):
"""SpecialTransport must be first to use its send_content. Explicit
object inheritance required for python2 apparently."""
def __init__(self, url):
self.components = url_parser.urlparse(url)
# works both python2 (with object inheritance) and python3
super(SpecialHttpsTransport, self).__init__(self)
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("url", nargs=1)
parser.add_argument("--raw", action='store_true')
parser.add_argument("--yaml", action='store_true')
parser.add_argument("--json", action='store_true')
parser.add_argument("-v", "--version", action='store_true')
args = parser.parse_args()
if args.version:
sys.exit(sname + " " + __version__)
if args.url[0].lower().startswith('https:'):
transport = SpecialHttpsTransport
else:
transport = SpecialHttpTransport
roundup_server = xmlrpc_.client.ServerProxy(
args.url[0],
transport=transport(args.url[0]),
verbose=False,
allow_none=True)
schema = roundup_server.schema()
if args.raw:
print(str(schema))
elif args.yaml:
print(format_yaml(schema))
elif args.json:
print(format_json(schema))
else:
print(format_pprint(schema))
print("")