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 =
<<-END
default:
  email: [email protected]  
  password: password
  store_tag: IMAPSTORE
  imap_server: imap.gmail.com
  imap_port: 993
	ssl: true
	
other:
  email: [email protected]
  password: password
  store_tag: IMAPSTORE
  imap_server: imap.gmail.com
  imap_port: 993
  ssl: true
END

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