# $Id$ ############################################################################# # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################## import time import os import md5 import mimetypes class SyncItem(object): default_mimetype = 'application/octet-stream' def __init__(self, key): ''' >>> key = 'S3ObjectName' >>> item = SyncItem(key) >>> item.key == key True ''' self.key = key self._s3 = None self._path = None self._size = None self._md5 = None def get_mimetype(self): ''' >>> item = SyncItem('hoge') >>> item.get_mimetype() 'application/octet-stream' >>> item = SyncItem('s3syncitem.py') >>> item.get_mimetype() 'text/x-python' >>> item.set_localpath('/') >>> item.get_mimetype() 'application/octet-stream' ''' if self.is_dir(): return self.default_mimetype return mimetypes.guess_type(self.key)[0] or self.default_mimetype def set_localpath(self, localpath): ''' see get_localpath() method. ''' self._path = localpath if self.is_dir(): self._size = 10 # dummy! else: # need refactoring for huge file reading... filedata = file(localpath, 'rb').read() self._size = len(filedata) self._md5 = md5.new(filedata).hexdigest() def get_localpath(self): ''' >>> item = SyncItem('s3syncitem.py') >>> item.get_localpath() == None True >>> item.set_localpath(__file__) >>> item.get_localpath() == __file__ True ''' return self._path def get_size(self): ''' >>> item = SyncItem('s3syncitem.py') >>> item.set_localpath(__file__) >>> bool(item.get_size()) True ''' return self._size def set_s3object(self, s3): self._s3 = s3 def is_local_exist(self): ''' return bool value if local file is exist. >>> key = 'hoge' >>> item = SyncItem(key) >>> item.is_local_exist() False ''' return self._path and True or False def is_dir(self): ''' return bool value if local filepath is directory. >>> item = SyncItem('/') >>> item.set_localpath(os.sep) >>> item.is_dir() True >>> item.set_localpath(__file__) >>> item.is_dir() False ''' if self.is_local_exist(): return os.path.isdir(self._path) return False def is_changed(self): ''' if SyncItem have only local DIR, status is 'changed'. >>> item = SyncItem('.') >>> item.set_localpath('.') >>> item.is_changed() True if SyncItem have local DIR and S3Object, status is 'not changed'. >>> item.set_s3object('Dummy') >>> item.is_changed() False if SyncItem have only local FILE, status is 'changed'. >>> item = SyncItem('s3syncitem.py') >>> item.set_localpath(__file__) >>> item.is_changed() True if SyncItem have local FILE and S3Object, compare MD5 value. >>> ''' if self.is_dir(): if self._s3 and self.is_local_exist(): return False else: if self._md5 and self._s3: mymd5 = self._md5.lower() s3md5 = str(self._s3.etag).strip('"').lower() return s3md5 != mymd5 return True class SyncResponse: def __init__(self, status, reason, elapse, size=None): self.status = status self.reason = reason self.elapse = elapse self.size = size if __name__ == '__main__': main()