Skip to content

Instantly share code, notes, and snippets.

@Kami
Created April 1, 2011 18:00
Show Gist options
  • Select an option

  • Save Kami/898566 to your computer and use it in GitHub Desktop.

Select an option

Save Kami/898566 to your computer and use it in GitHub Desktop.
import subprocess
from urlparse import urlparse, urlunparse
from httplib import HTTPException, HTTPSConnection
from urllib import quote as _quote, unquote
url='https://auth.api.rackspacecloud.com/v1.0'
def http_connection(url):
parsed = urlparse(url)
if parsed.scheme == 'http':
conn = HTTPConnection(parsed.netloc)
elif parsed.scheme == 'https':
conn = HTTPSConnection(parsed.netloc)
else:
raise ClientException('Cannot handle protocol scheme %s for url %s' %
(parsed.scheme, repr(url)))
return parsed, conn
def get_auth(url, user, key, snet=False):
parsed, conn = http_connection(url)
conn.request('GET', parsed.path, '',
{'X-Auth-User': user, 'X-Auth-Key': key})
resp = conn.getresponse()
resp.read()
if resp.status < 200 or resp.status >= 300:
raise ClientException('Auth GET failed', http_scheme=parsed.scheme,
http_host=conn.host, http_port=conn.port,
http_path=parsed.path, http_status=resp.status,
http_reason=resp.reason)
url = resp.getheader('x-storage-url')
if snet:
parsed = list(urlparse(url))
# Second item in the list is the netloc
parsed[1] = 'snet-' + parsed[1]
url = urlunparse(parsed)
return url, resp.getheader('x-storage-token',
resp.getheader('x-auth-token'))
def put_object(url, token, container, name, contents, content_length=None,
etag=None, chunk_size=65536, content_type=None, headers=None,
http_conn=None):
if http_conn:
parsed, conn = http_conn
else:
parsed, conn = http_connection(url)
path = '%s/%s/%s' % (parsed.path, quote(container), quote(name))
if not headers:
headers = {}
headers['X-Auth-Token'] = token
if etag:
headers['ETag'] = etag.strip('"')
if content_length is not None:
headers['Content-Length'] = str(content_length)
if content_type is not None:
headers['Content-Type'] = content_type
if not contents:
headers['Content-Length'] = '0'
if hasattr(contents, 'read'):
conn.putrequest('PUT', path)
for header, value in headers.iteritems():
conn.putheader(header, value)
if content_length is None:
conn.putheader('Transfer-Encoding', 'chunked')
conn.endheaders()
chunk = contents.read(chunk_size)
while chunk:
conn.send('%x\r\n%s\r\n' % (len(chunk), chunk))
chunk = contents.read(chunk_size)
conn.send('0\r\n\r\n')
else:
conn.endheaders()
left = content_length
while left > 0:
size = chunk_size
if size > left:
size = left
chunk = contents.read(size)
conn.send(chunk)
left -= len(chunk)
else:
conn.request('PUT', path, contents, headers)
resp = conn.getresponse()
resp.read()
if resp.status < 200 or resp.status >= 300:
raise ClientException('Object PUT failed', http_scheme=parsed.scheme,
http_host=conn.host, http_port=conn.port, http_path=path,
http_status=resp.status, http_reason=resp.reason)
return resp.getheader('etag').strip('"')
def quote(value, safe='/'):
if isinstance(value, unicode):
value = value.encode('utf8')
return _quote(value, safe)
class ClientException(Exception):
def __init__(self, msg, http_scheme='', http_host='', http_port='',
http_path='', http_query='', http_status=0, http_reason='',
http_device=''):
Exception.__init__(self, msg)
self.msg = msg
self.http_scheme = http_scheme
self.http_host = http_host
self.http_port = http_port
self.http_path = http_path
self.http_query = http_query
self.http_status = http_status
self.http_reason = http_reason
self.http_device = http_device
def __str__(self):
a = self.msg
b = ''
if self.http_scheme:
b += '%s://' % self.http_scheme
if self.http_host:
b += self.http_host
if self.http_port:
b += ':%s' % self.http_port
if self.http_path:
b += self.http_path
if self.http_query:
b += '?%s' % self.http_query
if self.http_status:
if b:
b = '%s %s' % (b, self.http_status)
else:
b = str(self.http_status)
if self.http_reason:
if b:
b = '%s %s' % (b, self.http_reason)
else:
b = '- %s' % self.http_reason
if self.http_device:
if b:
b = '%s: device %s' % (b, self.http_device)
else:
b = 'device %s' % self.http_device
return b and '%s: %s' % (a, b) or a
# All the defs above are for the put_object, they work.
class SizeLimitedFile(object):
def __init__(self, source, length):
self.source = source
self.length = length
def read(self, size):
if self.length <= 0:
print 'done'
return ""
to_read = min(size, self.length)
ret = self.source.read(to_read)
if len(ret) == 0:
self.length = 0
else:
self.length -= len(ret)
return ret
storage_url, key = get_auth('https://auth.api.rackspacecloud.com/v1.0','xxxxxxxxx','xxxxxxxxx',snet=False)
tarcmd = 'tar --use-compress-program=lzop -cvf - /home/crhodes/sandbox/outfile'
#cmd = ['/bin/tar --use-compress-program=lzop -cvf - /home/chrodes/sandbox/outfile']
pipe = subprocess.Popen(tarcmd,bufsize=0,shell = True,stdout = subprocess.PIPE)
#pipe = subprocess.Popen(tarcmd, stdout=subprocess.PIPE)
part_num = 0
returncode = pipe.poll()
while returncode is None:
src = SizeLimitedFile(pipe.stdout, 1024)
put_object(storage_url, key, 'cass_test_store', 'test_file-part-%d' % part_num, src)
part_num += 1
returncode = pipe.poll()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment