Class: Net::FS::Gmail

Inherits:
Object
  • Object
show all
Defined in:
lib/net/fs/gmail.rb

Overview

Net::FS::Gmail - store and retrieve files on Gmail

This is a port of Perl’s Net::FS::Gmail.

File storage should be compatible with the original Perl version.

License

Net::FS::Gmail is released under the Apache License, Version 2.0

Author

Blair Christensen. <[email protected]>

Copyright © 2007, Blair Christensen

Constant Summary collapse

FILESTORE_PREFIX =

Prepend this string to message Subject to mark Net::FS::Gmail files.

'GmailStore v'
FILESTORE_VERSION =

Version of filestore.

'0.1'
GMAIL_DOMAIN =

Append this email domain to Gmail username if not present.

'@gmail.com'
GMAIL_LABEL =

Gmail label where messages may be found.

'Inbox'
MOST_RECENT_VERSION =

Files are versioned from newest-to-oldest, starting from this number.

1
VERSION =

Net::FS::Gmail version

'0.0.2'

Instance Method Summary collapse

Constructor Details

#initialize(user, password) ⇒ Gmail

Create connection to Gmail. Returns Net::FS::Gmail object.

Raises RuntimeError when user or password is nil.

Example:

require 'net/fs/gmail'
fs = Net::FS::Gmail.new('your.gmail.account', 'your password')


51
52
53
54
55
56
57
# File 'lib/net/fs/gmail.rb', line 51

def initialize(user, password)
  # Handle nil verification myself since gmailer currently does not do any verification
  user.nil?     && raise('nil user')
  password.nil? && raise('nil password')
  @gmail  = GMailer.connect(user, password)
  @user   = user
end

Instance Method Details

#delete(file, version = nil) ⇒ Object

Permanently delete file from Gmail.

If version is specified only that version will be deleted. Otherwise all versions will be deleted.

Example:

fs.delete('example', 2)  # Delete version +2+ of file +example+
fs.delete('example')     # Delete all versions of file +example+


69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/net/fs/gmail.rb', line 69

def delete(file, version = nil)
  # TODO 20070901 DRY w/ "remove()"
  versions = self.versions(file)
  raise('No versions found') if versions.size < 1
  if version.nil?
    versions.each { |v| @gmail.delete_message(v.id) }
  else
    version = version.to_i
    raise('Version must be positive integer') if version < 1
    v = versions[version - 1]
    @gmail.delete_message(v.id)
  end
end

#filesObject

Get a list of all the file names stored on Gmail.

Example:

fs.files().each { |name| puts name }


89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/net/fs/gmail.rb', line 89

def files()
  files = []
  # TODO 20070831 create patch to add rdoc to all gmailer methods i call
  # TODO 20070831 create otherblog posts for all gmailer methods i call
  # TODO 20070831 create rdoc2gwiki tranlator?
  # TODO 20070831 ml.each      - yields Gmailer::Box objects
  # TODO 20070831 ml.each_msg  - yields Gmailer::Message objects and debug spew
  @gmail.messages(:standard => GMAIL_LABEL).each do |box|
    next unless box.subject =~ /^#{FILESTORE_PREFIX}[\d.]+ (.+)$/
    files << $1
  end
  files.uniq # TODO 20070901 i think this deviates from the original Perl
end

#quotaObject

Returns two element array of current quota usage.

Elements:

  • 0

    Usage (MB)

  • 1

    Usage (Percentage)

Example:

quota = fs.quota()
puts sprintf("%s MB (%s%%)", quota[0], quota[1])


114
115
116
117
118
119
120
# File 'lib/net/fs/gmail.rb', line 114

def quota()
  # TODO 20070901 why do i need to call this (or something like it) before getting a snapshot?
  @gmail.fetch(:contact => "freq") 
  snap = @gmail.snap(:standard)
  # TODO 20070901 add support for quota size
  [ snap.quota_mb, snap.quota_per ]
end

#remove(file, version) ⇒ Object

Move file to Gmail trash.

If version is specified only that version will be removed. Otherwise all versions will be trashed.

Example:

fs.remove('example', 2)  # Move version +2+ of file +example+ to trash
fs.remove('example')     # Move all versions of file +example+ to trash


132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/net/fs/gmail.rb', line 132

def remove(file, version)
  # TODO 20070901 DRY w/ "delete()"
  versions = self.versions(file)
  raise('No versions found') if versions.size < 1
  if version.nil?
    versions.each { |v| @gmail.trash(v.id) }
  else
    version = version.to_i
  raise('Version must be positive integer') if version < 1
    v = versions[version - 1]
    @gmail.trash(v.id)
  end
end

#retrieve(file, as = nil, version = MOST_RECENT_VERSION) ⇒ Object

Retrieves file from Gmail and writes to the local filesystem.

If as is specified, that will be used as the name of the output file. Otherwise file will be used. If version is not specified, the most recent version of file will be retrieved.

Example:

# Retrieve most recent version of +example+ and write to file +example+
fs.retrieve('example')

# Retrieve most recent version of +example+ and write to file +example.txt+
fs.retrieve('example', 'example.txt')

# Retrieve version +2+ of +example+ and write to file +/tmp/example-v2.txt+
fs.retrieve('example', '/tmp/example-v2.txt', 2)


163
164
165
166
167
168
169
# File 'lib/net/fs/gmail.rb', line 163

def retrieve(file, as = nil, version = MOST_RECENT_VERSION)
  as  = file if ( as.nil? || as.empty? )
  v   = self.versions(file)[ version.to_i - 1 ]
  att = v.attachment[0]
  # TODO 20070901 why "0.1" as the attachment id?  and can i retrieve that via the api somehow?
  @gmail.attachment("0.1", v.id, as, false) 
end

#store(file, as) ⇒ Object

Store file on Gmail.

If as is specified it will be used as the filename instead of file. The name of file will be expanded to the absolute path if as is not specified.

Example:

fs.store('example')                 # Store local file +example+ as +example+
fs.store('example.txt', 'example')  # Store local file +example.txt+ as +example+


181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/net/fs/gmail.rb', line 181

def store(file, as)
  File.exist?(file) || raise("No such file '#{file}'")
  file  = File.expand_path(file) # TODO 20070901 to expand or not to expand?
  as    = file if ( as.nil? || as.empty? )
  user  = @user
  user  =~ /#{GMAIL_DOMAIN}$/ || user += GMAIL_DOMAIN
  @gmail.send(
    :to       => "#{@user}@gmail.com",
    :subject  => "#{FILESTORE_PREFIX}#{FILESTORE_VERSION} #{as}",
    :files    => [ file ]
  )
end

#versions(file) ⇒ Object

Return array of all versions of file stored on Gmail.

Files are versioned from newest-to-oldest, beginning with MOST_RECENT_VERSION.

Example:

fs.versions('example').each_with_index do |v,idx|
  puts sprintf("%-3d\t%-16s\t%-7s", idx + 1, v.id, v.date)
end


204
205
206
207
208
209
210
211
# File 'lib/net/fs/gmail.rb', line 204

def versions(file)
  versions = []
  @gmail.messages(:standard => GMAIL_LABEL).each do |box|
    next unless box.subject =~ /^#{FILESTORE_PREFIX}[\d.]+ #{file}$/
    versions << box
  end
  versions
end