X-Git-Url: http://git.grml.org/?p=grml-paste.git;a=blobdiff_plain;f=grml-paste;h=b89a200559bcd36f1bb8c3457c491b0afa4b39a2;hp=cbd368ee5114f8fef774d167d9f22fbc9e1ada13;hb=HEAD;hpb=30469c38e027b62823bc443e63d3f4c469e00dff diff --git a/grml-paste b/grml-paste index cbd368e..b89a200 100755 --- a/grml-paste +++ b/grml-paste @@ -1,146 +1,150 @@ -#!/usr/bin/python +#!/usr/bin/python3 # Filename: grml-paste # Purpose: XmlRpc interface client to paste.grml.org # Author: Michael Gebetsroither # License: This file is licensed under the GPL v2. ################################################################################ -import sys -import xmlrpclib -import optparse -import inspect import getpass +import inspect +import optparse +import sys +from xmlrpc.client import ServerProxy # program defaults -DEFAULT_SERVER='http://paste.grml.org/server.pl' +DEFAULT_SERVER = "https://paste.grml.org/server.pl" + class ActionFailedException(Exception): - '''Thrown if server returned an error''' + """Thrown if server returned an error""" + def __init__(self, errormsg, ret): Exception.__init__(self, errormsg, ret) + def what(self): - '''Get errormessage''' + """Get errormessage""" return self.args[0] + def dwhat(self): - '''Get more verbose errormessage''' + """Get more verbose errormessage""" return self.args[1] -class Action(object): - def __init__(self, args, opts): - self.args_ = args - self.opts_ = opts - - def _createProxy(self): - return xmlrpclib.ServerProxy(self.opts_.server) - - def _callProxy(self, functor, server=None): - '''Wrapper for xml-rpc calls to server which throws an - ActionFailedException on error''' - if server is None: - server = self._createProxy() - ret = functor(server) - if ret['rc'] != 0: - raise ActionFailedException(ret['statusmessage'], ret) - return ret - - def call(self, method_name): - '''External Interface to call the appropriate action''' - return self.__getattribute__(method_name)() - - def actionAddPaste(self): - '''Add paste to the server: <1.line> <2.line> ... - - default Read paste from stdin. - [text] Every argument on the commandline will be interpreted as - a seperate line of paste. - ''' - server = self._createProxy() - o = self.opts_ - code = self.args_ - if len(self.args_) == 0: - code = [ i.rstrip() for i in sys.stdin.readlines() ] - code = '\n'.join(code) - result = self._callProxy(lambda s: s.paste.addPaste(code, o.name, o.expire * 3600, o.lang, o.private), - server) - return (result['statusmessage'], result) - - def actionDelPaste(self): - '''Delete paste from server: - - Digest of paste you want to remove. - ''' - digest = self.args_.pop(0) - result = self._callProxy(lambda s: s.paste.deletePaste(digest)) - return (result['statusmessage'], result) - - def actionGetPaste(self): - '''Get paste from server: - - Id of paste you want to receive. - ''' - id = self.args_.pop(0) - result = self._callProxy(lambda s: s.paste.getPaste(id)) - return (result['code'], result) - - def actionGetLangs(self): - '''Get supported language highlighting types from server''' - result = self._callProxy(lambda s: s.paste.getLanguages()) - return ('\n'.join(result['langs']), result) - - def actionAddShortUrl(self): - '''Add short-URL: - - Short-URL to add - ''' - url = self.args_.pop(0) - result = self._callProxy(lambda s: s.paste.addShortURL(url)) - return (result['url'], result) - - def actionGetShortUrl(self): - '''Resolve short-URL: - - Short-URL to get clicks of - ''' - url = self.args_.pop(0) - result = self._callProxy(lambda s: s.paste.resolveShortURL(url)) - return (result['url'], result) - - def actionGetShortUrlClicks(self): - '''Get clicks of short-URL: - - Short-URL to get clicks of - ''' - url = self.args_.pop(0) - result = self._callProxy(lambda s: s.paste.ShortURLClicks(url)) - return (result['count'], result) - - def actionHelp(self): - '''Print more verbose help about specific action: - - Topic on which you need more verbose help. - ''' - if len(self.args_) < 1: - alias = "help" - else: - alias = self.args_.pop(0) - - if alias in actions: - fun = actions[alias] - print inspect.getdoc(self.__getattribute__(fun)) - print "\naliase: " + " ".join([i for i in actions_r[fun] if i != alias]) - else: - print "Error: No such command - %s" % (alias) - OPT_PARSER.print_usage() - sys.exit(0) - - -# actionAddPaste -> [add, a] +def _paste(opts): + """Get paste proxy object""" + return ServerProxy(opts.server, verbose=False).paste + + +def _check_success(return_data): + """Check if call was successful, raise ActionFailedException otherwise""" + if return_data["rc"] != 0: + raise ActionFailedException(return_data["statusmessage"], return_data) + return return_data + + +def action_add_paste(opts, code): + """Add paste to the server: <1.line> <2.line> ... + + default Read paste from stdin. + [text] Every argument on the commandline will be interpreted as + a seperate line of paste. + """ + if len(code) == 0: + code = [line.rstrip() for line in sys.stdin.readlines()] + code = "\n".join(code) + result = _check_success( + _paste(opts).addPaste( + code, opts.name, opts.expire * 3600, opts.lang, opts.private + ) + ) + return result["statusmessage"], result + + +def action_del_paste(opts, args): + """Delete paste from server: + + Digest of paste you want to remove. + """ + digest = args.pop(0) + result = _check_success(_paste(opts).deletePaste(digest)) + return result["statusmessage"], result + + +def action_get_paste(opts, args): + """Get paste from server: + + Id of paste you want to receive. + """ + paste_id = args.pop(0) + result = _check_success(_paste(opts).getPaste(paste_id)) + return result["code"], result + + +def action_get_langs(opts, args): + """Get supported language highlighting types from server""" + result = _check_success(_paste(opts).getLanguages()) + return "\n".join(result["langs"]), result + + +def action_add_short_url(opts, args): + """Add short-URL: + + Short-URL to add + """ + url = args.pop(0) + result = _check_success(_paste(opts).addShortURL(url)) + return result["url"], result + + +def action_get_short_url(opts, args): + """Resolve short-URL: + + Short-URL to get clicks of + """ + url = args.pop(0) + result = _check_success(_paste(opts).resolveShortURL(url)) + return result["url"], result + + +def action_get_short_url_clicks(opts, args): + """Get clicks of short-URL: + + Short-URL to get clicks of + """ + url = args.pop(0) + result = _check_success(_paste(opts).ShortURLClicks(url)) + return result["count"], result + + +def action_help(opts, args): + """Print more verbose help about specific action: + + Topic on which you need more verbose help. + """ + if len(args) < 1: + alias = "help" + else: + alias = args.pop(0) + + if alias in actions: + function_name = actions[alias] + print(inspect.getdoc(globals()[function_name])) + print( + "\naliases: " + + " ".join([i for i in actions_r[function_name] if i != alias]) + ) + else: + print("Error: No such command - %s" % (alias)) + OPT_PARSER.print_usage() + sys.exit(0) + + +# action_add_paste -> [add, a] actions_r = {} -# add -> actionAddPaste -# a -> actionAddPaste -actions = {} +# add -> action_add_paste +# a -> action_add_paste +actions = {} # option parser OPT_PARSER = None @@ -150,55 +154,77 @@ OPT_PARSER = None # MAIN ## if __name__ == "__main__": - action_spec = ['actionAddPaste add a', - 'actionDelPaste del d rm', - 'actionGetPaste get g', - 'actionGetLangs getlangs gl langs l', - 'actionAddShortUrl addurl', - 'actionGetShortUrl geturl', - 'actionGetShortUrlClicks getclicks', - 'actionHelp help'] - for i in action_spec: - aliases = i.split() + action_specs = [ + "action_add_paste add a", + "action_del_paste del d rm", + "action_get_paste get g", + "action_get_langs getlangs gl langs l", + "action_add_short_url addurl", + "action_get_short_url geturl", + "action_get_short_url_clicks getclicks", + "action_help help", + ] + for action_spec in action_specs: + aliases = action_spec.split() cmd = aliases.pop(0) actions_r[cmd] = aliases - for (k,v) in actions_r.items(): + for (action_name, v) in actions_r.items(): for i in v: - actions[i] = k - - usage = "usage: %prog [options] ACTION \n\n" +\ - "actions:\n" +\ - "\n".join(["%12s\t%s" % (v[0], inspect.getdoc(getattr(Action, k)).split('\n')[0]) \ - for (k,v) in actions_r.items()]) + actions[i] = action_name + + usage = ( + "usage: %prog [options] ACTION \n\n" + + "actions:\n" + + "\n".join( + [ + "%12s\t%s" + % (v[0], inspect.getdoc(globals()[action_name]).splitlines()[0]) + for (action_name, v) in actions_r.items() + ] + ) + ) running_user = getpass.getuser() parser = optparse.OptionParser(usage=usage) - parser.add_option('-n', '--name', default=running_user, help="Name of poster") - parser.add_option('-e', '--expire', type=int, default=72, metavar='HOURS', - help='Time at wich paste should expire') - parser.add_option('-l', '--lang', default='Plain', help='Type of language to highlight') - parser.add_option("-p", "--private", action="count", dest="private", default=0, - help='Create hidden paste'), - parser.add_option('-s', '--server', default=DEFAULT_SERVER, - help='Paste server') - parser.add_option('-v', '--verbose', action='count', default=0, help='More output') + parser.add_option("-n", "--name", default=running_user, help="Name of poster") + parser.add_option( + "-e", + "--expire", + type=int, + default=72, + metavar="HOURS", + help="Time at which paste should expire", + ) + parser.add_option( + "-l", "--lang", default="Plain", help="Type of language to highlight" + ) + parser.add_option( + "-p", + "--private", + action="count", + dest="private", + default=0, + help="Create hidden paste", + ), + parser.add_option("-s", "--server", default=DEFAULT_SERVER, help="Paste server") + parser.add_option("-v", "--verbose", action="count", default=0, help="More output") (opts, args) = parser.parse_args() OPT_PARSER = parser if len(args) == 0: - parser.error('Please provide me with an action') + parser.error("Please provide me with an action") elif args[0] in actions: cmd = args.pop(0) - action = Action(args, opts) + action = actions[cmd] try: - (msg, ret) = action.call(actions[cmd]) + (msg, ret) = globals()[action](opts, args) if opts.verbose == 0: - print msg + print(msg) else: - print ret - except ActionFailedException, e: - sys.stderr.write('Server Error: %s\n' % e.what()) - if opts.verbose >0: - print e.dwhat() + print(ret) + except ActionFailedException as except_inst: + sys.stderr.write("Server Error: %s\n" % except_inst.what()) + if opts.verbose > 0: + print(except_inst.dwhat()) sys.exit(1) else: - parser.error('Unknown action: %s' % args[0]) + parser.error("Unknown action: %s" % args[0])