Class: IMAPSTORE::Imapstore

Inherits:
Object
  • Object
show all
Defined in:
lib/imapstore/imapstore.rb

Constant Summary collapse

MAX_FILE_SIZE =
20000000
CHUNK_SIZE =
10000000
CONFIG_TEMPLATE =
"default:\n  email: [email protected]  \n  password: password\n  store_tag: IMAPSTORE\n  imap_server: imap.gmail.com\n  imap_port: 993\n  ssl: true\n  \nother:\n  email: [email protected]\n  password: password\n  store_tag: IMAPSTORE\n  imap_server: imap.gmail.com\n  imap_port: 993\n  ssl: true\n"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file = File.expand_path('~/.imapstore/config.yml'), imapstore = "default", password = nil) ⇒ Imapstore

Returns a new instance of Imapstore.



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/imapstore/imapstore.rb', line 40

def initialize(file = File.expand_path('~/.imapstore/config.yml'), imapstore="default", password=nil)
puts "Initializing IMAP" if @verbose
@versioned = true
@verbose = false

@password = password

puts "Getting configuration file #{file} for account #{imapstore}" if @verbose
get_config(file, imapstore)
connect
end

Class Method Details

.create_config_file(file = File.expand_path('~/.imapstore/config.yml')) ⇒ Object



32
33
34
35
36
37
38
# File 'lib/imapstore/imapstore.rb', line 32

def self.create_config_file(file = File.expand_path('~/.imapstore/config.yml'))
      if !File.exists?(file)
 puts "creating #{File.dirname(file)}"
 FileUtils.mkdir_p(File.dirname(file))
File.open(file,"w").write(CONFIG_TEMPLATE)
      end      
end

Instance Method Details

#connectObject



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/imapstore/imapstore.rb', line 88

def connect()
raise "No password given" if @password == nil
  if !@imap && @email && @password && @imap_server && @imap_port
  if(@ssl == true)
      @imap = Net::IMAP.new(@imap_server, @imap_port, true)
  else
      @imap = Net::IMAP.new(@imap_server, @imap_port, false)
  end
    @imap.(@email, @password)
  end
end

#disconnectObject



100
101
102
103
104
105
106
107
108
# File 'lib/imapstore/imapstore.rb', line 100

def disconnect()
  if @imap
    @imap.logout()
    begin
      @imap.disconnect()
    rescue 
    end
  end
end

#emailObject



60
61
62
# File 'lib/imapstore/imapstore.rb', line 60

def email
  @email
end

#get_config(file = File.expand_path('~/.imapstore/config.yml'), imapstore = "default") ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/imapstore/imapstore.rb', line 110

def get_config(file = File.expand_path('~/.imapstore/config.yml'), imapstore = "default")
if !File.exists?(file)
  File.open(file,"w").write(CONFIG_TEMPLATE)
end

  aConfig = YAML::load_file(file)

  #COFIGURATION SECTION
  @email = aConfig[imapstore]['email']
  @password = aConfig[imapstore]['password'] if aConfig[imapstore]['password']
  @store_tag = aConfig[imapstore]['store_tag'] || "IMAPSTORE"
@imap_server = aConfig[imapstore]['imap_server']
@imap_port = aConfig[imapstore]['imap_port']
@ssl = aConfig[imapstore]['ssl'] || false
  #END CONFIGURATION SECTION
  
aConfig
end

#get_file(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false) ⇒ Object



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/imapstore/imapstore.rb', line 295

def get_file(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false)
  multipart_files = Hash.new
  file_list = transverse(target_folder, glob, recursive, dot_files, false) do |folder, file_name, message_id, mail, file_part, max_parts|
    if(file_name && mail.parts) 
      mail.parts.each do |m|
        if !m.main_type
          append_dir = folder
          append_dir.sub!(/^#{target_folder}\/*/,"")
          if append_dir != ""
            Dir.mkdir(append_dir) if !File.exists? append_dir   
            file_name = append_dir + "/" + file_name
          end
        
          if(file_part)
            multipart_files[file_name] = max_parts if !multipart_files[file_name]             
            file_name = file_name + "_#{file_part}_#{max_parts}"
          end
          puts "Getting file #{file_name}" if @verbose 
          
          File.open(file_name,"w") do |f|
            f.write(m.body)
          end
        end
      end
    end
  end
  
  multipart_files.each do |key,value|
    puts "Fusing #{key} ---- #{value}" if @verbose
    File.open(key,"w") do |f|
      1.upto(value.to_i) do |step|
        f.write(File.open("#{key}_#{step}_#{value}").read)
        File.unlink("#{key}_#{step}_#{value}")
      end
    end
  end
  return file_list
end

#imap_portObject



76
77
78
# File 'lib/imapstore/imapstore.rb', line 76

def imap_port
  @imap_port
end

#imap_serverObject



72
73
74
# File 'lib/imapstore/imapstore.rb', line 72

def imap_server
  @imap_server
end

#ls(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false) ⇒ Object



291
292
293
# File 'lib/imapstore/imapstore.rb', line 291

def ls(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false)
  transverse(target_folder, glob, recursive, dot_files, false)
end

#mkdir(folder) ⇒ Object



347
348
349
# File 'lib/imapstore/imapstore.rb', line 347

def mkdir(folder)
  @imap.create(folder)
end

#passwordObject



64
65
66
# File 'lib/imapstore/imapstore.rb', line 64

def password
  @password
end

#quota(folder) ⇒ Object



375
376
377
# File 'lib/imapstore/imapstore.rb', line 375

def quota(folder)
  @imap.getquotaroot(folder)
end

#rm_file(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false) ⇒ Object



336
337
338
339
340
341
342
343
344
345
# File 'lib/imapstore/imapstore.rb', line 336

def rm_file(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false)
      file_list = transverse(target_folder, glob, false, dot_files, false) do |folder, file_name, message_id, mail, file_part, max_parts|
        if file && message_id
      @imap.store(message_id, "+FLAGS", [:Deleted]) 
@imap.expunge
        end
      end
  
  file_list
end

#rmdir(target_folder, recursive = false, dot_files = false) ⇒ Object



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/imapstore/imapstore.rb', line 351

def rmdir(target_folder, recursive = false, dot_files = false)
  folders = []
  puts "..... Deleting #{target_folder}" if @verbose
  
  transverse(target_folder, /.+/, recursive, dot_files, false) do |folder, file, message_id, mail, file_part, max_parts| 
    puts "..... assigning dir #{folder} for removal" if @verbose
    folders << folder if !(folders.include? folder)
    
    if file && message_id
      puts "..... actually removing dir #{folder} file #{file_name}" if @verbose
         @imap.store(message_id, "+FLAGS", [:Deleted]) 
      @imap.expunge
    end
  end

  
  folders.each do |folder|
    puts "..... actually removing dir #{folder}" if @verbose
    @imap.delete(folder)
  end
  
  folders
end

#snipplet(subject = "snipplet", body = "", folder = "snipplets", file = nil) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/imapstore/imapstore.rb', line 129

def snipplet(subject = "snipplet", body = "", folder="snipplets", file = nil)
  puts "Storing snipplet" if @verbose
  
  mail = TMail::Mail.new
     mail.to = @email
     mail.from = @email
      mail.subject = subject

     mail.date = Time.now
     mail.mime_version = '1.0'
  
     mailpart1=TMail::Mail.new
     mailpart1.set_content_type 'text', 'plain'
     mailpart1.body = body
     mail.parts << mailpart1
     mail.set_content_type 'multipart', 'mixed'

  #      if file && FileTest.exists?(file)
  #        mailpart=TMail::Mail.new
  #        mailpart.body = Base64.encode64(chunk.to_s)
  #        mailpart.transfer_encoding="Base64"
  #        mailpart['Content-Disposition'] = "attachment; filename=#{CGI::escape(basename)}"
  #  mail.parts.push(mailpart)
  # end
  @imap.create(folder) if !@imap.list("", folder)
  @imap.append(folder, mail.to_s, [:Seen], Time.now)
  
end

#store_file(file, folder = "INBOX", subject = "") ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/imapstore/imapstore.rb', line 223

def store_file( file, folder = "INBOX", subject = "")
    
      @imap.create(folder) if !@imap.list("", folder)
    
      size = File.size(file) 
      if(size > MAX_FILE_SIZE)
        remaining = size
        max_chunk_no = (size/CHUNK_SIZE)+1
        chunk_no = 1
        File.open(file) do |f|
while(remaining>0)
  content = f.read(CHUNK_SIZE)
  store_file_chunk( file, folder, subject, content, chunk_no, max_chunk_no)
  chunk_no = chunk_no +1
  remaining = remaining - CHUNK_SIZE
end
        end
      else
        content=File.open(file).read
        store_file_chunk( file, folder, subject, content)
      end
end

#store_file_chunk(file, folder = "INBOX", subject = "", chunk = nil, chunk_no = 0, max_chunk_no = 0) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/imapstore/imapstore.rb', line 158

def store_file_chunk( file, folder = "INBOX", subject = "", chunk=nil, chunk_no=0, max_chunk_no=0 )
  if(max_chunk_no>0)
    puts "Storing part #{chunk_no} of #{max_chunk_no}"
  end
      basename = File.basename(file)
  version = 0

  if max_chunk_no == 0
    tag = "#{@store_tag}[#{basename}]"
  else
    tag = "#{@store_tag}[#{basename}](#{chunk_no}-#{max_chunk_no})"
  end
  @imap.select(folder)
  @imap.search(["SUBJECT", tag, "NOT", "DELETED"]).each do |message_id|
    if @versioned==true
      version = version + 1
    else
      @imap.store(message_id, "+FLAGS", [:Deleted]) 
    end
  end
  @imap.expunge
  
  mail = TMail::Mail.new
     mail.to = @email
     mail.from = @email
  if max_chunk_no == 0
       mail.subject = "#{@store_tag}[#{basename}]"
  else
       mail.subject = "#{@store_tag}[#{basename}](#{chunk_no}-#{max_chunk_no})"
  end
  
  if version > 0
    mail.subject = mail.subject + "(v. #{version})"
  end
  
  if subject
    mail.subject = mail.subject + ": #{subject}"
  end
  
     mail.date = Time.now
     mail.mime_version = '1.0'

     mailpart1=TMail::Mail.new
     mailpart1.set_content_type 'text', 'plain'
     mailpart1.body = "This is a mail storage message of file #{file}" 
     mail.parts << mailpart1
     mail.set_content_type 'multipart', 'mixed'

     if FileTest.exists?(file)
       mailpart=TMail::Mail.new
       mailpart.body = Base64.encode64(chunk.to_s)
       mailpart.transfer_encoding="Base64"
    if max_chunk_no == 0
         mailpart['Content-Disposition'] = "attachment; filename=#{CGI::escape(basename)}"
    else
         mailpart['Content-Disposition'] = "attachment; filename=#{CGI::escape(basename)}_#{chunk_no}-#{max_chunk_no}"
    end
       mail.parts.push(mailpart)
     end


     @imap.append(folder, mail.to_s, [:Seen], File.new(file).atime)

end

#store_tagObject



68
69
70
# File 'lib/imapstore/imapstore.rb', line 68

def store_tag
  @store_tag
end

#transverse(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false, folder_only = false) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/imapstore/imapstore.rb', line 246

def transverse(target_folder = "INBOX", glob = /.+/, recursive = false, dot_files = false, folder_only=false)
  file_list=[]
  #begin
    target_folder = "" if target_folder == "/"
    
    puts "..... fetching #{target_folder} " if @verbose 
      
    @imap.list(target_folder, "*").each do |folder|

      puts "..... transversing #{folder.name} " if @verbose
            
      if ((recursive == true) && (target_folder == "" ? true : folder.name.match(/^#{target_folder}(\/.+)*$/))) || (folder.name == target_folder) 
        puts "..... got hit transversing #{folder.name} " if @verbose
        file_list << folder.name
        if(block_given?)
          yield(folder.name, nil, nil, nil, nil, nil) 
        end
      
        if((!folder.attr.include? :Noselect) && (folder_only==false))

          @imap.select(folder.name)

          @imap.search(["NOT", "DELETED"]).each do |message_id|
            a = @imap.fetch(message_id, "RFC822")
            mail = TMail::Mail.parse(a[0].attr["RFC822"])
            file_name = mail.subject.match(/^[^\[]+\[([^\]]+)\]/)[1]
            puts "Considering #{file_name}" if @verbose
            
            parts = mail.subject.match(/^[^\[]+\[[^\]]+\]\(([0-9]+)\-([0-9]+)\)/)
            file_part = parts[1]
            max_parts = parts[2]
            if file_name.match(glob)
             file_list << folder.name + "/" + file_name 
              yield(folder.name, file_name, message_id, mail, file_part, max_parts) if block_given? 
            end
          end
        end
      end
    end
  #rescue
  #end
  
      file_list.sort
end

#verboseObject



80
81
82
# File 'lib/imapstore/imapstore.rb', line 80

def verbose
  @verbose
end

#verbose=(value) ⇒ Object



84
85
86
# File 'lib/imapstore/imapstore.rb', line 84

def verbose=(value)
  @verbose = value
end

#versionedObject



52
53
54
# File 'lib/imapstore/imapstore.rb', line 52

def versioned
  @versioned
end

#versioned=(is_versioned) ⇒ Object



56
57
58
# File 'lib/imapstore/imapstore.rb', line 56

def versioned=(is_versioned)
  @versioned = is_versioned
end