# -*- coding: utf-8 -*-

# http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/

import http.client
import mimetypes
import uuid


def post_multipart(host, selector, fields, files, charset="UTF-8"):
    """Post fields and files to an http host as multipart/form-data.
    fields is a sequence of (name, value) elements for regular form fields.
    files is a sequence of (name, filename, value) elements for data to be uploaded as files
    Return the server's response page.
    """
    content_type, body = encode_multipart_formdata(fields, files, charset)
    h = http.client.HTTPConnection(host)
    h.putrequest("POST", selector)
    h.putheader("Content-Type", content_type)
    h.putheader("Content-Length", str(len(body)))
    h.endheaders()
    h.send(body)
    resp = h.getresponse()
    return resp.read()


def encode_multipart_formdata(fields, files, charset="UTF-8"):
    """fields is a sequence of (name, value) elements for regular form fields.
    files is a sequence of (name, filename, value) elements for data to be uploaded as files
    Return (content_type, body) ready for httplib.HTTP instance
    """
    BOUNDARY = "----=_NextPart_%s" % uuid.uuid1()
    CRLF = "\r\n"
    L = []
    for (key, value) in fields:
        L.append("--" + BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"' % key)
        L.append("Content-Type: text/plain; charset=%s" % charset)
        L.append("")
        L.append(value.encode(charset))
    for (key, filename, value) in files:
        L.append("--" + BOUNDARY)
        L.append(
            'Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)
        )
        L.append("Content-Type: %s" % get_content_type(filename))
        L.append("")
        L.append(value)
    L.append("--" + BOUNDARY + "--")
    L.append("")
    body = CRLF.join(L)
    content_type = "multipart/form-data; boundary=%s" % BOUNDARY
    return content_type, body


def get_content_type(filename):
    return mimetypes.guess_type(filename)[0] or "application/octet-stream"
