~ubuntu-branches/ubuntu/wily/simplestreams/wily

« back to all changes in this revision

Viewing changes to simplestreams/objectstores/s3.py

  • Committer: Package Import Robot
  • Author(s): Scott Moser
  • Date: 2013-03-26 01:10:01 UTC
  • Revision ID: package-import@ubuntu.com-20130326011001-342bcgb65worw4r8
Tags: upstream-0.1.0~bzr191
ImportĀ upstreamĀ versionĀ 0.1.0~bzr191

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import boto.exception
 
2
import boto.s3
 
3
import boto.s3.connection
 
4
from contextlib import closing
 
5
import errno
 
6
import tempfile
 
7
 
 
8
import simplestreams.objectstores as objectstores
 
9
import simplestreams.contentsource as cs
 
10
 
 
11
class S3ObjectStore(objectstores.ObjectStore):
 
12
 
 
13
    _bucket = None
 
14
    _connection = None
 
15
 
 
16
    def __init__(self, prefix):
 
17
        # expect 's3://bucket/path_prefix'
 
18
        self.prefix = prefix
 
19
        if prefix.startswith("s3://"):
 
20
            path = prefix[5:]
 
21
        else:
 
22
            path = prefix
 
23
 
 
24
        (self.bucketname, self.path_prefix) = path.split("/", 1)
 
25
 
 
26
    @property
 
27
    def _conn(self):
 
28
        if not self._connection:
 
29
            self._connection = boto.s3.connection.S3Connection()
 
30
 
 
31
        return self._connection
 
32
 
 
33
    @property
 
34
    def bucket(self):
 
35
        if not self._bucket:
 
36
            self._bucket = self._conn.get_bucket(self.bucketname)
 
37
        return self._bucket
 
38
 
 
39
    def insert(self, path, reader, checksums=None, mutable=True):
 
40
        #store content from reader.read() into path, expecting result checksum
 
41
        try:
 
42
            tfile = tempfile.TemporaryFile()
 
43
            with reader(path) as rfp:
 
44
                while True:
 
45
                    buf = rfp.read(self.read_size)
 
46
                    tfile.write(buf)
 
47
                    if len(buf) != self.read_size:
 
48
                        break
 
49
            with closing(self.bucket.new_key(self.path_prefix + path)) as key:
 
50
                key.set_contents_from_file(tfile)
 
51
        finally:
 
52
            tfile.close()
 
53
 
 
54
    def insert_content(self, path, content, checksums=None):
 
55
        with closing(self.bucket.new_key(self.path_prefix + path)) as key:
 
56
            key.set_contents_from_string(content)
 
57
 
 
58
    def remove(self, path):
 
59
        #remove path from store
 
60
        self.bucket.delete_key(self.path_prefix + path)
 
61
 
 
62
    def reader(self, path):
 
63
        # essentially return an 'open(path, r)'
 
64
        key = self.bucket.get_key(self.path_prefix + path)
 
65
        if not key:
 
66
            myerr = IOError("Unable to open %s" % path)
 
67
            myerr.errno = errno.ENOENT
 
68
            raise myerr
 
69
 
 
70
        return cs.FdContentSource(fd=key, url=self.path_prefix + path)
 
71
 
 
72
    def exists_with_checksum(self, path, checksums=None):
 
73
        key = self.bucket.get_key(self.path_prefix + path)
 
74
        if key is None:
 
75
            return False
 
76
 
 
77
        if 'md5' in checksums:
 
78
            return checksums['md5'] == key.etag.replace('"', "")
 
79
 
 
80
        return False
 
81
 
 
82
 
 
83
# vi: ts=4 expandtab