X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=grml-paste;h=b89a200559bcd36f1bb8c3457c491b0afa4b39a2;hb=c0acd324c28506c5c110bf6dcee87238267a8a6d;hp=d4b7fb6699f7b8509cfc144ae969b17b71fa55c7;hpb=453ebd84a6d80bdbfd34e0427b68b8e89a43500d;p=grml-paste.git diff --git a/grml-paste b/grml-paste index d4b7fb6..b89a200 100755 --- a/grml-paste +++ b/grml-paste @@ -1,75 +1,230 @@ -#!/usr/bin/env ruby +#!/usr/bin/python3 # Filename: grml-paste -# Purpose: paste files to the online grml paste bot -# Authors: grml-team (grml.org), (c) 2007 Nico Golde -# Bug-Reports: see http://grml.org/bugs/ -# License: This file is licensed under the GPL v2 -########################################################################## - -require 'uri' -require 'net/http' - -url = URI.parse('http://paste.grml.org/paste') - -def usage - $stderr.puts "usage: #{$0} [-n nick] [-s summary] [-f source] [-h|--help]\n" - $stderr.puts "\t -n \tset your nickname (defaults to Anonymuos)" - $stderr.puts "\t -s \tspecify a summary of your paste (defaults to none)" - $stderr.puts "\t -f \tsets the file to read from, you don't need this for reading from stdin" - $stderr.puts "\t --help\t\tprint this help" - Kernel.exit(1) -end - -file = nil -summary = "none" -nick = "Anonymous" -channel = "#grml" -text = "" - -ARGV.each_index do |i| - if ARGV[i] == '-h' or ARGV[i] == '--help' then - usage - elsif ARGV[i] == '-n' and ARGV[i+1] != nil then - nick = ARGV[i+1] - elsif ARGV[i] == '-s' and ARGV[i+1] != nil then - summary = ARGV[i+1] - elsif ARGV[i] == '-f' and ARGV[i+1] != nil then - file = ARGV[i+1] - end -end - -if file == nil or file == "-" - f = STDIN -else - begin - f = File.open(file) - rescue - $stderr.puts "Error: couldn't open file: #{file}" - Kernel.exit(1) - end -end - -f.each_line do |line| - text << line -end - -begin - res = Net::HTTP.post_form(url,{'Paste it' => 'Paste it', 'paste' => text, 'channel' => channel, 'summary' => summary, 'nick' => nick}) -rescue - $stderr.puts "Unable to post HTTP request" - Kernel.exit(1) -end - -results = res.body.scan(/ 0 then - result = results[0].sub(/ +# License: This file is licensed under the GPL v2. +################################################################################ + +import getpass +import inspect +import optparse +import sys +from xmlrpc.client import ServerProxy + +# program defaults +DEFAULT_SERVER = "https://paste.grml.org/server.pl" + + +class ActionFailedException(Exception): + """Thrown if server returned an error""" + + def __init__(self, errormsg, ret): + Exception.__init__(self, errormsg, ret) + + def what(self): + """Get errormessage""" + return self.args[0] + + def dwhat(self): + """Get more verbose errormessage""" + return self.args[1] + + +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 -> action_add_paste +# a -> action_add_paste +actions = {} + +# option parser +OPT_PARSER = None + + +## +# MAIN +## +if __name__ == "__main__": + 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 (action_name, v) in actions_r.items(): + for i in v: + 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 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") + elif args[0] in actions: + cmd = args.pop(0) + action = actions[cmd] + try: + (msg, ret) = globals()[action](opts, args) + if opts.verbose == 0: + print(msg) + else: + 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])