cloudsync 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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