cloud-backup 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 kazuyoshi tlacaelel
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ = cloud-backup
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 kazuyoshi tlacaelel. See LICENSE for details.
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cloud-backup"
8
+ gem.summary = %Q{Backup to multiple cloud storage engines easily!}
9
+ gem.description = %Q{Backup to different clouds or create a driver and extend functionality!}
10
+ gem.email = "kazu.dev@gmail.com"
11
+ gem.homepage = "http://github.com/ktlacaelel/cloud-backup"
12
+ gem.authors = ["kazuyoshi tlacaelel"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "cloud-backup #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cloud-backup}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["kazuyoshi tlacaelel"]
12
+ s.date = %q{2010-07-14}
13
+ s.description = %q{Backup to different clouds or create a driver and extend functionality!}
14
+ s.email = %q{kazu.dev@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "cloud-backup.gemspec",
27
+ "lib/cloud-backup.rb",
28
+ "lib/driver.rb",
29
+ "lib/driver_stack.rb",
30
+ "lib/drivers/log_backup_driver.rb",
31
+ "lib/drivers/rack_cloud_backup_driver.rb",
32
+ "lib/error.rb",
33
+ "test/helper.rb",
34
+ "test/test_cloud-backup.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/ktlacaelel/cloud-backup}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{Backup to multiple cloud storage engines easily!}
41
+ s.test_files = [
42
+ "test/helper.rb",
43
+ "test/test_cloud-backup.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
52
+ else
53
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
54
+ end
55
+ else
56
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
57
+ end
58
+ end
59
+
@@ -0,0 +1,15 @@
1
+
2
+ # External but loaded from drivers
3
+ #
4
+ # - 'cloudfiles'
5
+
6
+
7
+ # Internal.
8
+ require 'driver'
9
+ require 'driver_stack'
10
+ require 'error'
11
+
12
+ # TODO: Create some sort of factory for drivers
13
+ require 'drivers/log_backup_driver'
14
+ require 'drivers/rack_cloud_backup_driver'
15
+
@@ -0,0 +1,120 @@
1
+ module CloudBackup
2
+
3
+ # Abstract driver for cloud-backups.
4
+ #
5
+ # This class is thought as an interface, it encapsulates the
6
+ # abstract logic of a backup and let's child-classes *drivers*
7
+ # implement the details of how to communicate to a specific storage
8
+ # engine.
9
+ #
10
+ class Driver
11
+
12
+ # Driver Initializer
13
+ #
14
+ # Each driver will probably have different parameters, api-keys
15
+ # authentication methods etc.
16
+ #
17
+ # Thus, initialization must be handled/implemented by child classes
18
+ #
19
+ def initialize
20
+ raise Error.must_define :initialize
21
+ end
22
+
23
+ # Initiate backup
24
+ #
25
+ # This callback is reserved to initiate server connections or
26
+ # specific per-driver initialization.
27
+ #
28
+ def initiate
29
+ raise Error.must_define :initiate
30
+ end
31
+
32
+ # Driver Identificator
33
+ #
34
+ # Specifies the *identificator* where the resources will be
35
+ # installed.
36
+ #
37
+ # For example: If you are storing data into Google-Storage, or
38
+ # S3 this could be a bucket-name.
39
+ #
40
+ # Note: each driver may specify different types of identificators
41
+ # or implement it's own methods depending on the storage-engine
42
+ # that is being used.
43
+ #
44
+ def identificator
45
+ raise Error.must_define :identificator
46
+ end
47
+
48
+ # Identificator changer
49
+ #
50
+ # Allows the client to change the identificator
51
+ #
52
+ def identificator name
53
+ raise Error.must_define :identificator=
54
+ end
55
+
56
+ # File aggregator
57
+ #
58
+ # Adds a file to be backed up by the driver, path might be an
59
+ # *absolute* or *relative* depending on how you are running your
60
+ # script.
61
+ #
62
+ # *absolute* paths are recommendend
63
+ #
64
+ def add_file path
65
+ @files ||= []
66
+ @files << path
67
+ end
68
+
69
+ # Uncommited files
70
+ #
71
+ # Returns a list of files that have not been backed up, but were
72
+ # passed by the *add_file* method. to be backed-up!
73
+ #
74
+ def list
75
+ @files ||= []
76
+ end
77
+
78
+ # Lists backed-up files ordered by date.
79
+ #
80
+ # Must return a list of all files that exist in the *Remote-Storage-Engine*
81
+ # as an array, ordered by date!
82
+ #
83
+ # Note: (FIFO)
84
+ #
85
+ def list_by_date
86
+ raise Error.must_define :list_by_date
87
+ end
88
+
89
+ # Remote resource remover
90
+ #
91
+ # Deletes a remote resource, normally this is thought to remove
92
+ # resources after new ones are beinng added
93
+ #
94
+ def remove name
95
+ raise Error.must_define :remove
96
+ end
97
+
98
+ # File uploader.
99
+ #
100
+ # Uploads all files that were added to the *queue*
101
+ #
102
+ def upload
103
+ raise Error.must_define :upload
104
+ end
105
+
106
+ # Termination callback
107
+ #
108
+ # This method is called after all other methods are called, right
109
+ # before terminating execution. You might wana use this to close
110
+ # connections to remote servers.
111
+ #
112
+ # Also. Good for notifications!
113
+ #
114
+ def terminate
115
+ raise Error.must_define :terminate
116
+ end
117
+
118
+ end
119
+
120
+ end
@@ -0,0 +1,80 @@
1
+ module CloudBackup
2
+
3
+ class DriverStack
4
+
5
+ attr_accessor :max_items
6
+
7
+ def initialize
8
+ @list = []
9
+ @max_items = 2
10
+ @file_names = []
11
+ end
12
+
13
+ def list
14
+ @list
15
+ end
16
+
17
+ def addable? driver
18
+ driver.is_a? CloudBackup::Driver
19
+ end
20
+
21
+ def add_driver konstant
22
+ @list << konstant
23
+ end
24
+
25
+ def add_file name
26
+ @file_names << name
27
+ end
28
+
29
+ def add_files array
30
+ @file_names = @file_names + array
31
+ end
32
+
33
+ def perform_backup!
34
+ driver_initiate
35
+ driver_add_files
36
+ driver_upload_files
37
+ driver_remove_old_files
38
+ driver_shut_down_execution
39
+ end
40
+
41
+ def driver_initiate
42
+ @list.each do |driver|
43
+ driver.initiate
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def driver_add_files
50
+ @list.each do |driver|
51
+ @file_names.each do |file_name|
52
+ driver.add_file file_name
53
+ end
54
+ end
55
+ end
56
+
57
+ def driver_upload_files
58
+ @list.each do |driver|
59
+ driver.upload
60
+ end
61
+ end
62
+
63
+ def driver_remove_old_files
64
+ @list.each do |driver|
65
+ names = driver.list_by_date
66
+ (names - names.first(@max_items)).each do |name|
67
+ driver.remove name
68
+ end
69
+ end
70
+ end
71
+
72
+ def driver_shut_down_execution
73
+ @list.each do |driver|
74
+ driver.terminate
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,48 @@
1
+ class LogBackupDriver < CloudBackup::Driver
2
+
3
+ def initialize stream
4
+ @stream = stream
5
+ end
6
+
7
+ def initiate
8
+ output 'Initiating execution'
9
+ end
10
+
11
+ def identificator
12
+ @identificator
13
+ end
14
+
15
+ def identificator= name
16
+ @identificator = name
17
+ end
18
+
19
+ def list_by_date
20
+ output 'Listing driver items by date'
21
+ list.each do |file|
22
+ output "Listing.. file: #{file}"
23
+ end
24
+ @list ||= list
25
+ end
26
+
27
+ def remove name
28
+ @list = @list - [name]
29
+ output "Removing item: #{name}"
30
+ end
31
+
32
+ def upload
33
+ list.each do |file|
34
+ output "Uploading.. file: #{file}"
35
+ end
36
+ end
37
+
38
+ def terminate
39
+ output 'Terminating execution'
40
+ end
41
+
42
+ private
43
+
44
+ def output data
45
+ @stream.puts data
46
+ end
47
+
48
+ end
@@ -0,0 +1,53 @@
1
+ require 'cloudfiles'
2
+
3
+ class RackCloudBackupDriver < CloudBackup::Driver
4
+
5
+ def initialize credentials
6
+ @id = credentials[:id]
7
+ @key = credentials[:key]
8
+ @cf = CloudFiles::Connection.new(@id, @key)
9
+ end
10
+
11
+ def initiate
12
+ @bucket = get_or_create_bucket
13
+ end
14
+
15
+ def identificator
16
+ @identificator
17
+ end
18
+
19
+ def identificator= name
20
+ @identificator = name
21
+ end
22
+
23
+ # TODO: parse metadata
24
+ def list_by_date
25
+ @bucket.objects
26
+ end
27
+
28
+ def remove name
29
+ @bucket.delete_object name
30
+ end
31
+
32
+ # TODO: set metadata to objects
33
+ def upload
34
+ list.each do |file|
35
+ object = @bucket.create_object File.basename(file)
36
+ object.write File.read(file)
37
+ end
38
+ end
39
+
40
+ def terminate
41
+ @cf, @bucket = nil
42
+ end
43
+
44
+ private
45
+
46
+ def get_or_create_bucket
47
+ unless @cf.containers.include? identificator
48
+ @cf.create_container identificator
49
+ end
50
+ @cf.container identificator
51
+ end
52
+
53
+ end
@@ -0,0 +1,18 @@
1
+ module CloudBackup
2
+
3
+ class Error < Exception
4
+ end
5
+
6
+ class << Error
7
+
8
+ def must_define(method)
9
+ new "You must define a (#{method}) method in your driver class."
10
+ end
11
+
12
+ def invalid_identificator
13
+ new 'Invalid identificator.'
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'cloud-backup'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestCloudBackup < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloud-backup
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - kazuyoshi tlacaelel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-14 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Backup to different clouds or create a driver and extend functionality!
36
+ email: kazu.dev@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - cloud-backup.gemspec
52
+ - lib/cloud-backup.rb
53
+ - lib/driver.rb
54
+ - lib/driver_stack.rb
55
+ - lib/drivers/log_backup_driver.rb
56
+ - lib/drivers/rack_cloud_backup_driver.rb
57
+ - lib/error.rb
58
+ - test/helper.rb
59
+ - test/test_cloud-backup.rb
60
+ has_rdoc: true
61
+ homepage: http://github.com/ktlacaelel/cloud-backup
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: 3
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.7
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Backup to multiple cloud storage engines easily!
94
+ test_files:
95
+ - test/helper.rb
96
+ - test/test_cloud-backup.rb