hubic 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -17,7 +17,9 @@ From the commande line:
17
17
  HUBIC_USER=foo@bar.com # Set the user on which we will act
18
18
  hubic client config # Configure the client API key
19
19
  hubic auth # Authenticate the user
20
+ hubic mkdir cloud # Create directory
20
21
  hubic upload file.txt cloud/file.txt # Upload file
22
+ hubic md5 cloud/file.txt # Retrieve MD5
21
23
  hubic download cloud/file.txt # Download file
22
24
  hubic delete cloud/file.txt # Remove file
23
25
  ```
data/bin/hubic CHANGED
@@ -128,4 +128,13 @@ when 'upload' # local / hubic
128
128
  src = ARGV[0]
129
129
  obj = ARGV[1]
130
130
  Hubic.for_user(user).upload(src, obj)
131
+ when 'mkdir'
132
+ obj = ARGV[0]
133
+ Hubic.for_user(user).mkdir(obj, parents: false)
134
+ when 'mkdir_p'
135
+ obj = ARGV[0]
136
+ Hubic.for_user(user).mkdir(obj, parents: true)
137
+ when 'md5'
138
+ obj = ARGV[0]
139
+ puts Hubic.for_user(user).md5(obj)
131
140
  end
@@ -30,6 +30,9 @@ class Hubic
30
30
  end
31
31
  class NotFound < Error
32
32
  end
33
+ class Exists < Error
34
+ end
35
+
33
36
  end
34
37
 
35
38
  # Set the default client Id to use
@@ -1,6 +1,35 @@
1
1
  require 'mime/types'
2
2
 
3
3
  class Hubic
4
+ # Create directory
5
+ # @param obj
6
+ # @param parents [true, false]
7
+ def mkdir(obj, parents: false)
8
+ container, path, = normalize_object(obj)
9
+
10
+ # Check for parents (create or raise error)
11
+ parent = File.dirname(path)
12
+ if ! %w[. /].include?(parent)
13
+ if (meta = get_metadata([container, parent])).nil?
14
+ if parents
15
+ mkdir([container, parent], parents: parents)
16
+ else
17
+ raise Error, "parent doesn't exist"
18
+ end
19
+ elsif meta[:type] != TYPE_DIRECTORY
20
+ raise Error, "parent is not a directory"
21
+ end
22
+ end
23
+
24
+ # Check if place is already taken before creating directory
25
+ if (meta = get_metadata(obj)).nil?
26
+ put_object(obj, nil, TYPE_DIRECTORY)
27
+ elsif meta[:type] != TYPE_DIRECTORY
28
+ raise Error::Exists, "a file already exists"
29
+ elsif !parents
30
+ raise Error::Exists, "the directory already exists"
31
+ end
32
+ end
4
33
 
5
34
  def download(obj, dst=nil, size: nil, offset: 0, &block)
6
35
  # Handle file name or nil as a posible destination
@@ -30,11 +59,11 @@ class Hubic
30
59
  io.close unless io.nil?
31
60
  end
32
61
 
33
- def upload(src, obj, type='application/octet-stream', &block)
62
+ def upload(src, obj, type=TYPE_OCTET_STREAM, &block)
34
63
  case src
35
64
  when String, Pathname
36
65
  type = (MIME::Types.of(src).first ||
37
- MIME::Types['application/octet-stream'].first).content_type
66
+ MIME::Types[TYPE_OCTET_STREAM].first).content_type
38
67
  end
39
68
  put_object(obj, src, type, &block)
40
69
  end
@@ -51,8 +80,9 @@ class Hubic
51
80
  raise "not implemented yet"
52
81
  end
53
82
 
54
- def checksum(src)
55
- raise "not implemented yet"
83
+ def md5(obj)
84
+ meta = get_metadata(obj)
85
+ meta[:etag]
56
86
  end
57
87
 
58
88
 
@@ -5,6 +5,9 @@ require 'json'
5
5
 
6
6
 
7
7
  class Hubic
8
+ TYPE_OCTET_STREAM = 'application/octet-stream'
9
+ TYPE_DIRECTORY = 'application/directory'
10
+
8
11
  class Container
9
12
  attr_reader :name, :count, :bytes, :metadata
10
13
  def initialize(hubic, name)
@@ -49,6 +52,50 @@ class Hubic
49
52
  end
50
53
  end
51
54
 
55
+ def parse_response_for_meta(response)
56
+ { :lastmod => (Time.parse(response['last-modified']) rescue nil),
57
+ :length => response.content_length,
58
+ :type => response['content-type'],
59
+ :etag => response['etag']
60
+ }
61
+ end
62
+
63
+
64
+ def get_metadata(obj)
65
+ container, path, uri = normalize_object(obj)
66
+ meta = {}
67
+
68
+
69
+ hdrs = {}
70
+ hdrs['X-Auth-Token'] = @os[:token]
71
+
72
+ http = Net::HTTP.new(uri.host, uri.port)
73
+ if uri.scheme == 'https'
74
+ http.use_ssl = true
75
+ # http.verify_mode = OpenSSL::SSL::VERIFY_NONE
76
+ end
77
+ http.start
78
+
79
+ http.request_head(uri.request_uri, hdrs) {|response|
80
+ case response
81
+ when Net::HTTPSuccess
82
+ meta = parse_response_for_meta(response)
83
+ when Net::HTTPNotFound
84
+ meta = nil
85
+ when Net::HTTPRedirection
86
+ fail "http redirect is not currently handled"
87
+ when Net::HTTPUnauthorized
88
+ # TODO: Need to refresh token
89
+ else
90
+ fail "resource unavailable: #{uri} (#{response.class})"
91
+ end
92
+ }
93
+
94
+ meta
95
+ ensure
96
+ http.finish unless http.nil?
97
+ end
98
+
52
99
  def get_object(obj, dst=nil, size: nil, offset: 0, &block)
53
100
  container, path, uri = normalize_object(obj)
54
101
 
@@ -85,13 +132,7 @@ class Hubic
85
132
  fail "resource unavailable: #{uri} (#{response.class})"
86
133
  end
87
134
 
88
- lastmod = Time.parse(response['last-modified']) rescue nil
89
- length = response.content_length
90
- type = response['content-type']
91
- meta = { :lastmod => lastmod,
92
- :length => length,
93
- :type => type
94
- }
135
+ meta = parse_response_for_meta(response)
95
136
 
96
137
  if block
97
138
  block.call(meta)
@@ -118,9 +159,16 @@ class Hubic
118
159
  http.finish unless http.nil?
119
160
  end
120
161
 
121
- def put_object(obj, src, type='application/octet-stream', &block)
162
+ def put_object(obj, src, type = TYPE_OCTET_STREAM, &block)
122
163
  container, path, uri = normalize_object(obj)
123
- io = File.open(src)
164
+ case src
165
+ when String
166
+ io = File.open(src)
167
+ when NilClass
168
+ io = StringIO.new('')
169
+ else
170
+ raise ArgumentError, 'Not Implemented Yet'
171
+ end
124
172
 
125
173
  hdrs = {}
126
174
  hdrs['X-Auth-Token' ] = @os[:token]
@@ -235,7 +283,7 @@ class Hubic
235
283
  end
236
284
 
237
285
  def normalize_object(obj)
238
- openstack_setup_refresh
286
+ openstack_setup_refresh # TODO: no need to refresh just get the endpoint
239
287
 
240
288
  c, p = case obj
241
289
  when String
@@ -1,3 +1,3 @@
1
1
  class Hubic
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hubic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-21 00:00:00.000000000 Z
12
+ date: 2014-05-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -141,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
141
  version: '0'
142
142
  segments:
143
143
  - 0
144
- hash: 254901150746708933
144
+ hash: 1807576899535075838
145
145
  required_rubygems_version: !ruby/object:Gem::Requirement
146
146
  none: false
147
147
  requirements:
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
150
  version: '0'
151
151
  segments:
152
152
  - 0
153
- hash: 254901150746708933
153
+ hash: 1807576899535075838
154
154
  requirements: []
155
155
  rubyforge_project:
156
156
  rubygems_version: 1.8.29