#http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
#   Submitter: Wade Leftwich
# Licensing:
#   according to http://aspn.activestate.com/ASPN/Cookbook/Python
#   "Except where otherwise noted, recipes in the Python Cookbook are published under the Python license ."
#   This recipe is covered under the Python license: http://www.python.org/license

import httplib, mimetypes, urllib2
from socket import error, herror, gaierror, timeout

def link_exists(host, selector):
    """
    Check to see if the given host exists and is reachable
    """
    try:
      site = urllib2.urlopen("http://" + host + selector)
      meta = site.info()
    except urllib2.URLError, e:
      print "FAIL: graph server does not resolve" 
      print "FAIL: " + str(e.reason)
      return 0
    return 1

def post_multipart(host, selector, fields, files):
    """
    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.
    """
    try:
      content_type, body = encode_multipart_formdata(fields, files)
      h = httplib.HTTP(host)
      h.putrequest('POST', selector)
      h.putheader('content-type', content_type)
      h.putheader('content-length', str(len(body)))
      h.endheaders()
      h.send(body)
      errcode, errmsg, headers = h.getreply()
      return h.file.read()
    except (httplib.HTTPException, error, herror, gaierror, timeout), e:
      print "FAIL: graph server unreachable"
      print "FAIL: " + str(e)
      raise
    except:
      print "FAIL: graph server unreachable"
      raise

def encode_multipart_formdata(fields, files):
    """
    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 = '----------ThIs_Is_tHe_bouNdaRY_$'
    CRLF = '\r\n'
    L = []
    for (key, value) in fields:
        L.append('--' + BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"' % key)
        L.append('')
        L.append(value)
    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'
