#!/usr/bin/python
import sys, os

if sys.hexversion >= 0x3000000:
    import urllib.request as urlmod
    from urllib.parse import urlencode
else:
    import urllib2 as urlmod
    from urllib import urlencode

MDL = 1000000 * 2

class Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable

class MultipartPostHandler(urlmod.BaseHandler):
    handler_order = urlmod.HTTPHandler.handler_order - 10 # needs to run first

    def http_request(self, request):

        doseq = 1

        data = request.get_data()
        if data is not None and type(data) != str:
            v_files = []
            v_vars = []
            try:
                 for(key, value) in list(data.items()):
                     if hasattr(value, "fileno"):
                         v_files.append((key, value))
                     else:
                         v_vars.append((key, value))
            except TypeError:
                systype, value, traceback = sys.exc_info()
                raise TypeError("not a valid non-string sequence or mapping object").with_traceback(traceback)

            if len(v_files) == 0:
                data = urlencode(v_vars, doseq)
            else:
                boundary, data = self.multipart_encode(v_vars, v_files)

                contenttype = 'multipart/form-data; boundary=%s' % boundary
                request.add_unredirected_header('Content-Type', contenttype)
            request.add_data(data)
        return request

    def multipart_encode(vars, files, boundary = None, buf = None):

        from io import StringIO
        import mimetools, mimetypes

        if boundary is None:
            boundary = mimetools.choose_boundary()
        if buf is None:
            buf = StringIO()
        for(key, value) in vars:
            buf.write('--%s\r\n' % boundary)
            buf.write('Content-Disposition: form-data; name="%s"' % key)
            buf.write('\r\n\r\n' + value + '\r\n')
        for(key, fd) in files:
            file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
            filename = fd.name.split('/')[-1]
            contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
            buf.write('--%s\r\n' % boundary)
            buf.write('Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename))
            buf.write('Content-Type: %s\r\n' % contenttype)
            # buffer += 'Content-Length: %s\r\n' % file_size
            fd.seek(0)
            buf.write('\r\n' + fd.read() + '\r\n')
        buf.write('--' + boundary + '--\r\n\r\n')
        buf = buf.getvalue()
        return boundary, buf
    multipart_encode = Callable(multipart_encode)

    https_request = http_request

class PastieInterface:

    def __init__(self):
        self.url = 'http://pastebin.rogentos.ro/send'
        self.opener = urlmod.build_opener(MultipartPostHandler)
        self.generated = False
        self.params = {}

        mydict = {}
        if os.getenv('HTTP_PROXY'):
            mydict['http'] = os.getenv('HTTP_PROXY')
        if mydict:
            self.add_proxy_opener(urllib2,mydict)

    def add_proxy_opener(self, module, data):

        import types
        if type(module) != types.ModuleType:
            raise exceptionTools.InvalidDataType("InvalidDataType: not a module")
        if not data:
            return

        username = None
        password = None
        authinfo = None
        if 'password' in data:
            username = data.pop('username')
        if 'password' in data:
            username = data.pop('password')
        if username == None or password == None:
            username = None
            password = None
        else:
            passmgr = module.HTTPPasswordMgrWithDefaultRealm()
            if data['http']:
                passmgr.add_password(None, data['http'], username, password)
            if data['ftp']:
                passmgr.add_password(None, data['ftp'], username, password)
            authinfo = module.ProxyBasicAuthHandler(passmgr)

        proxy_support = module.ProxyHandler(data)
        if authinfo:
            opener = module.build_opener(proxy_support, authinfo)
        else:
            opener = module.build_opener(proxy_support)
        module.install_opener(opener)

    def submit(self, f_obj):

        data = f_obj.read()
        if len(data) > MDL:
            sys.stderr.write("Doge said that it can't handle it.\n")
            sys.stderr.write("%d bytes are way too much, "
                             "expecting at most %d bytes.\n" % (
                                 len(data), MDL,))
            raise SystemExit(1)
        self.params['pastebin_syntax_id'] = "-1"
        self.params['pastebin_doctypes_id'] = "-1"
        self.params['expiration_days'] = "-1"
        self.params['pastebin_permissions_id'] = "-1"
        self.params['pastie_content'] = data
        self.params['just_url'] = "1"
        if not data:
            return False
        result = self.opener.open(self.url, self.params).read()
        print(result.strip())
        return True

    def submit_as_file(self, f_obj):

        data = f_obj.read()
        if len(data) > MDL:
            raise SystemExit(1)
        self.params['pastebin_syntax_id'] = "-1"
        self.params['pastebin_doctypes_id'] = "-2"
        self.params['expiration_days'] = "-1"
        self.params['pastebin_permissions_id'] = "-1"
        self.params['pastie_content'] = data
        self.params['just_url'] = "1"
        if not data:
            return False
        result = self.opener.open(self.url, self.params).read()
        print(result.strip())
        return True

my = PastieInterface()
f_obj = sys.stdin
f_obj_diff = False
for arg in sys.argv[1:]:
    if os.access(arg, os.R_OK) and os.path.isfile(arg):
        f_obj = open(arg, "rb")
        f_obj_diff = True
        break

if "-f" in sys.argv:
    rc = my.submit_as_file(f_obj)
else:
    rc = my.submit(f_obj)

if f_obj_diff:
    f_obj.close()

if not rc:
    print("syntax error !")
    print("syntax:", sys.argv[0], "[-f] <path>")
    print("note: if <path> is not provided, stdin will be used")
    raise SystemExit(1)