defog 0.3.0 → 0.3.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.
@@ -50,7 +50,7 @@ Open a proxy to a remote file by creating a <code>Defog::File</code> object:
50
50
  end
51
51
 
52
52
  <code>mode</code> can be "r", "r+", "w", "w+", "a", or "a+" with the usual
53
- semantics.
53
+ semantics, and can be suffixed with "b" or with ":" and encoding as usual.
54
54
 
55
55
  When opened in a readable mode ("r", "r+", "w+", "a+"), first caches the
56
56
  cloud file in the local proxy. When opened in a writeable mode ("r+", "w",
@@ -1,5 +1,6 @@
1
1
  module Defog
2
- # Create a Defog::File proxy instance via Defog::Proxy#file, such as
2
+ # Create a Defog::File proxy instance via Defog::Handle#open or via the
3
+ # shortcut from Defog::Proxy#file, such as
3
4
  #
4
5
  # defog = Defog::Proxy.new(:provider => :AWS, :aws_access_key_id => access_key, ...)
5
6
  #
@@ -28,8 +29,17 @@ module Defog
28
29
  #
29
30
  # (Note that the proxy file path has the same file extension as the cloud key string.)
30
31
  #
31
- # Upon closing the proxy file, in normal use the cloud storage gets synchronized and
32
- # the proxy deleted. See File#close for more details.
32
+ # Upon closing the proxy file, in normal use the cloud storage gets
33
+ # synchronized if needed and the proxy deleted. To prevent deletion, you
34
+ # can use:
35
+ # defog.file("key", "r", :persist => true)
36
+ # See File#close for more details.
37
+ #
38
+ # If you are managing your cache size, when opening a proxy for writing you may want to provide a hint as
39
+ # to the expected size of the data:
40
+ # defog.file("key", "w", :size_hint => 500.kilobytes)
41
+ # See README for more details.
42
+ #
33
43
  class File < ::File
34
44
 
35
45
  def initialize(opts={}, &block) #:nodoc:
@@ -40,7 +50,9 @@ module Defog
40
50
  key = @handle.key
41
51
  proxy_path = @handle.proxy_path
42
52
  proxy_path.dirname.mkpath
43
- case opts.mode
53
+ re_encoding = /(b|:.*)$/
54
+ @encoding = opts.mode.match(re_encoding).to_s
55
+ case opts.mode.sub(re_encoding,'')
44
56
  when "r"
45
57
  download = true
46
58
  @upload = false
@@ -64,11 +76,11 @@ module Defog
64
76
  end
65
77
 
66
78
  def download_proxy
67
- @handle.proxy.fog_wrapper.get_file(@handle.key, @handle.proxy_path)
79
+ @handle.proxy.fog_wrapper.get_file(@handle.key, @handle.proxy_path, @encoding)
68
80
  end
69
81
 
70
82
  def upload_proxy
71
- @handle.proxy.fog_wrapper.put_file(@handle.key, @handle.proxy_path)
83
+ @handle.proxy.fog_wrapper.put_file(@handle.key, @handle.proxy_path, @encoding)
72
84
  end
73
85
 
74
86
 
@@ -20,16 +20,18 @@ module Defog #:nodoc: all
20
20
  klass.new(opts)
21
21
  end
22
22
 
23
- def get_file(key, path)
23
+ def get_file(key, path, encoding)
24
24
  raise Error::NoCloudFile, "No such file in #{provider} #{location}: #{key}" unless fog_head(key)
25
25
  return if path.exist? and Digest::MD5.hexdigest(path.read) == get_md5(key)
26
- path.open("w") do |f|
26
+ path.open("w#{encoding}") do |f|
27
27
  f.write(fog_head(key).body)
28
28
  end
29
29
  end
30
30
 
31
- def put_file(key, path)
32
- fog_directory.files.create(:key => key, :body => path.open)
31
+ def put_file(key, path, encoding)
32
+ path.open("r#{encoding}") do |file|
33
+ fog_directory.files.create(:key => key, :body => file)
34
+ end
33
35
  end
34
36
 
35
37
  def fog_head(key)
@@ -78,11 +78,12 @@ module Defog
78
78
 
79
79
  # Returns a Defog::File object, which is a specialization of ::File.
80
80
  #
81
- # <code>mode</code> can be "r", "r+", "w", "w+", "a", or "a+" with the
81
+ # <code>mode</code> can be the usual "r", "r+", "w", "w+", "a", or "a+" with the
82
82
  # usual semantics. When opened in a readable mode ("r", "r+", "w+",
83
83
  # "a+"), first caches the cloud file in the local proxy. When opened
84
84
  # in a writeable mode ("r+", "w", "w+", "a", "a+"), arranges to upload
85
- # the changes back to the cloud file at close time.
85
+ # the changes back to the cloud file at close time. The mode can be
86
+ # suffixed with 'b' or with ':' and encoding specifiers as usual.
86
87
  #
87
88
  # Like ::File.open, if called with a block yields the file object to
88
89
  # the block and ensures the file will be closed when leaving the block.
@@ -92,6 +93,12 @@ module Defog
92
93
  # :persist => true
93
94
  # to suppress deleting the file and so maintain the file after closing. See File#close for more
94
95
  # details.
96
+ #
97
+ # If you are managing your cache size, when opening a proxy for writing
98
+ # you may want to provide a hint as to the expected size of the data:
99
+ # :size_hint => 500.kilobytes
100
+ # See README for more details.
101
+ #
95
102
  def open(mode, opts={}, &block)
96
103
  opts = opts.keyword_args(:persist => @proxy.persist, :size_hint => :optional)
97
104
  File.open(opts.merge(:handle => self, :mode => mode), &block)
@@ -1,3 +1,3 @@
1
1
  module Defog
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -5,6 +5,7 @@ shared_examples "get proxy" do
5
5
  create_remote("hello")
6
6
  file = @proxy.file(key, @mode)
7
7
  File.exist?(file.path).should be_true
8
+ file.close
8
9
  end
9
10
 
10
11
  it "should raise error if remote doesn't exist" do
@@ -22,13 +23,13 @@ shared_examples "get proxy" do
22
23
  it "should use existing proxy if it's valid" do
23
24
  create_remote("hello")
24
25
  create_proxy("hello")
25
- Pathname.any_instance.should_not_receive(:open).with("w")
26
+ Pathname.any_instance.should_not_receive(:open).with(/^w/)
26
27
  @proxy.file(key, @mode)
27
28
 
28
29
  # doublecheck that should_not_receive was the right
29
30
  # thing to test. will it be received for an invalid proxy?
30
31
  create_proxy("goodbye")
31
- Pathname.any_instance.should_receive(:open).with("w")
32
+ Pathname.any_instance.should_receive(:open).with(/^w/)
32
33
  @proxy.file(key, @mode)
33
34
  end
34
35
  end
@@ -41,6 +42,22 @@ shared_examples "read" do
41
42
  file.read.should == "read me"
42
43
  end
43
44
  end
45
+
46
+ it "should pass 'b' mode through" do
47
+ create_remote("binary me")
48
+ @proxy.file(key, "#{@mode}b") do |file|
49
+ file.external_encoding.name.should == "ASCII-8BIT"
50
+ end
51
+ end
52
+
53
+ it "should pass encodings through" do
54
+ create_remote("encode me")
55
+ @proxy.file(key, "#{@mode}:EUC-JP:UTF-16") do |file|
56
+ file.external_encoding.name.should == "EUC-JP"
57
+ file.internal_encoding.name.should == "UTF-16"
58
+ end
59
+ end
60
+
44
61
  end
45
62
 
46
63
  shared_examples "read after write" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-27 00:00:00.000000000 Z
12
+ date: 2012-04-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
16
- requirement: &70100481071360 !ruby/object:Gem::Requirement
16
+ requirement: &70269507983660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70100481071360
24
+ version_requirements: *70269507983660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: hash_keyword_args
27
- requirement: &70100481070940 !ruby/object:Gem::Requirement
27
+ requirement: &70269507983240 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70100481070940
35
+ version_requirements: *70269507983240
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: fastandand
38
- requirement: &70100481070520 !ruby/object:Gem::Requirement
38
+ requirement: &70269507982820 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70100481070520
46
+ version_requirements: *70269507982820
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &70100481070100 !ruby/object:Gem::Requirement
49
+ requirement: &70269507982400 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70100481070100
57
+ version_requirements: *70269507982400
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &70100481069680 !ruby/object:Gem::Requirement
60
+ requirement: &70269507981980 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70100481069680
68
+ version_requirements: *70269507981980
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
- requirement: &70100481069240 !ruby/object:Gem::Requirement
71
+ requirement: &70269507981540 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70100481069240
79
+ version_requirements: *70269507981540
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov-gem-adapter
82
- requirement: &70100481068720 !ruby/object:Gem::Requirement
82
+ requirement: &70269507981020 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70100481068720
90
+ version_requirements: *70269507981020
91
91
  description: Wrapper to fog gem, proxying access to cloud files as local files.
92
92
  email:
93
93
  - ronen@barzel.org