368 lines
13 KiB
Ruby
Executable file
368 lines
13 KiB
Ruby
Executable file
require 'imap_session'
|
|
require 'imap_mailbox'
|
|
require 'imap_message'
|
|
require 'mail'
|
|
require 'mail_plugin_extension'
|
|
require 'net/smtp'
|
|
|
|
class MessagesOpsController < ApplicationController
|
|
|
|
include ImapMailboxModule
|
|
include ImapSessionModule
|
|
include ImapMessageModule
|
|
include MessagesHelper
|
|
|
|
before_filter :check_current_user ,:selected_folder,:get_current_folders
|
|
before_filter :open_imap_session, :select_imap_folder
|
|
before_filter :prepare_compose_buttons
|
|
before_filter :get_system_folders, :only => [:composed,:single,:multi]
|
|
before_filter :prepare_composed , :only => [:composed]
|
|
before_filter :create_message_with_params, :only=> [:composed,:single,:multi]
|
|
after_filter :close_imap_session
|
|
#theme :theme_resolver
|
|
|
|
|
|
############################################### single #####################################
|
|
|
|
def single
|
|
if params[:reply] or params[:reply_all]
|
|
reply
|
|
return
|
|
elsif params[:trash]
|
|
trash
|
|
elsif params[:move]
|
|
move
|
|
elsif params[:copy]
|
|
copy
|
|
end
|
|
redirect_to :controller => 'messages', :action => 'index'
|
|
end
|
|
|
|
############################################### multi ######################################
|
|
|
|
def multi
|
|
begin
|
|
if !params[:uids]
|
|
flash[:warning] = t(:no_selected,:scope=>:message)
|
|
elsif params[:set_unread]
|
|
set_unread
|
|
elsif params[:set_read]
|
|
set_read
|
|
elsif params[:trash]
|
|
trash
|
|
elsif params[:copy]
|
|
copy
|
|
elsif params[:move]
|
|
move
|
|
end
|
|
rescue Exception => e
|
|
flash[:error] = "#{t(:imap_error,:scope=>:internal)} (#{e.to_s})"
|
|
end
|
|
redirect_to :controller => 'messages', :action => 'index'
|
|
end
|
|
|
|
############################################### ################################################
|
|
|
|
|
|
def set_unread
|
|
params["uids"].each do |uid|
|
|
@mailbox.set_unread(uid)
|
|
@current_user.messages.where('folder_id = ? and uid = ?',@current_folder,uid).first.update_attributes(:unseen => 1)
|
|
end
|
|
end
|
|
|
|
def set_read
|
|
params["uids"].each do |uid|
|
|
@mailbox.set_read(uid)
|
|
@current_user.messages.where('folder_id = ? and uid = ?',@current_folder,uid).first.update_attributes(:unseen => 0)
|
|
end
|
|
end
|
|
|
|
def trash
|
|
if @trash_folder.nil?
|
|
flash[:warning] = t(:not_configured_trash, :scope=>:folder)
|
|
else
|
|
params["uids"].each do |uid|
|
|
@mailbox.move_message(uid,@trash_folder.full_name)
|
|
message = @current_folder.messages.find_by_uid(uid)
|
|
message.change_folder(@trash_folder)
|
|
end
|
|
@mailbox.expunge
|
|
@trash_folder.update_stats
|
|
@current_folder.update_stats
|
|
end
|
|
end
|
|
|
|
def copy
|
|
if params[:folder][:target].empty?
|
|
flash[:warning] = t(:no_selected,:scope=>:folder)
|
|
else
|
|
dest_folder = @current_user.folders.find(params[:folder][:target])
|
|
params["uids"].each do |uid|
|
|
@mailbox.copy_message(uid,dest_folder.full_name)
|
|
message = @current_folder.messages.find_by_uid(uid)
|
|
new_message = message.clone
|
|
new_message.folder_id = dest_folder.id
|
|
new_message.save
|
|
end
|
|
dest_folder.update_stats
|
|
@current_folder.update_stats
|
|
end
|
|
end
|
|
|
|
def move
|
|
if params[:folder][:target].empty?
|
|
flash[:warning] = t(:no_selected,:scope=>:folder)
|
|
else
|
|
dest_folder = @current_user.folders.find(params[:folder][:target])
|
|
logger.info "DEST: "+dest_folder.inspect
|
|
params["uids"].each do |uid|
|
|
logger.info "UID: "+uid
|
|
logger.info "DEST_FULL: "+dest_folder.full_name
|
|
@mailbox.move_message(uid,dest_folder.full_name)
|
|
message = @current_folder.messages.find_by_uid(uid)
|
|
logger.info "M: "+message.inspect
|
|
logger.info "UPDATE_DEST_BEFORE1: "+dest_folder.inspect
|
|
message.change_folder(dest_folder)
|
|
logger.info "UPDATE_DEST_BEFORE2: "+dest_folder.inspect
|
|
end
|
|
logger.info "UPDATE_DEST_BEFORE: "+dest_folder.inspect
|
|
@mailbox.expunge
|
|
dest_folder.update_stats
|
|
logger.info "UPDATE_DEST: "+dest_folder.inspect
|
|
@current_folder.update_stats
|
|
logger.info "UPDATE_CUT: "+@current_folder.inspect
|
|
end
|
|
end
|
|
|
|
def upload
|
|
begin
|
|
raise MailrException.new :cause=>:no_tmp_dir,:scope=>:common if not File.exists?($defaults["msg_upload_dir"])
|
|
raise MailrException.new :cause=>:no_file_chosen,:scope=>:common if not params[:upload]
|
|
@operation = :upload
|
|
name = params[:file][:data].original_filename
|
|
upload_dir = $defaults["msg_upload_dir"]
|
|
path = File.join(upload_dir, @current_user.username + "_" + name)
|
|
File.open(path, "wb") { |f| f.write(params[:file][:data].read) }
|
|
rescue MailrException => e
|
|
flash[:error] = t(e.message[:cause],:scope => e.message[:scope])
|
|
rescue Exception => e
|
|
flash[:error] = t(:general_error,:scope=>:internal) + " (" + e.class.name + " " + e.to_s + ")"
|
|
end
|
|
create_message_with_params
|
|
render 'messages/compose'
|
|
end
|
|
|
|
# Files uploaded from Internet Explorer:
|
|
#
|
|
#Internet Explorer includes the entire path of a file in the filename sent, so the original_filename routine will return something like:
|
|
#
|
|
#C:\Documents and Files\user_name\Pictures\My File.jpg
|
|
#
|
|
#instead of just:
|
|
#
|
|
#My File.jpg
|
|
#
|
|
#This is easily handled by File.basename, which strips out everything before the filename.
|
|
#
|
|
#def sanitize_filename(file_name)
|
|
# # get only the filename, not the whole path (from IE)
|
|
# just_filename = File.basename(file_name)
|
|
# # replace all none alphanumeric, underscore or perioids
|
|
# # with underscore
|
|
# just_filename.sub(/[^\w\.\-]/,'_')
|
|
#end
|
|
#
|
|
#Deleting an existing File:
|
|
#
|
|
#If you want to delete any existing file then its simple and need to write following code:
|
|
#
|
|
# def cleanup
|
|
# File.delete("#{RAILS_ROOT}/dirname/#{@filename}")
|
|
# if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}")
|
|
# end
|
|
|
|
def composed
|
|
if params[:delete_marked] and params[:files]
|
|
params[:files].each do |filename|
|
|
path = File.join(Rails.root,$defaults["msg_upload_dir"],@current_user.username + "_" +filename)
|
|
File.delete(path) if File.exist?(path)
|
|
end
|
|
create_message_with_params
|
|
@operation = :new
|
|
render 'messages/compose'
|
|
return
|
|
elsif params[:upload]
|
|
upload
|
|
elsif params[:save]
|
|
save
|
|
elsif params[:sendout]
|
|
sendout
|
|
else
|
|
redirect_to :controller => 'messages', :action => 'index'
|
|
end
|
|
end
|
|
|
|
def sendout
|
|
begin
|
|
smtp_server = @current_user.servers.primary_for_smtp
|
|
raise MailrException.new :cause=>:not_configured_smtp,:scope => :compose if smtp_server.nil?
|
|
raise MailrException.new :cause=>:has_no_domain,:scope=>:user if @current_user.has_domain?.nil?
|
|
raise MailrException.new :cause=>:not_configured_sent,:scope=>:compose if @sent_folder.nil?
|
|
send_mail_message( smtp_server,
|
|
@current_user.has_domain?,
|
|
@current_user.login,
|
|
@current_user.get_cached_password(session),
|
|
@mail.to_s,
|
|
@current_user.email,
|
|
params[:message][:to_addr]
|
|
)
|
|
@mailbox.append(@sent_folder.full_name,@mail.to_s,[:Seen])
|
|
upload_dir = $defaults["msg_upload_dir"]
|
|
@attachments.each do |file|
|
|
path = File.join(upload_dir, @current_user.username + "_" + file[:name])
|
|
File.delete(path) if File.exist?(path)
|
|
end
|
|
rescue MailrException => e
|
|
flash[:error] = t(e.message[:cause],:scope => e.message[:scope])
|
|
rescue Exception => e
|
|
flash[:error] = t(:general_error,:scope=>:internal) + " (" + e.class.name + " " + e.to_s + ")"
|
|
else
|
|
flash[:success] = t(:was_sent,:scope => :compose)
|
|
redirect_to :controller => 'messages', :action => 'index'
|
|
return
|
|
end
|
|
@operation = :new
|
|
render 'messages/compose'
|
|
end
|
|
|
|
def save
|
|
begin
|
|
raise MailrException.new :cause=>:not_configured_drafts,:scope=>:folder if @drafts_folder.nil?
|
|
@mailbox.append(@drafts_folder.full_name,@mail.to_s,[:Seen])
|
|
if params[:olduid].present?
|
|
@mailbox.move_message(params[:olduid],@trash_folder.full_name)
|
|
@mailbox.expunge
|
|
end
|
|
rescue MailrException => e
|
|
flash[:error] = t(e.message[:cause],:scope => e.message[:scope])
|
|
rescue Exception => e
|
|
flash[:error] = t(:general_error,:scope=>:internal) + " (" + e.class.name + " " + e.to_s + ")"
|
|
else
|
|
@attachments.each do |filename|
|
|
path = File.join(Rails.root,filename[:name])
|
|
File.delete(path) if File.exist?(path)
|
|
end
|
|
flash[:success] = t(:was_saved,:scope => :compose)
|
|
end
|
|
redirect_to :controller => 'messages', :action => 'index'
|
|
end
|
|
|
|
#FIXME edit does not support attachments
|
|
def edit
|
|
#logger.info @current_folder.inspect
|
|
#logger.info params.inspect
|
|
|
|
old_message = @current_user.messages.where('folder_id = ? and uid = ?',@current_folder,params[:id]).first
|
|
@message = Message.new
|
|
@message.to_addr = old_message.to_addr
|
|
@message.subject = old_message.subject
|
|
|
|
imap_message = @mailbox.fetch_body(old_message.uid)
|
|
mail = Mail.new(imap_message)
|
|
if mail.multipart?
|
|
@message.body = mail.text_part.nil? ? "" : mail.text_part.decoded_and_charseted.gsub(/<\/?[^>]*>/, "")
|
|
else
|
|
@message.body = mail.decoded_and_charseted.gsub(/<\/?[^>]*>/, "")
|
|
end
|
|
@attachments = []
|
|
@operation = :edit
|
|
@olduid = old_message.uid
|
|
render 'messages/compose'
|
|
end
|
|
|
|
def reply
|
|
old_message = @current_user.messages.where('folder_id = ? and uid = ?',@current_folder,params[:uids].first).first
|
|
@message = Message.new
|
|
#@message.to_addr = old_message.from_addr
|
|
#@message.to_addr = old_message.from.first
|
|
#@message.subject = old_message.subject
|
|
|
|
imap_message = @mailbox.fetch_body(old_message.uid)
|
|
mail = Mail.new(imap_message)
|
|
@message.to_addr = mail.from.first
|
|
@message.subject = mail.subject
|
|
|
|
if params[:reply_all]
|
|
@message.cc_addr = mail.cc.join('; ')
|
|
end
|
|
|
|
if mail.multipart?
|
|
@message.body = mail.text_part.nil? ? "" : mail.text_part.decoded_and_charseted.gsub(/<\/?[^>]*>/, "")
|
|
else
|
|
@message.body = mail.decoded_and_charseted.gsub(/<\/?[^>]*>/, "")
|
|
end
|
|
@attachments = []
|
|
@operation = :reply
|
|
render 'messages/compose'
|
|
end
|
|
|
|
###################################### protected section #######################################
|
|
|
|
protected
|
|
|
|
def send_mail_message(smtp_server,domain,username,password,msgstr,from,to)
|
|
if smtp_server.auth.nil?
|
|
smtp = Net::SMTP.start(smtp_server.name, smtp_server.port, domain)
|
|
else
|
|
smtp = Net::SMTP.start(smtp_server.name, smtp_server.port, domain, username, password, smtp_server.auth)
|
|
end
|
|
smtp.send_message msgstr, from, to
|
|
smtp.finish
|
|
end
|
|
|
|
def prepare_composed
|
|
@mail = Mail.new
|
|
@mail.subject = params[:message][:subject]
|
|
@mail.from = @current_user.full_id
|
|
#TODO check if email address is valid if not get address from contacts
|
|
@mail.to = params[:message][:to_addr]
|
|
@mail.cc = params[:message][:cc_addr]
|
|
@mail.body = params[:message][:body]
|
|
@attachments = Dir.glob(File.join($defaults["msg_upload_dir"],@current_user.username + "*"))
|
|
@attachments.each do |a|
|
|
@mail.add_file :filename => File.basename(a.gsub(/#{@current_user.username}_/,"")), :content => File.read(a)
|
|
end
|
|
end
|
|
|
|
############################################ set_mail_defaults ####################################
|
|
|
|
def set_mail_defaults(user,server,session)
|
|
if server.auth.nil? or server.auth == 'none'
|
|
password = nil
|
|
authentication = nil
|
|
enable_starttls_auto = nil
|
|
openssl_verify_mode = nil
|
|
user_name = nil
|
|
else
|
|
password = user.get_cached_password(session)
|
|
authentication = server.auth
|
|
enable_starttls_auto = server.use_tls
|
|
openssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
user_name = user.login
|
|
end
|
|
Mail.defaults do
|
|
delivery_method :smtp, {:address => server.name,
|
|
:port => server.port,
|
|
:domain => user.domain,
|
|
:user_name => user_name,
|
|
:password => password,
|
|
:authentication => authentication,
|
|
:enable_starttls_auto => enable_starttls_auto,
|
|
:openssl_verify_mode => openssl_verify_mode
|
|
}
|
|
end
|
|
end
|
|
|
|
end
|