Source

pybuckets / src / pybuckets / botos3.py

Full commit
from boto.exception import S3CreateError
from boto.s3.bucket import Bucket as BotoBucket
from boto.s3.connection import S3Connection
from boto.s3.key import Key
from .pybuckets import Bucket, BucketServer, DuplicateBucketNameException, \
    BucketsException, server_registry
from .pybuckets import build_kw_from_params_and_object
import operator

# S3CreateError - body, box_usage, bucket, error_code, error_message,message,reason,request_id,status

class BotoS3BucketIterator(object):
    def __init__(self,sequence):
        self.iter = sequence.__iter__()
    def __next__(self):
        return next(self.iter)
    
class BotoValueWrapper(object):
    def __init__(self,botokey):
        self.botokey = botokey
    def __rshift__(self,target):
        if isinstance(target,str) :
            self.botokey.get_contents_to_filename(target)
        elif hasattr(target,'write') :
            self.botokey.get_contents_to_file(target)
        else :
            raise Exception('invalid destination')
    def __lshift__(self,source):
        if isinstance(source,str) :
            self.botokey.set_contents_from_filename(source)
        elif hasattr(source,'read') :
            self.botokey.set_contents_from_file(source)
        else :
            raise Exception('invalid source')
        
class BotoS3Bucket(Bucket):
    def __init__(self,name,server):
        self.name = name
        self.server = server
        if self.server :
            self.s3bucket = BotoBucket(self.server.connection,self.name)
        else :
            self.s3bucket = None
    
    def __iter__(self):
        return BotoS3BucketIterator(list(self.keys()))
    
    def __str__(self):
        return 'BotoS3Bucket(%s,%s)' % (self.name, str(self.server))
    
    def keys(self):
        return list(map(operator.attrgetter('name'),self.s3bucket.get_all_keys()))
        
    def __call__(self,key):
        k = Key(self.s3bucket)
        k.key = key
        return BotoValueWrapper(k)

    def get_data(self,name):
        k = Key(self.s3bucket)
        k.key = name
        return k.get_contents_as_string()
    
    def set_data(self,name,value):
        k = Key(self.s3bucket)
        k.key = name
        return k.set_contents_from_string(value)
    
    def delete_key(self,name):
        k = Key(self.s3bucket)
        k.key = name
        k.delete()

class BotoS3Server(BucketServer):
    def __init__(self,**config):
        super(BotoS3Server,self).__init__(('aws_access_key_id','aws_secret_access_key','host','port','is_secure', 'debug','calling_format','headers','location','policy'),**config)
        
        self.connection = S3Connection(
                    **build_kw_from_params_and_object({},self,
                        ('aws_access_key_id','aws_secret_access_key','host','port','is_secure', 'debug','calling_format')))
        
    def keys(self):
        return list(map(operator.attrgetter('name'),self.connection.get_all_buckets()))
    
    def get(self,name):
        return BotoS3Bucket(name,self)
    
    def create_bucket(self,name,**kwargs):
        try :
            bucket = self.connection.create_bucket(name,
                                **build_kw_from_params_and_object(kwargs,self,('headers','location','policy'))
                            )
            return self.create_using_boto_bucket(bucket)
        except S3CreateError as s3e :
            if s3e.error_code == 'BucketAlreadyExists' :
                raise DuplicateBucketNameException(s3e,s3e.bucket)
            else :
                raise BucketsException(s3e)
        except Exception as e:
            raise BucketsException(e)
    def __str__(self):
        return 'BotoS3Server(%s)' % self.key
            
    def create_using_boto_bucket(self,boto_bucket):
        bucket = BotoS3Bucket(boto_bucket.name,self)
        return bucket

server_registry['botos3'] = BotoS3Server