cloudsync 2.2.1 → 2.3.0

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.
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  gem.homepage = "http://github.com/megaphone/cloudsync"
12
12
  gem.authors = ["Cory Forsyth"]
13
13
  gem.add_dependency "right_aws", "~> 2.0.0"
14
- gem.add_dependency "cloudfiles", "~> 1.4.8"
14
+ gem.add_dependency "cloudfiles", "~> 1.4.9"
15
15
  gem.add_dependency "commander", "~> 4.0.3"
16
16
  gem.add_dependency "net-ssh", "~> 2.0.19"
17
17
  gem.add_dependency "net-sftp", "~> 2.0.4"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.1
1
+ 2.3.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{cloudsync}
8
- s.version = "2.2.1"
8
+ s.version = "2.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cory Forsyth"]
12
- s.date = %q{2010-10-15}
12
+ s.date = %q{2010-10-20}
13
13
  s.default_executable = %q{cloudsync}
14
14
  s.description = %q{Sync files between various clouds or sftp servers. Available backends are S3, CloudFiles, and SFTP servers. Can sync, mirror, and prune.}
15
15
  s.email = %q{cory.forsyth@gmail.com}
@@ -53,14 +53,14 @@ Gem::Specification.new do |s|
53
53
 
54
54
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
55
55
  s.add_runtime_dependency(%q<right_aws>, ["~> 2.0.0"])
56
- s.add_runtime_dependency(%q<cloudfiles>, ["~> 1.4.8"])
56
+ s.add_runtime_dependency(%q<cloudfiles>, ["~> 1.4.9"])
57
57
  s.add_runtime_dependency(%q<commander>, ["~> 4.0.3"])
58
58
  s.add_runtime_dependency(%q<net-ssh>, ["~> 2.0.19"])
59
59
  s.add_runtime_dependency(%q<net-sftp>, ["~> 2.0.4"])
60
60
  s.add_runtime_dependency(%q<escape>, ["~> 0.0.4"])
61
61
  else
62
62
  s.add_dependency(%q<right_aws>, ["~> 2.0.0"])
63
- s.add_dependency(%q<cloudfiles>, ["~> 1.4.8"])
63
+ s.add_dependency(%q<cloudfiles>, ["~> 1.4.9"])
64
64
  s.add_dependency(%q<commander>, ["~> 4.0.3"])
65
65
  s.add_dependency(%q<net-ssh>, ["~> 2.0.19"])
66
66
  s.add_dependency(%q<net-sftp>, ["~> 2.0.4"])
@@ -68,7 +68,7 @@ Gem::Specification.new do |s|
68
68
  end
69
69
  else
70
70
  s.add_dependency(%q<right_aws>, ["~> 2.0.0"])
71
- s.add_dependency(%q<cloudfiles>, ["~> 1.4.8"])
71
+ s.add_dependency(%q<cloudfiles>, ["~> 1.4.9"])
72
72
  s.add_dependency(%q<commander>, ["~> 4.0.3"])
73
73
  s.add_dependency(%q<net-ssh>, ["~> 2.0.19"])
74
74
  s.add_dependency(%q<net-sftp>, ["~> 2.0.4"])
@@ -3,6 +3,10 @@ require 'tempfile'
3
3
  module Cloudsync
4
4
  module Backend
5
5
  class Base
6
+ OBJECT_LIMIT = 250
7
+ CONTAINER_LIMIT = 250
8
+ BUCKET_LIMIT = CONTAINER_LIMIT
9
+
6
10
  attr_accessor :store, :sync_manager, :name, :upload_prefix
7
11
 
8
12
  def initialize(opts = {})
@@ -80,6 +84,13 @@ module Cloudsync
80
84
 
81
85
  private
82
86
 
87
+ def remove_container_name(string)
88
+ parts = string.split("/")
89
+ parts.shift
90
+ parts.join("/")
91
+ end
92
+ alias :remove_bucket_name :remove_container_name
93
+
83
94
  def dry_run?
84
95
  return false unless @sync_manager
85
96
  @sync_manager.dry_run?
@@ -42,12 +42,13 @@ module Cloudsync
42
42
  $LOGGER.debug("Finished putting #{file} to #{self} (#{Time.now - start_time}s)")
43
43
  end
44
44
 
45
- def files_to_sync(upload_prefix={})
45
+ def files_to_sync(upload_prefix="")
46
46
  $LOGGER.info("Getting files to sync [#{self}]")
47
-
48
- containers_to_sync(upload_prefix).inject([]) do |files, container|
47
+
48
+ files = []
49
+ containers_to_sync(upload_prefix) do |container|
49
50
  container = get_or_create_container(container)
50
- objects_from_container(container, upload_prefix).each do |path, hash|
51
+ objects_from_container(container, remove_container_name(upload_prefix)) do |path, hash|
51
52
  next if hash[:content_type] == "application/directory"
52
53
 
53
54
  file = Cloudsync::File.from_cf_info(container, path, hash, self.to_s)
@@ -96,27 +97,56 @@ module Cloudsync
96
97
  end
97
98
 
98
99
  def containers_to_sync(upload_prefix)
99
- upload_prefix[:bucket] ? [upload_prefix[:bucket]] : @store.containers
100
+ container_name = upload_prefix.split("/").first
101
+ if container_name
102
+ yield container_name
103
+ else
104
+ last_marker = nil
105
+ loop do
106
+ containers = @store.containers(CONTAINER_LIMIT, last_marker)
107
+ break if containers.empty?
108
+ containers.each do |container|
109
+ last_marker = container
110
+ yield container
111
+ end
112
+ end
113
+ end
100
114
  end
101
115
 
102
- def objects_from_container(container, upload_prefix)
103
- $LOGGER.debug("Getting files from #{container.name}")
104
-
105
- objects = []
106
- if upload_prefix[:prefix]
107
- container.objects_detail(:path => upload_prefix[:prefix]).collect do |path, hash|
108
- if hash[:content_type] == "application/directory"
109
- objects += objects_from_container(container, :prefix => path)
110
- else
111
- objects << [path, hash]
116
+ # cf = Cloudsync::Backend::CloudFiles.new( YAML::load_file("cloudsync.yml")[:cloudfiles]); $LOGGER = Logger.new(STDOUT); count = 0; cf.files_to_sync {|p,h| count += 1 }; puts count
117
+ # cf = Cloudsync::Backend::CloudFiles.new( YAML::load_file("cloudsync.yml")[:cloudfiles]); $LOGGER = Logger.new(STDOUT); count = 0; paths = []; cf.files_to_sync("mpsounds-adobe.max.trivia") {|f| count += 1; paths << f.path}; puts count
118
+
119
+
120
+ # prefix_path must not include the container name at the beginning of the string
121
+ def objects_from_container(container, prefix_path="", &block)
122
+ $LOGGER.debug("Getting files from #{container.name} (prefix: #{prefix_path})")
123
+
124
+ last_marker = nil
125
+ loop do
126
+ params = {:limit => OBJECT_LIMIT, :marker => last_marker}
127
+ params[:path] = prefix_path if !prefix_path.empty?
128
+
129
+ $LOGGER.debug("OFC #{container.name} (#{prefix_path}) loop: #{params.inspect}")
130
+
131
+ objects_details = container.objects_detail(params)
132
+
133
+ $LOGGER.debug("OFC #{container.name} (#{prefix_path}) got #{objects_details.size}. #{objects_details.class}")
134
+ $LOGGER.debug("-"*50)
135
+
136
+ break if objects_details.empty?
137
+
138
+ objects_details.sort.each do |path, hash|
139
+ if hash[:content_type] == "application/directory" && !prefix_path.empty?
140
+ $LOGGER.debug("OFC #{container.name} (#{prefix_path}) recursing into #{path}")
141
+ objects_from_container(container, path, &block)
142
+ $LOGGER.debug("OFC #{container.name} (#{prefix_path}) done recursing into #{path}")
112
143
  end
144
+
145
+ last_marker = path
146
+ yield path, hash
113
147
  end
114
- else
115
- objects = container.objects_detail
116
148
  end
117
- objects
118
149
  end
119
-
120
150
 
121
151
  def get_obj_from_store(file)
122
152
  @store.container(file.bucket).object(file.upload_path)
@@ -72,7 +72,7 @@ module Cloudsync
72
72
  $LOGGER.info("Getting files to sync [#{self}]")
73
73
 
74
74
  buckets_to_sync(upload_prefix).inject([]) do |files, bucket|
75
- objects_from_bucket(bucket, upload_prefix).collect do |key|
75
+ objects_from_bucket(bucket, upload_prefix) do |key|
76
76
  file = Cloudsync::File.from_s3_obj(key, self.to_s)
77
77
  if block_given?
78
78
  yield file
@@ -90,6 +90,9 @@ module Cloudsync
90
90
  end
91
91
 
92
92
  private
93
+
94
+ # cf = Cloudsync::Backend::S3.new( YAML::load_file("cloudsync.yml")[:s3]); $LOGGER = Logger.new(STDOUT); count = 0; cf.files_to_sync {|p,h| count += 1 }; puts count
95
+
93
96
 
94
97
  def buckets_to_sync(upload_prefix="")
95
98
  bucket_name = upload_prefix.split("/").first
@@ -103,14 +106,21 @@ module Cloudsync
103
106
  def objects_from_bucket(bucket, upload_prefix="")
104
107
  $LOGGER.debug("Getting files from #{bucket}")
105
108
 
106
- prefix_parts = upload_prefix.split("/")
107
- prefix_parts.shift
108
- prefix = prefix_parts.join("/")
109
+ prefix = remove_bucket_name(upload_prefix)
110
+ params = {'marker' => "", 'max-keys' => OBJECT_LIMIT}
111
+ params['prefix'] = prefix if !prefix.nil?
109
112
 
110
- if !prefix.empty?
111
- bucket.keys(:prefix => prefix)
112
- else
113
- bucket.keys
113
+ loop do
114
+ $LOGGER.debug(params.inspect)
115
+ keys = bucket.keys(params)
116
+ break if keys.empty?
117
+
118
+ keys.each do |key|
119
+ $LOGGER.debug(key.name)
120
+ yield key
121
+ end
122
+
123
+ params['marker'] = keys.last.name
114
124
  end
115
125
  end
116
126
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudsync
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 2
9
- - 1
10
- version: 2.2.1
8
+ - 3
9
+ - 0
10
+ version: 2.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Cory Forsyth
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-15 00:00:00 -04:00
18
+ date: 2010-10-20 00:00:00 -04:00
19
19
  default_executable: cloudsync
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -42,12 +42,12 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- hash: 23
45
+ hash: 21
46
46
  segments:
47
47
  - 1
48
48
  - 4
49
- - 8
50
- version: 1.4.8
49
+ - 9
50
+ version: 1.4.9
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency