Package flickrapi :: Module multipart
[hide private]
[frames] | no frames]

Source Code for Module flickrapi.multipart

  1  # -*- encoding: utf-8 -*- 
  2   
  3  '''Module for encoding data as form-data/multipart''' 
  4   
  5  import os 
  6  import base64 
  7   
  8   
9 -class Part(object):
10 11 '''A single part of the multipart data. 12 13 >>> Part({'name': 'headline'}, 'Nice Photo') 14 ... # doctest: +ELLIPSIS 15 <flickrapi.multipart.Part object at 0x...> 16 17 >>> image = open('tests/photo.jpg') 18 >>> Part({'name': 'photo', 'filename': image}, image.read(), 'image/jpeg') 19 ... # doctest: +ELLIPSIS 20 <flickrapi.multipart.Part object at 0x...> 21 ''' 22
23 - def __init__(self, parameters, payload, content_type=None):
24 self.content_type = content_type 25 self.parameters = parameters 26 self.payload = payload
27
28 - def render(self):
29 '''Renders this part -> List of Strings''' 30 31 parameters = ['%s="%s"' % (k, v) 32 for k, v in self.parameters.iteritems()] 33 34 lines = ['Content-Disposition: form-data; %s' % '; '.join(parameters)] 35 36 if self.content_type: 37 lines.append("Content-Type: %s" % self.content_type) 38 39 lines.append('') 40 41 if isinstance(self.payload, unicode): 42 lines.append(self.payload.encode('utf-8')) 43 else: 44 lines.append(self.payload) 45 46 return lines
47 48
49 -class FilePart(Part):
50 '''A single part with a file as the payload 51 52 This example has the same semantics as the second Part example: 53 54 >>> FilePart({'name': 'photo'}, 'tests/photo.jpg', 'image/jpeg') 55 ... #doctest: +ELLIPSIS 56 <flickrapi.multipart.FilePart object at 0x...> 57 ''' 58
59 - def __init__(self, parameters, filename, content_type):
60 parameters['filename'] = filename 61 62 imagefile = open(filename, 'rb') 63 payload = imagefile.read() 64 imagefile.close() 65 66 Part.__init__(self, parameters, payload, content_type)
67 68
69 -def boundary():
70 """Generate a random boundary, a bit like Python 2.5's uuid module.""" 71 72 bytes = os.urandom(16) 73 return base64.b64encode(bytes, 'ab').strip('=')
74 75
76 -class Multipart(object):
77 '''Container for multipart data''' 78
79 - def __init__(self):
80 '''Creates a new Multipart.''' 81 82 self.parts = [] 83 self.content_type = 'form-data/multipart' 84 self.boundary = boundary()
85
86 - def attach(self, part):
87 '''Attaches a part''' 88 89 self.parts.append(part)
90
91 - def __str__(self):
92 '''Renders the Multipart''' 93 94 lines = [] 95 for part in self.parts: 96 lines += ['--' + self.boundary] 97 lines += part.render() 98 lines += ['--' + self.boundary + "--"] 99 100 return '\r\n'.join(lines)
101
102 - def header(self):
103 '''Returns the top-level HTTP header of this multipart''' 104 105 return ("Content-Type", 106 "multipart/form-data; boundary=%s" % self.boundary)
107