diff --git a/etc/sample_rax_credentials.conf b/etc/sample_rax_credentials.conf new file mode 100644 index 0000000..f0d1564 --- /dev/null +++ b/etc/sample_rax_credentials.conf @@ -0,0 +1,3 @@ +[rackspace_cloud] +username = my_username +api_key = 01234567890abcdef diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4d10377 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +notigen +notification_utils +pyrax +python-dateutil +simport diff --git a/setup.cfg b/setup.cfg index cd30def..f11aca0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,7 +6,7 @@ summary = data archiving library description-file = README.md license = Apache-2 classifier = - Development Status :: 2 - Pre-Alpha + Development Status :: 5 - Production/Stable Environment :: Console Intended Audience :: Developers Intended Audience :: Information Technology @@ -14,9 +14,12 @@ classifier = Operating System :: OS Independent Programming Language :: Python Topic :: Software Development :: Libraries :: Python Modules +home-page = https://github.com/StackTach/shoebox keywords = - setup - distutils + json + archive + swift + openstack [files] packages = - shoebox \ No newline at end of file + shoebox diff --git a/shoebox/handlers.py b/shoebox/handlers.py index c796615..5ad9de2 100644 --- a/shoebox/handlers.py +++ b/shoebox/handlers.py @@ -17,9 +17,15 @@ import os import os.path import shutil +import pyrax + import simport +class MissingArgument(Exception): + pass + + class ArchiveCallback(object): def __init__(self, **kwargs): pass @@ -29,8 +35,12 @@ class ArchiveCallback(object): pass def on_close(self, filename): - """Called when an Archive is closed.""" - pass + """Called when an Archive is closed. + If you move/change the file/name return the + new location so subsequent callbacks will + have the right location. + """ + return filename class CallbackList(ArchiveCallback): @@ -50,7 +60,7 @@ class CallbackList(ArchiveCallback): def on_close(self, filename): for c in self.callbacks: - c.on_close(filename) + filename = c.on_close(filename) class ChangeExtensionCallback(ArchiveCallback): @@ -60,7 +70,9 @@ class ChangeExtensionCallback(ArchiveCallback): self.new_extension = kwargs.get('new_extension', '.done') def on_close(self, filename): - os.rename(filename, "%s.%s" % (filename, self.new_extension)) + new = "%s.%s" % (filename, self.new_extension) + os.rename(filename, new) + return new class MoveFileCallback(ArchiveCallback): @@ -71,3 +83,37 @@ class MoveFileCallback(ArchiveCallback): def on_close(self, filename): """Move this file to destination folder.""" shutil.move(filename, self.destination_folder) + path, fn = os.path.split(filename) + return os.path.join(self.destination_folder, fn) + + +class DeleteFileCallback(ArchiveCallback): + def on_close(self, filename): + """Delete this file.""" + os.remove(filename) + return None + + +class SwiftUploadCallback(ArchiveCallback): + def __init__(self, **kwargs): + super(SwiftUploadCallback, self).__init__(**kwargs) + self.credentials_file = kwargs.get('credentials_file') + if not self.credentials_file: + raise MissingArgument("No credentials_file defined.") + + self.container = kwargs.get('container', 'shoebox') + self.auth_method = kwargs.get('auth_method', 'rackspace') + self.region = kwargs.get('region', 'DFW') + + pyrax.set_setting('identity_type', self.auth_method) + pyrax.set_setting("region", self.region) + pyrax.set_credential_file(self.credentials_file) + + self.cloud_files = pyrax.cloudfiles + + def on_close(self, filename): + checksum = pyrax.utils.get_checksum(filename) + # Blocking call ... + obj = self.cloud_files.upload_file(self.container, filename, + etag=checksum) + return filename diff --git a/tox.ini b/tox.ini index 93a052e..ca0ec80 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,7 @@ deps = mock notigen notification_utils + pyrax python-dateutil simport