Class: Pione::Location::DropboxLocation

Inherits:
DataLocation show all
Defined in:
lib/pione/location/dropbox-location.rb

Overview

DropboxLocation represents locations on Dropbox server.

Constant Summary

Constants inherited from DataLocation

Pione::Location::DataLocation::KNOWN_ATTRS

Class Attribute Summary collapse

Attributes inherited from DataLocation

#path, #uri

Attributes inherited from BasicLocation

#address

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from DataLocation

#+, #==, #append, #as_directory, #basename, #cached?, #ctime, define, #directory_entries, #dirname, #extname, #file_entries, #hash, #inspect, #local, #local?, #mtime=, need_caching?, real_appendable?, #rebuild, set_scheme, #sha1, writable?, #write

Methods inherited from BasicLocation

#==, #hash, #inspect, location_type

Constructor Details

#initialize(uri) ⇒ DropboxLocation

Returns a new instance of DropboxLocation.



144
145
146
# File 'lib/pione/location/dropbox-location.rb', line 144

def initialize(uri)
  super(uri)
end

Class Attribute Details

.clientObject (readonly)

Returns the value of attribute client.



12
13
14
# File 'lib/pione/location/dropbox-location.rb', line 12

def client
  @client
end

Class Method Details

.auth_by_oauth2flow(redirect, session) ⇒ String

Authorize dropbox account by DropboxOAuth2Flow.

Parameters:

  • redirect (String)

    redirect URL

  • session (Hash)

    session

Returns:

  • (String)

    authorize URL



110
111
112
113
114
115
116
# File 'lib/pione/location/dropbox-location.rb', line 110

def auth_by_oauth2flow(redirect, session)
  if @consumer_key and @consumer_secret
    return DropboxOAuth2Flow.new(@consumer_key, @consumer_secret, redirect, session, :dropbox_auth_csrf_token)
  else
    raise DropboxLocationUnavailabel.new("There are no consumer key and consumer secret.")
  end
end

.auth_by_oauth2flow_no_redirectString

Authorize dropbox account by DropboxOAuth2FlowNoRedirect.

Returns:

  • (String)

    authorize URL



94
95
96
97
98
99
100
# File 'lib/pione/location/dropbox-location.rb', line 94

def auth_by_oauth2flow_no_redirect
  if @consumer_key and @consumer_secret
    return DropboxOAuth2FlowNoRedirect.new(@consumer_key, @consumer_secret)
  else
    raise DropboxLocationUnavailable.new("There are no consumer key and consumer secret.")
  end
end

.cached?Boolean

Return true if Dropbox's access token cache exists.

Returns:

  • (Boolean)

    true if Dropbox's access token cache exists



18
19
20
21
# File 'lib/pione/location/dropbox-location.rb', line 18

def cached?
  cache = Pathname.new("~/.pione/dropbox_api.cache").expand_path
  return (cache.exist? and cache.read.size > 0)
end

.enable(tuple_space) ⇒ void

This method returns an undefined value.

Enable Dropbox locations. This method get an access token from the tuple space and make a Dropbox client. This assumes to be called from task worker agents.

Parameters:



62
63
64
65
66
67
68
69
# File 'lib/pione/location/dropbox-location.rb', line 62

def enable(tuple_space)
  tuple = TupleSpace::AttributeTuple.new("dropbox_access_token", nil)
  if tuple_access_token = tuple_space.read!(tuple)
    @client = DropboxClient.new(tuple_access_token.value)
  else
    raise DropboxLocationUnavailable.new("There is no access token.")
  end
end

.get_code_for_cui_client(flow) ⇒ Array

Get code for CUI client.

Returns:

  • (Array)

    access token and Dropbox user ID



134
135
136
137
138
139
140
141
# File 'lib/pione/location/dropbox-location.rb', line 134

def get_code_for_cui_client(flow)
  puts '1. Go to: %s' % flow.start
  puts '2. Click "Allow"'
  puts '3. Copy the authorization code'
  print 'Enter the authorization code here: '
  code = STDIN.gets.strip
  flow.finish(code)
end

.rebuild(path) ⇒ Object



71
72
73
# File 'lib/pione/location/dropbox-location.rb', line 71

def rebuild(path)
  Location["dropbox:%s" % path]
end

.setup_consumer_key_and_secretvoid

This method returns an undefined value.

Setup Dropbox's consumer key and secret. They are loaded from a YAML file "dropbox_api.yml" at PIONE's home directory.



79
80
81
82
83
84
85
86
87
88
# File 'lib/pione/location/dropbox-location.rb', line 79

def setup_consumer_key_and_secret
  path = Pathname.new("~/.pione/dropbox_api.yml").expand_path
  if File.exist?(path)
    api = YAML.load(path.read)
    @consumer_key = api["key"]
    @consumer_secret = api["secret"]
  else
    raise DropboxLocationUnavailable.new("There are no consumer key and consumer secret.")
  end
end

.setup_for_cui_client(tuple_space) ⇒ void

This method returns an undefined value.

Setup Dropbox location for CUI client. This method gets Dropbox's access token from cache file or OAuth2.

Parameters:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/pione/location/dropbox-location.rb', line 29

def setup_for_cui_client(tuple_space)
  return if @client

  access_token = nil
  cache = Pathname.new("~/.pione/dropbox_api.cache").expand_path

  if cache.exist?
    # load access token from cache file
    access_token = cache.read
  else
    # get access token by OAtuh2
    setup_consumer_key_and_secret
    flow = auth_by_oauth2flow_no_redirect
    access_token, user_id = get_code_for_cui_client(flow)

    # cache session
    cache.open("w+") {|c| c.write access_token}
  end

  # make a client
  @client = DropboxClient.new(access_token)

  # share access token in tuple space
  share_access_token(tuple_space, access_token)
end

.share_access_token(tuple_space_server, access_token) ⇒ void

This method returns an undefined value.

Share dropbox's access token with PIONE agents.

Parameters:

  • tuple_space_server (TupleSpaceServer)

    tuple space server

  • access_token (String)

    access token



125
126
127
128
# File 'lib/pione/location/dropbox-location.rb', line 125

def share_access_token(tuple_space_server, access_token)
  tuple = TupleSpace::AttributeTuple.new("dropbox_access_token", access_token)
  tuple_space_server.write(tuple)
end

Instance Method Details

#copy(dest) ⇒ Object

Raises:



248
249
250
251
252
253
254
255
256
# File 'lib/pione/location/dropbox-location.rb', line 248

def copy(dest)
  raise NotFound.new(self) unless exist?

  if dest.scheme == scheme
    client.file_copy(@path.to_s, dest.path)
  else
    dest.write(read)
  end
end

#create(data) ⇒ Object



148
149
150
151
152
153
154
155
# File 'lib/pione/location/dropbox-location.rb', line 148

def create(data)
  if exist?
    raise ExistAlready.new(self)
  else
    client.put_file(@path.to_s, StringIO.new(data))
  end
  return self
end

#deleteObject



166
167
168
169
170
# File 'lib/pione/location/dropbox-location.rb', line 166

def delete
  if exist?
    client.file_delete(@path.to_s)
  end
end

#directory?Boolean

Returns:

  • (Boolean)


223
224
225
226
227
228
229
230
231
# File 'lib/pione/location/dropbox-location.rb', line 223

def directory?
  begin
     = client.(@path.to_s)
    return (["is_dir"] and not(["is_deleted"]))
  rescue DropboxError
    # when there exists no files and no directories
    false
  end
end

#entries(option = {}) ⇒ Object



184
185
186
# File 'lib/pione/location/dropbox-location.rb', line 184

def entries(option={})
  rel_entries(option).map {|entry| rebuild(@path + entry)}
end

#exist?Boolean

Returns:

  • (Boolean)


204
205
206
207
208
209
210
211
# File 'lib/pione/location/dropbox-location.rb', line 204

def exist?
   = client.(@path.to_s)
  return not(["is_deleted"])
rescue DropboxLocationUnavailable
  raise
rescue DropboxError
  return false
end

#file?Boolean

Returns:

  • (Boolean)


213
214
215
216
217
218
219
220
221
# File 'lib/pione/location/dropbox-location.rb', line 213

def file?
  begin
     = client.(@path.to_s)
    return (not(["is_dir"]) and not(["is_deleted"]))
  rescue DropboxError
    # when there exists no files and no directories
    false
  end
end


258
259
260
261
262
263
264
# File 'lib/pione/location/dropbox-location.rb', line 258

def link(orig)
  if orig.scheme == scheme
    orig.copy(link)
  else
    update(orig.read)
  end
end

#mkdirObject



233
234
235
236
237
# File 'lib/pione/location/dropbox-location.rb', line 233

def mkdir
  unless exist?
    client.file_create_folder(@path.to_s)
  end
end

#move(dest) ⇒ Object



239
240
241
242
243
244
245
246
# File 'lib/pione/location/dropbox-location.rb', line 239

def move(dest)
  if dest.scheme == scheme
    client.file_move(@path.to_s, dest.path)
  else
    copy(dest)
    delete
  end
end

#mtimeObject

dropbox have "modified" time only, therefore ctime is not implemented



174
175
176
177
# File 'lib/pione/location/dropbox-location.rb', line 174

def mtime
   = client.(@path.to_s)
  Time.parse(["modified"])
end

#readObject



157
158
159
# File 'lib/pione/location/dropbox-location.rb', line 157

def read
  exist? ? client.get_file(@path.to_s) : (raise NotFound.new(self))
end

#rel_entries(option = {}) ⇒ Object

Raises:



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/pione/location/dropbox-location.rb', line 188

def rel_entries(option={})
  list = []
  raise NotFound.new(self) if not(directory?)

   = client.(@path.to_s)
  ["contents"].select{|entry| not(entry["is_deleted"])}.each do |entry|
    list << entry["path"].sub(@path.to_s, "").sub(/^\//, "")
    entry_location = rebuild(@path + File.basename(entry["path"]))
    if option[:rec] and entry_location.directory?
      _list = entry_location.rel_entries(option).map {|subentry| entry + subentry}
      list = list + _list
    end
  end
  return list
end

#sizeObject



179
180
181
182
# File 'lib/pione/location/dropbox-location.rb', line 179

def size
   = client.(@path.to_s)
  return ["bytes"]
end

#turn(dest) ⇒ Object



266
267
268
# File 'lib/pione/location/dropbox-location.rb', line 266

def turn(dest)
  copy(dest)
end

#update(data) ⇒ Object



161
162
163
164
# File 'lib/pione/location/dropbox-location.rb', line 161

def update(data)
  client.put_file(@path.to_s, StringIO.new(data), true)
  return self
end