class Pione::Location::DropboxLocation

DropboxLocation represents locations on Dropbox server.

Attributes

client[R]

Public Class Methods

auth_by_oauth2flow(redirect, session) click to toggle source

Authorize dropbox account by ‘DropboxOAuth2Flow`.

@param redirect [String]

redirect URL

@param session [Hash]

session

@return [String]

authorize URL
# 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_redirect() click to toggle source

Authorize dropbox account by ‘DropboxOAuth2FlowNoRedirect`.

@return [String]

authorize URL
# 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?() click to toggle source

Return true if Dropbox’s access token cache exists.

@return [Boolean]

true if Dropbox's access token cache exists
# 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) click to toggle source

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.

@param tuple_space_server [TupleSpaceServer]

tuple space server

@return [void]

# 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) click to toggle source

Get code for CUI client.

@return [Array]

access token and Dropbox user ID
# 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
new(uri) click to toggle source
Calls superclass method Pione::Location::DataLocation::new
# File lib/pione/location/dropbox-location.rb, line 144
def initialize(uri)
  super(uri)
end
rebuild(path) click to toggle source
# File lib/pione/location/dropbox-location.rb, line 71
def rebuild(path)
  Location["dropbox:%s" % path]
end
setup_consumer_key_and_secret() click to toggle source

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

@return [void]

# 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) click to toggle source

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

@param tuple_space [TupleSpaceServer]

tuple space

@return [void]

# 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) click to toggle source

Share dropbox’s access token with PIONE agents.

@param tuple_space_server [TupleSpaceServer]

tuple space server

@param access_token [String]

access token

@return [void]

# 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

Public Instance Methods

copy(dest) click to toggle source
# 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) click to toggle source
# 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
delete() click to toggle source
# File lib/pione/location/dropbox-location.rb, line 166
def delete
  if exist?
    client.file_delete(@path.to_s)
  end
end
directory?() click to toggle source
# File lib/pione/location/dropbox-location.rb, line 223
def directory?
  begin
    metadata = client.metadata(@path.to_s)
    return (metadata["is_dir"] and not(metadata["is_deleted"]))
  rescue DropboxError
    # when there exists no files and no directories
    false
  end
end
entries(option={}) click to toggle source
# File lib/pione/location/dropbox-location.rb, line 184
def entries(option={})
  rel_entries(option).map {|entry| rebuild(@path + entry)}
end
exist?() click to toggle source
# File lib/pione/location/dropbox-location.rb, line 204
def exist?
  metadata = client.metadata(@path.to_s)
  return not(metadata["is_deleted"])
rescue DropboxLocationUnavailable
  raise
rescue DropboxError
  return false
end
file?() click to toggle source
# File lib/pione/location/dropbox-location.rb, line 213
def file?
  begin
    metadata = client.metadata(@path.to_s)
    return (not(metadata["is_dir"]) and not(metadata["is_deleted"]))
  rescue DropboxError
    # when there exists no files and no directories
    false
  end
end
mkdir() click to toggle source
# File lib/pione/location/dropbox-location.rb, line 233
def mkdir
  unless exist?
    client.file_create_folder(@path.to_s)
  end
end
move(dest) click to toggle source
# 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
mtime() click to toggle source

dropbox have “modified” time only, therefore ctime is not implemented

# File lib/pione/location/dropbox-location.rb, line 174
def mtime
  metadata = client.metadata(@path.to_s)
  Time.parse(metadata["modified"])
end
read() click to toggle source
# 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={}) click to toggle source
# File lib/pione/location/dropbox-location.rb, line 188
def rel_entries(option={})
  list = []
  raise NotFound.new(self) if not(directory?)

  metadata = client.metadata(@path.to_s)
  metadata["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
size() click to toggle source
# File lib/pione/location/dropbox-location.rb, line 179
def size
  metadata = client.metadata(@path.to_s)
  return metadata["bytes"]
end
turn(dest) click to toggle source
# File lib/pione/location/dropbox-location.rb, line 266
def turn(dest)
  copy(dest)
end
update(data) click to toggle source
# 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

Private Instance Methods

client() click to toggle source

Check availability of Dropbox’s access token.

@return [void]

# File lib/pione/location/dropbox-location.rb, line 275
def client
  if self.class.client.nil?
    # raise an exception when Dropbox client isn't enabled
    raise DropboxLocationUnavailable.new("There is no access token.")
  else
    self.class.client
  end
end