chore: remove useless use of OOP
[grml-paste.git] / grml-paste
1 #!/usr/bin/python3
2 # Filename:      grml-paste
3 # Purpose:       XmlRpc interface client to paste.grml.org
4 # Author:        Michael Gebetsroither <gebi@grml.org>
5 # License:       This file is licensed under the GPL v2.
6 ################################################################################
7
8 import sys
9 from xmlrpc.client import ServerProxy
10 import optparse
11 import inspect
12 import getpass
13
14 # program defaults
15 DEFAULT_SERVER = "http://paste.grml.org/server.pl"
16
17
18 class ActionFailedException(Exception):
19     """Thrown if server returned an error"""
20
21     def __init__(self, errormsg, ret):
22         Exception.__init__(self, errormsg, ret)
23
24     def what(self):
25         """Get errormessage"""
26         return self.args[0]
27
28     def dwhat(self):
29         """Get more verbose errormessage"""
30         return self.args[1]
31
32
33 def _paste(opts):
34     """Get paste proxy object"""
35     return (ServerProxy(opts.server, verbose=False).paste)
36
37
38 def _check_success(return_data):
39     """Check if call was successful, raise AcitonFailedException otherwise"""
40     if return_data["rc"] != 0:
41         raise ActionFailedException(return_data["statusmessage"], return_data)
42     return return_data
43
44
45 def action_add_paste(opts, code):
46     """Add paste to the server: <1.line> <2.line> ...
47
48     default     Read paste from stdin.
49     [text]      Every argument on the commandline will be interpreted as
50                 a seperate line of paste.
51     """
52     if len(code) == 0:
53         code = [line.rstrip() for line in sys.stdin.readlines()]
54     code = "\n".join(code)
55     result = _check_success(_paste(opts).addPaste(code, opts.name, opts.expire * 3600, opts.lang, opts.private))
56     return result["statusmessage"], result
57
58
59 def action_del_paste(opts, args):
60     """Delete paste from server: <digest>
61
62     <digest>    Digest of paste you want to remove.
63     """
64     digest = args.pop(0)
65     result = _check_success(_paste(opts).deletePaste(digest))
66     return result["statusmessage"], result
67
68
69 def action_get_paste(opts, args):
70     """Get paste from server: <id>
71
72     <id>        Id of paste you want to receive.
73     """
74     paste_id = args.pop(0)
75     result = _check_success(_paste(opts).getPaste(paste_id))
76     return result["code"], result
77
78
79 def action_get_langs(opts, args):
80     """Get supported language highlighting types from server"""
81     result = _check_success(_paste(opts).getLanguages())
82     return "\n".join(result["langs"]), result
83
84
85 def action_add_short_url(opts, args):
86     """Add short-URL: <url>
87
88     <url>        Short-URL to add
89     """
90     url = args.pop(0)
91     result = _check_success(_paste(opts).addShortURL(url))
92     return result["url"], result
93
94
95 def action_get_short_url(opts, args):
96     """Resolve short-URL: <url>
97
98     <url>        Short-URL to get clicks of
99     """
100     url = args.pop(0)
101     result = _check_success(_paste(opts).resolveShortURL(url))
102     return result["url"], result
103
104
105 def action_get_short_url_clicks(opts, args):
106     """Get clicks of short-URL: <url>
107
108     <url>        Short-URL to get clicks of
109     """
110     url = args.pop(0)
111     result = _check_success(_paste(opts).ShortURLClicks(url))
112     return result["count"], result
113
114
115 def action_help(opts, args):
116     """Print more verbose help about specific action: <action>
117
118     <action>    Topic on which you need more verbose help.
119     """
120     if len(args) < 1:
121         alias = "help"
122     else:
123         alias = args.pop(0)
124
125     if alias in actions:
126         function_name = actions[alias]
127         print(inspect.getdoc(globals()[function_name]))
128         print("\naliases: " + " ".join([i for i in actions_r[function_name] if i != alias]))
129     else:
130         print("Error: No such command - %s" % (alias))
131         OPT_PARSER.print_usage()
132     sys.exit(0)
133
134
135 # action_add_paste -> [add, a]
136 actions_r = {}
137
138 # add -> action_add_paste
139 # a   -> action_add_paste
140 actions = {}
141
142 # option parser
143 OPT_PARSER = None
144
145
146 ##
147 # MAIN
148 ##
149 if __name__ == "__main__":
150     action_specs = [
151         "action_add_paste add a",
152         "action_del_paste del d rm",
153         "action_get_paste get g",
154         "action_get_langs getlangs gl langs l",
155         "action_add_short_url addurl",
156         "action_get_short_url geturl",
157         "action_get_short_url_clicks getclicks",
158         "action_help     help"
159     ]
160     for action_spec in action_specs:
161         aliases = action_spec.split()
162         cmd = aliases.pop(0)
163         actions_r[cmd] = aliases
164     for (action_name, v) in actions_r.items():
165         for i in v:
166             actions[i] = action_name
167
168     usage = "usage: %prog [options] ACTION <args>\n\n" +\
169             "actions:\n" +\
170             "\n".join(["%12s\t%s" % (v[0], inspect.getdoc(globals()[action_name]).splitlines()[0])
171                       for (action_name, v) in actions_r.items()])
172     running_user = getpass.getuser()
173     parser = optparse.OptionParser(usage=usage)
174     parser.add_option("-n", "--name", default=running_user, help="Name of poster")
175     parser.add_option("-e", "--expire", type=int, default=72, metavar="HOURS",
176                       help="Time at wich paste should expire")
177     parser.add_option("-l", "--lang", default="Plain", help="Type of language to highlight")
178     parser.add_option("-p", "--private", action="count", dest="private", default=0,
179                       help="Create hidden paste"),
180     parser.add_option("-s", "--server", default=DEFAULT_SERVER,
181                       help="Paste server")
182     parser.add_option("-v", "--verbose", action="count", default=0, help="More output")
183     (opts, args) = parser.parse_args()
184     OPT_PARSER = parser
185
186     if len(args) == 0:
187         parser.error("Please provide me with an action")
188     elif args[0] in actions:
189         cmd = args.pop(0)
190         action = actions[cmd]
191         try:
192             (msg, ret) = globals()[action](opts, args)
193             if opts.verbose == 0:
194                 print(msg)
195             else:
196                 print(ret)
197         except ActionFailedException as except_inst:
198             sys.stderr.write("Server Error: %s\n" % except_inst.what())
199             if opts.verbose > 0:
200                 print(except_inst.dwhat())
201             sys.exit(1)
202     else:
203         parser.error("Unknown action: %s" % args[0])