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 ################################################################################
15 DEFAULT_SERVER='http://paste.grml.org/server.pl'
17 class ActionFailedException(Exception):
18 '''Thrown if server returned an error'''
19 def __init__(self, errormsg, ret):
20 Exception.__init__(self, errormsg, ret)
22 '''Get errormessage'''
25 '''Get more verbose errormessage'''
30 def __init__(self, args, opts):
34 def _createProxy(self):
35 return xmlrpclib.ServerProxy(self.opts_.server)
37 def _callProxy(self, functor, server=None):
38 '''Wrapper for xml-rpc calls to server which throws an
39 ActionFailedException on error'''
41 server = self._createProxy()
44 raise ActionFailedException(ret['statusmessage'], ret)
47 def call(self, method_name):
48 '''External Interface to call the appropriate action'''
49 return self.__getattribute__(method_name)()
51 def actionAddPaste(self):
52 '''Add paste to the server: <1.line> <2.line> ...
54 default Read paste from stdin.
55 [text] Every argument on the commandline will be interpreted as
56 a seperate line of paste.
58 server = self._createProxy()
61 if len(self.args_) == 0:
62 code = [ i.strip() for i in sys.stdin.readlines() ]
63 code = '\n'.join(code)
64 result = self._callProxy(lambda s: s.paste.addPaste(code, o.name, o.expire * 3600, o.lang, o.private),
66 return (result['statusmessage'], result)
68 def actionDelPaste(self):
69 '''Delete paste from server: <digest>
71 <digest> Digest of paste you want to remove.
73 digest = self.args_.pop(0)
74 result = self._callProxy(lambda s: s.paste.deletePaste(digest))
75 return (result['statusmessage'], result)
77 def actionGetPaste(self):
78 '''Get paste from server: <id>
80 <id> Id of paste you want to receive.
82 id = self.args_.pop(0)
83 result = self._callProxy(lambda s: s.paste.getPaste(id))
84 return (result['code'], result)
86 def actionGetLangs(self):
87 '''Get supported language highlighting types from server'''
88 result = self._callProxy(lambda s: s.paste.getLanguages())
89 return ('\n'.join(result['langs']), result)
91 def actionAddShortUrl(self):
92 '''Add short-URL: <url>
94 <url> Short-URL to add
96 url = self.args_.pop(0)
97 result = self._callProxy(lambda s: s.paste.addShortURL(url))
98 return (result['url'], result)
100 def actionGetShortUrl(self):
101 '''Resolve short-URL: <url>
103 <url> Short-URL to get clicks of
105 url = self.args_.pop(0)
106 result = self._callProxy(lambda s: s.paste.resolveShortURL(url))
107 return (result['url'], result)
109 def actionGetShortUrlClicks(self):
110 '''Get clicks of short-URL: <url>
112 <url> Short-URL to get clicks of
114 url = self.args_.pop(0)
115 result = self._callProxy(lambda s: s.paste.ShortURLClicks(url))
116 return (result['count'], result)
118 def actionHelp(self):
119 '''Print more verbose help about specific action: <action>
121 <action> Topic on which you need more verbose help.
123 if len(self.args_) < 1:
126 alias = self.args_.pop(0)
130 print inspect.getdoc(self.__getattribute__(fun))
131 print "\naliase: " + " ".join([i for i in actions_r[fun] if i != alias])
133 print "Error: No such command - %s" % (alias)
134 OPT_PARSER.print_usage()
138 # actionAddPaste -> [add, a]
141 # add -> actionAddPaste
142 # a -> actionAddPaste
152 if __name__ == "__main__":
153 action_spec = ['actionAddPaste add a',
154 'actionDelPaste del d rm',
155 'actionGetPaste get g',
156 'actionGetLangs getlangs gl langs l',
157 'actionAddShortUrl addurl',
158 'actionGetShortUrl geturl',
159 'actionGetShortUrlClicks getclicks',
161 for i in action_spec:
164 actions_r[cmd] = aliases
165 for (k,v) in actions_r.items():
169 usage = "usage: %prog [options] ACTION <args>\n\n" +\
171 "\n".join(["%12s\t%s" % (v[0], inspect.getdoc(getattr(Action, k)).split('\n')[0]) \
172 for (k,v) in actions_r.items()])
173 running_user = getpass.getuser()
174 parser = optparse.OptionParser(usage=usage)
175 parser.add_option('-n', '--name', default=running_user, help="Name of poster")
176 parser.add_option('-e', '--expire', type=int, default=72, metavar='HOURS',
177 help='Time at wich paste should expire')
178 parser.add_option('-l', '--lang', default='Plain', help='Type of language to highlight')
179 parser.add_option("-p", "--private", action="count", dest="private", default=0,
180 help='Create hidden paste'),
181 parser.add_option('-s', '--server', default=DEFAULT_SERVER,
183 parser.add_option('-v', '--verbose', action='count', default=0, help='More output')
184 (opts, args) = parser.parse_args()
188 parser.error('Please provide me with an action')
189 elif args[0] in actions:
191 action = Action(args, opts)
193 (msg, ret) = action.call(actions[cmd])
194 if opts.verbose == 0:
198 except ActionFailedException, e:
199 sys.stderr.write('Server Error: %s\n' % e.what())
204 parser.error('Unknown action: %s' % args[0])