diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d1bc6ad..97b6f01 100755 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,7 +3,9 @@ require 'yaml' class ApplicationController < ActionController::Base protect_from_forgery + before_filter :load_defaults,:current_user,:set_locale + before_filter :plugins_configuration rescue_from ActiveRecord::RecordNotFound do @@ -12,14 +14,14 @@ class ApplicationController < ActionController::Base redirect_to :controller=>'user', :action => 'login' end + def load_defaults + $defaults ||= YAML::load(File.open(Rails.root.join('config','defaults.yml'))) + end + ################################# protected section ########################################### protected - def load_defaults - $defaults ||= YAML::load(File.open(Rails.root.join('config','defaults.yml'))) - end - def theme_resolver if @current_user.nil? $defaults['theme'] @@ -49,24 +51,35 @@ class ApplicationController < ActionController::Base end def selected_folder - session[:selected_folder] ? @selected_folder = session[:selected_folder] : @selected_folder = $defaults['mailbox_inbox'] + if session[:selected_folder] + @selected_folder = session[:selected_folder] + else + folder = @current_user.folders.inbox.first + if not folder.nil? + @selected_folder = folder.full_name + end + end end def get_current_folders @folders_shown = @current_user.folders.shown.order("name asc") - @current_folder = @current_user.folders.find_by_full_name(@selected_folder) + if not @selected_folder.nil? + @current_folder = @current_user.folders.find_by_full_name(@selected_folder) + end end def self.decode_quoted(text,unknown_charset = $defaults["msg_unknown_charset"]) begin - if text.=~(/=\?/).nil? + if text.match(/\=\?.+\?\w\?.+\?\=/).nil? after = Iconv.conv('UTF-8',unknown_charset,text) #after = text else -# TODO support multiple showing of =?xxx?= - text =~ /(=\?.+\?=)/ + +# FIXME support multiple showing of =?xxx?= + + after = text - match = $1 + match = text.match(/\=\?.+\?\w\?.+\?\=/).to_s f = match.split(/\?/) case f[2].downcase when 'q': @@ -85,6 +98,7 @@ class ApplicationController < ActionController::Base end end + #logger.custom('after',after) return after rescue Exception => e logger.error("Class Message: #{e.to_s}: T: #{text} M: #{match} R: #{replace} A: #{after}") diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb index f165d2f..9c2e149 100755 --- a/app/controllers/contacts_controller.rb +++ b/app/controllers/contacts_controller.rb @@ -1,8 +1,6 @@ class ContactsController < ApplicationController - before_filter :check_current_user,:selected_folder - - before_filter :get_current_folders + before_filter :check_current_user,:selected_folder, :get_current_folders before_filter :get_contacts, :only => [:index] diff --git a/app/controllers/folders_controller.rb b/app/controllers/folders_controller.rb index 6d753f9..f183acc 100755 --- a/app/controllers/folders_controller.rb +++ b/app/controllers/folders_controller.rb @@ -6,34 +6,36 @@ class FoldersController < ApplicationController include ImapMailboxModule include ImapSessionModule - before_filter :check_current_user ,:selected_folder + before_filter :check_current_user,:selected_folder, :get_current_folders - before_filter :open_imap_session, :except => [:index,:show_hide] - after_filter :close_imap_session, :except => [:index,:show_hide] + before_filter :open_imap_session, :except => [:index,:show_hide,:system] + after_filter :close_imap_session, :except => [:index,:show_hide,:system] before_filter :get_folders theme :theme_resolver def index - + @buttons = [] + @buttons << {:text => 'show_hide',:image => 'tick.png'} + @buttons << {:text => 'refresh',:image => 'tick.png'} end def create - if params["folder"].empty? + if params[:folder][:target].empty? flash[:warning] = t(:to_create_empty,:scope=>:folder) render "index" else begin #TODO recreate local copy of folders - if params["parent_folder"].empty? - @mailbox.create_folder(params[:folder]) + if params[:folder][:parent].empty? + @mailbox.create_folder(params[:folder][:target]) else - parent_folder = @current_user.folders.find(params["parent_folder"]) + parent_folder = @current_user.folders.find(params[:folder][:parent]) if parent_folder.depth >= $defaults["mailbox_max_parent_folder_depth"].to_i raise Exception, t(:max_depth,:scope=>:folder) end - @mailbox.create_folder(parent_folder.full_name + parent_folder.delim + params[:folder]) + @mailbox.create_folder(parent_folder.full_name + parent_folder.delim + params[:folder][:target]) end rescue Exception => e flash[:error] = t(:can_not_create,:scope=>:folder) + ' (' + e.to_s + ')' @@ -46,25 +48,18 @@ class FoldersController < ApplicationController end def delete - if params["folder"].empty? + if params[:folder][:delete].empty? flash[:warning] = t(:to_delete_empty,:scope=>:folder) render "index" else begin - folder = @current_user.folders.find(params["folder"]) - system_folders = Array.new - system_folders << $defaults["mailbox_inbox"] - system_folders << $defaults["mailbox_trash"] - system_folders << $defaults["mailbox_sent"] - system_folders << $defaults["mailbox_drafts"] - if system_folders.include?(folder.full_name.downcase) - raise Exception, t(:system_folder) + folder = @current_user.folders.find(params[:folder][:delete]) + if @folders_system.include?(folder) + raise Exception, t(:system,:scope=>:folder) end @mailbox.delete_folder(folder.full_name) - logger.custom('c',@current_folder.inspect) - logger.custom('f',folder.inspect) if @current_folder.eql? folder - session[:selected_folder] = $defaults['mailbox_inbox'] + session[:selected_folder] = nil end folder.destroy rescue Exception => e @@ -77,25 +72,48 @@ class FoldersController < ApplicationController end end - def show_hide - if !params["folders_to_show"].nil? - @folders.each do |f| - if params["folders_to_show"].include?(f.id.to_s) - f.shown = true - f.save - else - f.shown = false - f.save - end + def system + logger.custom('sss',params[:folder].inspect) + @folders.each do |f| + logger.custom('s',f.inspect) + if f.isSystem? + f.setNone end - end + if f.id == params[:folder][:mailbox_inbox].to_i + f.setInbox + end + if f.id == params[:folder][:mailbox_sent].to_i + f.setSent + end + if f.id == params[:folder][:mailbox_trash].to_i + f.setTrash + end + if f.id == params[:folder][:mailbox_drafts].to_i + f.setDrafts + end + end redirect_to :action => 'index' end def refresh - Folder.refresh(@mailbox,@current_user) - flash.keep - redirect_to :action => 'index' + # TODO save system folders + if params[:refresh] + Folder.refresh(@mailbox,@current_user) + flash.keep + elsif params[:show_hide] + if !params["folders_to_show"].nil? + @folders.each do |f| + if params["folders_to_show"].include?(f.id.to_s) + f.shown = true + f.save + else + f.shown = false + f.save + end + end + end + end + redirect_to :action => 'index' end def select @@ -114,7 +132,10 @@ class FoldersController < ApplicationController def emptybin begin - trash_folder = @current_user.folders.find_by_full_name($defaults["mailbox_trash"]) + trash_folder = @current_user.folders.trash.first + if trash_folder.nil? + raise Exception, t(:not_configured_trash,:scope=>:folder) + end @mailbox.set_folder(trash_folder.full_name) trash_folder.messages.each do |m| @mailbox.delete_message(m.uid) @@ -134,16 +155,13 @@ class FoldersController < ApplicationController protected def get_folders - @folders = @current_user.folders.order("name asc") - @folders_shown = [] - @folders.each do |f| - if f.shown == true - @folders_shown << f - end - if f.selected?(@selected_folder) - @current_folder = f - end - end + @folders = @current_user.folders + @folders_shown = @current_user.folders.shown + #@folders_system = @current_user.folders.sys + @current_user.folders.inbox.first.nil? ? @folder_inbox = "" : @folder_inbox = @current_user.folders.inbox.first.id + @current_user.folders.drafts.first.nil? ? @folder_drafts = "" : @folder_drafts = @current_user.folders.drafts.first.id + @current_user.folders.sent.first.nil? ? @folder_sent = "" : @folder_sent = @current_user.folders.sent.first.id + @current_user.folders.trash.first.nil? ? @folder_trash = "" : @folder_trash = @current_user.folders.trash.first.id end end diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 33d8fee..f440f40 100755 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -2,6 +2,7 @@ require 'imap_session' require 'imap_mailbox' require 'imap_message' require 'mail' +require 'mail_plugin_extension' class MessagesController < ApplicationController @@ -13,13 +14,25 @@ class MessagesController < ApplicationController before_filter :check_current_user ,:selected_folder,:get_current_folders before_filter :open_imap_session, :select_imap_folder + + before_filter :prepare_buttons, :only => [:compose,:reply,:edit,:sendout_or_save] + + #before_filter :mail_defaults, :only => [:sendout_or_save] + + before_filter :get_system_folders, :only => [:index,:ops,:sendout_or_save] + after_filter :close_imap_session theme :theme_resolver def index + if @sent_folder.nil? || @drafts_folder.nil? || @inbox_folder.nil? || @trash_folder.nil? + flash[:warning] = t(:not_all_configured,:scope => :folder) + end + if @current_folder.nil? + flash[:warning] = t(:no_selected,:scope => :folder) redirect_to :controller => 'folders', :action => 'index' return end @@ -32,6 +45,12 @@ class MessagesController < ApplicationController folder_status['MESSAGES'].zero? ? uids_remote = [] : uids_remote = @mailbox.fetch_uids uids_local = @current_user.messages.where(:folder_id => @current_folder).collect(&:uid) + logger.custom('current_folder',@current_folder.inspect) + logger.custom('uids_local',uids_local.join(",")) + logger.custom('uids_remote',uids_remote.join(",")) + logger.custom('to_delete',(uids_local-uids_remote).join(",")) + logger.custom('to_fetch',(uids_remote-uids_local).join(",")) + (uids_local-uids_remote).each do |uid| @current_folder.messages.find_by_uid(uid).destroy end @@ -49,16 +68,123 @@ class MessagesController < ApplicationController def compose @message = Message.new + if params[:message] + @message = update_attributes(params[:message]) + end end def reply + + attachments = [] + body = '' + + old_message = @current_user.messages.find(params[:id]) @message = Message.new + @message.to_addr = address_formatter(old_message.from_addr,:raw) + @message.subject = old_message.subject + @reply = true + imap_message = @mailbox.fetch_body(old_message.uid) + mail = Mail.new(imap_message) + if mail.multipart? + Attachment.fromMultiParts(attachments,old_message.id,mail.parts) + else + Attachment.fromSinglePart(attachments,old_message.id,mail) + end + + for idx in 0..attachments.size-1 + if attachments[idx].isText? + body << attachments[idx].decode_and_charset + break + end + end + @message.body = body render 'compose' end - def sendout - flash[:notice] = t(:was_sent,:scope => :sendout) - redirect_to :action => 'index' + def edit + + attachments = [] + body = '' + + old_message = @current_user.messages.find(params[:id]) + @message = Message.new + @message.to_addr = address_formatter(old_message.to_addr,:raw) + @message.subject = old_message.subject + imap_message = @mailbox.fetch_body(old_message.uid) + mail = Mail.new(imap_message) + if mail.multipart? + Attachment.fromMultiParts(attachments,old_message.id,mail.parts) + else + Attachment.fromSinglePart(attachments,old_message.id,mail) + end + + for idx in 0..attachments.size-1 + if attachments[idx].isText? + body << attachments[idx].decode_and_charset + break + end + end + @message.body = body + render 'compose' + end + + def sendout_or_save + + mail = Mail.new + mail.subject = params[:message][:subject] + mail.from = @current_user.full_address + mail.to = params[:message][:to_addr] + mail.body = params[:message][:body] + mail.add_file :filename => 'somefile.png', :content => File.read('/tmp/script_monitor_20110810143216.log') + + if params[:send] + smtp_server = @current_user.servers.primary_for_smtp + + if smtp_server.nil? + flash[:error] = t(:not_configured_smtp,:scope => :compose) + @message = Message.new + if params[:message] + @message = update_attributes(params[:message]) + end + render 'compose' + return + end + + begin + + set_mail_defaults(@current_user,smtp_server,session) + #logger.custom('mail',Mail.delivery_method.inspect) + + @response = mail.deliver! + #logger.custom('response',@response.inspect) + + if @sent_folder.nil? + raise t(:not_configured_sent,:scope=>:compose) + end + @mailbox.append(@sent_folder.full_name,mail.to_s,[:Seen]) + + rescue Exception => e + flash[:error] = "#{t(:imap_error)} (#{e.to_s})" + redirect_to :action => 'index' + return + end + flash[:notice] = t(:was_sent,:scope => :compose) + redirect_to :action => 'index' + elsif params[:save_as_draft] + begin + if @drafts_folder.nil? + raise t(:not_configured_drafts,:scope=>:compose) + end + # TODO delete old one if was edit + @mailbox.append(@drafts_folder.full_name,mail.to_s,[:Seen]) + rescue Exception => e + flash[:error] = "#{t(:imap_error)} (#{e.to_s})" + redirect_to :action => 'index' + return + end + flash[:notice] = t(:was_saved,:scope => :compose) + redirect_to :action => 'index' + end end def msgops @@ -90,20 +216,21 @@ class MessagesController < ApplicationController @current_user.messages.find_by_uid(uid).update_attributes(:unseen => 0) end elsif params["trash"] - dest_folder = @current_user.folders.find_by_full_name($defaults["mailbox_trash"]) - params["uids"].each do |uid| - @mailbox.move_message(uid,dest_folder.full_name) - message = @current_folder.messages.find_by_uid(uid) - message.change_folder(dest_folder) + if not @trash_folder.nil? + 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 - @mailbox.expunge - dest_folder.update_stats - @current_folder.update_stats elsif params["copy"] - if params["dest_folder"].empty? + if params[:folder][:target].empty? flash[:warning] = t(:no_selected,:scope=>:folder) else - dest_folder = @current_user.folders.find(params["dest_folder"]) + 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) @@ -115,10 +242,10 @@ class MessagesController < ApplicationController @current_folder.update_stats end elsif params["move"] - if params["dest_folder"].empty? + if params[:folder][:target].empty? flash[:warning] = t(:no_selected,:scope=>:folder) else - dest_folder = @current_user.folders.find(params["dest_folder"]) + dest_folder = @current_user.folders.find(params[:folder][:target]) params["uids"].each do |uid| @mailbox.move_message(uid,dest_folder.full_name) message = @current_folder.messages.find_by_uid(uid) @@ -136,33 +263,91 @@ class MessagesController < ApplicationController end def show - logger.custom('start',Time.now) - @attachments = [] - @render_as_text = [] - @render_as_html_idx = nil + @images = [] + @attachments = [] + @text_part = nil + @html_part = nil @message = @current_user.messages.find_by_uid(params[:id]) @message.update_attributes(:unseen => false) - logger.custom('start_fetch',Time.now) imap_message = @mailbox.fetch_body(@message.uid) - logger.custom('stop_fetch',Time.now) - parts = imap_message.split(/\r\n\r\n/) - @message_header = parts[0] - logger.custom('before_parse',Time.now) - @mail = Mail.new(imap_message) - logger.custom('after_parse',Time.now) - if @mail.multipart? - Attachment.fromMultiParts(@attachments,@message.id,@mail.parts) - else - Attachment.fromSinglePart(@attachments,@message.id,@mail) - end - logger.custom('attach',Time.now) - for idx in 0..@attachments.size-1 - @attachments[idx].isText? ? @render_as_text << @attachments[idx].decode_and_charset : @render_as_text - @attachments[idx].isHtml? ? @render_as_html_idx ||= idx : @render_as_html_idx - end - logger.custom('done',Time.now) + mail = Mail.new(imap_message) + @plain_header = mail.header.to_s + @from = mail.From.addrs + @to = mail.To.addrs + @cc = mail.Cc + @bcc = mail.Bcc + @subject = mail.Subject + @date = mail.date + + if mail.multipart? == true + if not mail.text_part.nil? + @text_part = mail.text_part.decoded_and_charseted + end + if not mail.html_part.nil? + @html_part = mail.html_part.decoded_and_charseted + end + attachments = mail.attachments + if not attachments.size.zero? + for idx in 0..attachments.size - 1 + a = attachments[idx] + a.idx = idx + a.parent_id = @message.uid + if a.isImage? + @images << a + else + @attachments << a + end + end + end + else + part = Mail::Part.new(mail) + part.idx = 0 + part.parent_id = @message.uid + if part.isText? + @text_part = part.decoded_and_charseted + elsif part.isImage? + @images << part + elsif part.isHtml? + @html_part = part.decoded_and_charseted + else + @attachments << part + end + end + + + #@attachments = [] + #logger.custom('after_parse',Time.now) + #if mail.multipart? + # Attachment.fromMultiParts(@attachments,@message.id,@mail.parts) + #else + # Attachment.fromSinglePart(@attachments,@message.id,@mail) +# end + #logger.custom('attach',Time.now) + +# for idx in 0..@attachments.size-1 +# @attachments[idx].idx = idx +# @attachments[idx].isText? ? @render_as_text << @attachments[idx].decode_and_charset : @render_as_text +# @attachments[idx].isHtml? ? @render_as_html_idx ||= idx : @render_as_html_idx +# @attachments[idx].isImageAndNotCid? ? @images << @attachments[idx] : @images +# end + #logger.custom('done',Time.now) + #@attachments = @mail.attachments + end + + def html_body + message = @current_user.messages.find(params[:id]) + mail = Mail.new(@mailbox.fetch_body(message.uid)) + if mail.multipart? + @body = mail.html_part.decoded_and_charseted + else + @body = mail.decoded_and_charseted + end + if @body.nil? + @body = t(:no_body,:scope=>:message) + end + render 'html_body',:layout => 'html_body' end def body @@ -204,4 +389,46 @@ class MessagesController < ApplicationController render :text => a.decode end + ############################################# protected section ########################################## + + def prepare_buttons + @buttons = [] + @buttons << {:text => 'send',:image => 'tick.png'} + @buttons << {:text => 'save_as_draft',:image => 'tick.png'} + end + + 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.full_address + 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 + + def get_system_folders + @drafts_folder = @current_user.folders.drafts.first + @sent_folder = @current_user.folders.sent.first + @inbox_folder = @current_user.folders.inbox.first + @trash_folder = @current_user.folders.trash.first + end + end diff --git a/app/controllers/prefs_controller.rb b/app/controllers/prefs_controller.rb index b1ac2ed..d1bfc38 100755 --- a/app/controllers/prefs_controller.rb +++ b/app/controllers/prefs_controller.rb @@ -4,21 +4,42 @@ class PrefsController < ApplicationController before_filter :get_current_folders - before_filter :get_prefs + before_filter :get_prefs, :only => [:look,:update_look] theme :theme_resolver - def index - end - - def update + def update_look if params[:prefs] @prefs.update_attributes(params[:prefs]) end - redirect_to :action => 'index' + redirect_to :action => 'look' end - ############################################ private section ######################################### + def update_servers + + redirect_to :action => 'servers' + end + + def update_identity + if params[:user] + @current_user.update_attributes(params[:user]) + end + redirect_to :action => 'identity' + end + + def look + + end + + def identity + @identity = @curent_user + end + + def servers + @servers = @current_user.servers + end + + ############################# protected section ################################## def get_prefs @prefs = @current_user.prefs diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 42b2497..ad2e7b1 100755 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -61,9 +61,10 @@ class UserController < ApplicationController if @user.valid? and @server.valid? @user.save - @server.user_id = @user.id - @server.save - Prefs.create_default(@user.id) + #@server.user_id = @user.id + #@server.save + Prefs.create_default(@user) + Server.create_defaults(@user) flash[:notice] = t(:setup_done,:scope=>:user) redirect_to :action => 'login' else diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c498d6a..01ac0a2 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,3 +1,5 @@ +require 'iconv' + module ApplicationHelper def form_field(object,field,flabel,example,val) @@ -36,7 +38,7 @@ def form_field(object,field,flabel,example,val) end -def mail_param_view(object,field,value) +def show_param_view(object,field,value) model_name = eval(object.class.model_name) html = "" html << "
" + #html << text.gsub!(/\r\n/,"\n") html << h(text) html << "" html diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 89417c8..d22472b 100755 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -1,3 +1,4 @@ + class Attachment include ActiveModel::Validations include ActiveModel::Conversion @@ -19,7 +20,9 @@ class Attachment if p =~ /=/ fields = p.split(/=/) key = fields[0] - value = fields[1] + fields.delete_at(0) + value = fields.join("=") + # FIXME maybe do decoding only for name and filename key if Attachment.attribute_method?(key) == true send("#{key}=", ApplicationController.decode_quoted(value)) end @@ -111,6 +114,10 @@ class Attachment @type =~ /^text\/html/ end + def isImageAndNotCid? + @type =~ /^image/ and @cid.size.zero? + end + def title @description.nil? ? name : @description end diff --git a/app/models/folder.rb b/app/models/folder.rb index c3dfc97..00ace6c 100755 --- a/app/models/folder.rb +++ b/app/models/folder.rb @@ -5,6 +5,20 @@ class Folder < ActiveRecord::Base before_save :check_fill_params, :on => :create has_many :messages, :dependent => :destroy + SYS_NONE = 0 + SYS_TRASH = 1 + SYS_INBOX = 2 + SYS_SENT = 3 + SYS_DRAFTS = 4 + + default_scope :order => 'name asc' + scope :shown, where(['shown = ?',true]) + scope :inbox, where(['sys = ?',SYS_INBOX]) + scope :sent, where(['sys = ?',SYS_SENT]) + scope :drafts, where(['sys = ?',SYS_DRAFTS]) + scope :trash, where(['sys = ?',SYS_TRASH]) + scope :sys, where(['sys > ?',SYS_NONE]) + def full_name if parent.empty? name @@ -33,6 +47,48 @@ class Folder < ActiveRecord::Base full_name.downcase == folder_name.downcase end + def isSystem? + sys > SYS_NONE + end + + def isTrash? + sys == SYS_TRASH + end + + def isSent? + sys == SYS_SENT + end + + def isInbox? + sys == SYS_INBOX + end + + def isDrafts? + sys == SYS_DRAFTS + end + + def setNone + update_attributes(:sys => SYS_NONE) + end + + def setTrash + update_attributes(:sys => SYS_TRASH) + end + + def setSent + update_attributes(:sys => SYS_SENT) + end + + def setInbox + update_attributes(:sys => SYS_INBOX) + end + + def setDrafts + update_attributes(:sys => SYS_DRAFTS) + end + + + ############################################## private section ##################################### private @@ -43,6 +99,7 @@ class Folder < ActiveRecord::Base self.parent.nil? ? self.parent = "" : self.parent self.haschildren.nil? ? self.haschildren = false : self.haschildren self.delim.nil? ? self.delim = "." : self.delim + self.sys.nil? ? self.sys = SYS_NONE : self.sys end def self.createBulk(user,imapFolders) @@ -64,7 +121,8 @@ class Folder < ActiveRecord::Base :haschildren => has_children, :delim => data.delim, :total => data.messages, - :unseen => data.unseen) + :unseen => data.unseen, + :sys => SYS_NONE) end end @@ -76,16 +134,10 @@ class Folder < ActiveRecord::Base where(['name = ? and parent = ?',nam,par]).first end - def self.shown - where(['shown = ?',true]) - end - def self.refresh(mailbox,user) user.folders.destroy_all folders=mailbox.folders Folder.createBulk(user,folders) end - - end diff --git a/app/models/message.rb b/app/models/message.rb index 31a1110..3169452 100755 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -6,7 +6,8 @@ class Message < ActiveRecord::Base belongs_to :folder set_primary_key :uid - attr_accessible :unseen, :to_addr, :size, :content_type, :folder_id, :subject, :date, :uid, :from_addr, :user_id, :msg_id + attr_accessible :unseen, :to_addr, :size, :content_type, :folder_id, :subject, :date, :uid, :from_addr, :user_id, :msg_id, :body,:cc_addr,:bcc_addr + attr_accessor :body def self.addr_to_db(addr) ret = "" @@ -33,9 +34,8 @@ class Message < ActiveRecord::Base envelope = imap_message.attr['ENVELOPE'] - from = addr_to_db(envelope.from[0]) - to = addr_to_db(envelope.to[0]) - + envelope.from.nil? ? from = "" : from = addr_to_db(envelope.from[0]) + envelope.to.nil? ? to = "" : to = addr_to_db(envelope.to[0]) envelope.subject.nil? ? subject = "" : subject = ApplicationController.decode_quoted(envelope.subject) create( @@ -57,5 +57,4 @@ class Message < ActiveRecord::Base update_attributes(:folder_id => folder.id) end - end diff --git a/app/models/prefs.rb b/app/models/prefs.rb index e495248..7285eea 100755 --- a/app/models/prefs.rb +++ b/app/models/prefs.rb @@ -6,8 +6,8 @@ class Prefs < ActiveRecord::Base protected - def self.create_default(user_id) - Prefs.create(:user_id => user_id, + def self.create_default(user) + Prefs.create(:user_id => user.id, :theme => $defaults['theme'], :locale => $defaults['locale'], :msgs_per_page => $defaults['msgs_per_page'], diff --git a/app/models/server.rb b/app/models/server.rb index ef08784..02b4f41 100755 --- a/app/models/server.rb +++ b/app/models/server.rb @@ -2,17 +2,40 @@ class Server < ActiveRecord::Base validates_presence_of :name belongs_to :user - before_save :fill_params + #before_save :fill_params - def self.primary - first + def self.primary_for_imap + where(:for_imap=>true).first end - private + def self.primary_for_smtp + where(:for_smtp=>true).first + end - def fill_params - self.port = $defaults['imap_port'] - $defaults['imap_use_ssl'] == true ? self.use_ssl = 1 : self.use_ssl = 0 - end + def self.create_defaults(user) + create( :user_id=>user.id, + :name=>"localhost", + :port=>$defaults['imap_port'], + :use_ssl=>false, + :use_tls=>false, + :for_smtp=>false, + :for_imap=>true + ) + create( :user_id=>user.id, + :name=>"localhost", + :port=>$defaults['smtp_port'], + :use_ssl=>false, + :use_tls=>false, + :for_smtp=>true, + :for_imap=>false + ) + end + +# private + +# def fill_params +# port.nil? ? port = $defaults['imap_port'] : port +# $defaults['imap_use_ssl'] == true ? self.use_ssl = 1 : self.use_ssl = 0 +# end end diff --git a/app/models/user.rb b/app/models/user.rb index cb11571..9a72af4 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,4 +31,16 @@ class User < ActiveRecord::Base (0...8).map{65.+(rand(25)).chr}.join end + def full_name + first_name + " " + last_name + end + + def full_address + if email =~ /\@/ + email + else + email + "@" + domain + end + end + end diff --git a/config/defaults.yml b/config/defaults.yml index 28b669a..21d249f 100755 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -30,14 +30,12 @@ imap_ssl_port: 993 imap_bye_timeout_retry_seconds: 2 imap_fetch_slice: 20 +smtp_port: 25 + session_encryption: true session_password: asDD3s2@sAdc983# mailbox_max_parent_folder_depth: 3 -mailbox_inbox: INBOX -mailbox_trash: INBOX.Trash -mailbox_sent: INBOX.sent -mailbox_drafts: INBOX.drafts # array of logins which only can login to application, comment it to allow everyone to login -only_can_logins: [some_login] +only_can_logins: [soldier] diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 9a2bcf7..892841a 100755 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -29,6 +29,8 @@ pl: size: Rozmiar date: Data body: Treść + cc_addr: Dw + bcc_addr: UDw user: email: E-mail password: Hasło @@ -53,14 +55,18 @@ pl: prefs: prefs: Ustawienia + look: Wygląd + identity: Tożsamość + servers: Serwery folder: + folder: Folder folders: Foldery no_shown: Nie prezentowany jest żaden folder. Skonfiguruj widok folderów w zakładce parent: Folder nadrzędny to_create: Folder do utworzenia to_delete: Folder do usunięcia - shown: Foldery pokazane + shown: Wyświetlane foldery emptybin: Opróżnij current: Folder bieżący no_selected: Nie wybrano żadnego folderu @@ -72,6 +78,12 @@ pl: can_not_delete: Nie można usunąć folderu was_deleted: Folder został usunięty to_folder: do folderu + system: Folder systemowy + not_all_configured: Nie wszystkie systemowe foldery zostały skonfigurowane + inbox_name: Odebrane + sent_name: Wysłane + trash_name: Kosz + drafts_name: Roboczy message: messages: Wiadomości @@ -87,6 +99,8 @@ pl: content: Treść wiadomości header_source: Nagłówek wiadomości show_header: Pokaż nagłówek + edit: Edycja + images: Obrazy compose: compose: Nowa wiadomość @@ -94,9 +108,14 @@ pl: not_contain_at: ",jeżeli nie zawiera znaku @, adres będzie szukany w kontaktach" subject_of_the_message: Temat wiadomości write_your_message_here: Tu wpisz swoją wiadomość - - sendout: was_sent: Wiadomość została wysłana + was_saved: Wiadomość została zapisana w katalogu roboczym + reply_string: "Odp: " + not_configured_smtp: Brak konfiguracji SMTP + not_configured_drafts: Folder Roboczy nie został przypisany + not_configured_sent: Folder Wysłany nie został przypisany + not_configured_trash: Folder Kosz nie został przypisany + not_configured_inbox: Folder Odebrane nie został przypisany show: replay_to: Odpowiedz @@ -141,4 +160,6 @@ pl: download: Pobierz view: Pokaż version: Wersja + save_as_draft: Zapisz w katalogu roboczym + set: Ustaw diff --git a/config/routes.rb b/config/routes.rb index edad3f2..471b348 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,14 @@ Mailr::Application.routes.draw do - match "prefs/index" => "prefs#index", :as => :prefs - post "prefs/update" + #match "prefs/index" => "prefs#index", :as => :prefs + + post "prefs/update_look" + post "prefs/update_identity" + post "prefs/update_servers" + + match "prefs/look" => "prefs#look", :as => :prefs_look + match "prefs/identity" => "prefs#identity", :as => :prefs_identity + match "prefs/servers" => "prefs#servers", :as => :prefs_servers resources :contacts post "contacts/ops" @@ -11,8 +18,9 @@ Mailr::Application.routes.draw do match "folders/index" => 'folders#index', :as => :folders post "folders/create" post "folders/delete" + post "folders/system" post "folders/show_hide" - get "folders/refresh" + post "folders/refresh" get "folders/refresh_status" post "folders/refresh" match "folders/select/:id" => 'folders#select', :as => :folders_select @@ -32,10 +40,12 @@ Mailr::Application.routes.draw do post "messages/ops" post "messages/msgops" match "messages/compose" => 'messages#compose' + match "messages/edit/:id" => 'messages#edit' ,:as => :messages_edit match "messages/reply/:id" => 'messages#reply' - post "messages/sendout" + match "messages/sendout_or_save" => 'messages#sendout_or_save' ,:as =>:sendout_or_save match "messages/show/:id" => 'messages#show' match "messages/body/:id/:idx" => 'messages#body' , :as => :messages_part_body + match "messages/html_body/:id" => 'messages#html_body' , :as => :messages_html_body match "messages/attachment/:id/:idx" => 'messages#attachment', :as => :messages_attachment_download get "user/logout" diff --git a/db/migrate/20110830070509_add_options_to_servers.rb b/db/migrate/20110830070509_add_options_to_servers.rb new file mode 100755 index 0000000..40f19c0 --- /dev/null +++ b/db/migrate/20110830070509_add_options_to_servers.rb @@ -0,0 +1,13 @@ +class AddOptionsToServers < ActiveRecord::Migration + def self.up + add_column :servers,:use_tls,:boolean + add_column :servers,:for_imap,:boolean + add_column :servers,:for_smtp,:boolean + end + + def self.down + remove_column :servers,:use_tls + remove_column :servers,:for_imap + remove_column :servers,:for_smtp + end +end diff --git a/db/migrate/20110830074142_add_domain_to_users.rb b/db/migrate/20110830074142_add_domain_to_users.rb new file mode 100755 index 0000000..12f7cb9 --- /dev/null +++ b/db/migrate/20110830074142_add_domain_to_users.rb @@ -0,0 +1,9 @@ +class AddDomainToUsers < ActiveRecord::Migration + def self.up + add_column :users, :domain, :string + end + + def self.down + remove_column :users, :domain + end +end diff --git a/db/migrate/20110831090041_add_type_to_folders.rb b/db/migrate/20110831090041_add_type_to_folders.rb new file mode 100755 index 0000000..25af170 --- /dev/null +++ b/db/migrate/20110831090041_add_type_to_folders.rb @@ -0,0 +1,9 @@ +class AddTypeToFolders < ActiveRecord::Migration + def self.up + add_column :folders, :sys, :integer + end + + def self.down + remove_column :folders, :sys + end +end diff --git a/db/migrate/20110901120826_add_auth_to_servers.rb b/db/migrate/20110901120826_add_auth_to_servers.rb new file mode 100755 index 0000000..89a0dd9 --- /dev/null +++ b/db/migrate/20110901120826_add_auth_to_servers.rb @@ -0,0 +1,9 @@ +class AddAuthToServers < ActiveRecord::Migration + def self.up + add_column :servers, :auth, :string + end + + def self.down + remove_column :servers, :auth + end +end diff --git a/db/schema.rb b/db/schema.rb index 19415c8..fd6d2d5 100755 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20110816120258) do +ActiveRecord::Schema.define(:version => 20110901120826) do create_table "contacts", :force => true do |t| t.string "nick" @@ -35,6 +35,7 @@ ActiveRecord::Schema.define(:version => 20110816120258) do t.string "parent" t.boolean "shown" t.string "alter_name" + t.integer "sys" end create_table "messages", :id => false, :force => true do |t| @@ -70,6 +71,10 @@ ActiveRecord::Schema.define(:version => 20110816120258) do t.datetime "created_at" t.datetime "updated_at" t.boolean "use_ssl" + t.boolean "use_tls" + t.boolean "for_imap" + t.boolean "for_smtp" + t.string "auth" end create_table "users", :force => true do |t| @@ -78,6 +83,7 @@ ActiveRecord::Schema.define(:version => 20110816120258) do t.string "last_name" t.datetime "created_at" t.datetime "updated_at" + t.string "domain" end end diff --git a/lib/imap_mailbox.rb b/lib/imap_mailbox.rb index 6f0fd1e..a589711 100755 --- a/lib/imap_mailbox.rb +++ b/lib/imap_mailbox.rb @@ -194,6 +194,14 @@ class IMAPMailbox end end + def append(folder,message,flags) + begin + @imap.append(folder,message,flags) + rescue Exception => e + raise e + end + end + end end diff --git a/lib/imap_session.rb b/lib/imap_session.rb index 8b915f3..8183cce 100755 --- a/lib/imap_session.rb +++ b/lib/imap_session.rb @@ -6,7 +6,7 @@ module ImapSessionModule def open_imap_session begin @mailbox ||= ImapMailboxModule::IMAPMailbox.new(logger,$defaults["imap_debug"]) - @mailbox.connect(@current_user.servers.primary,@current_user.email, @current_user.get_cached_password(session)) + @mailbox.connect(@current_user.servers.primary_for_imap,@current_user.email, @current_user.get_cached_password(session)) rescue Exception => ex redirect_to :controller => 'internal', :action => 'loginfailure' end diff --git a/lib/mail_plugin_extension.rb b/lib/mail_plugin_extension.rb new file mode 100755 index 0000000..4959332 --- /dev/null +++ b/lib/mail_plugin_extension.rb @@ -0,0 +1,45 @@ +require 'iconv' + +module Mail + + class Message + + def decoded_and_charseted + begin + if not charset.upcase == 'UTF-8' + charset.nil? ? source_charset = $defaults["msg_unknown_charset"] : source_charset = charset + charseted = Iconv.iconv("UTF-8",source_charset,decoded).first + else + charseted = decoded + end + rescue + decoded + end + + end + + end + + class Part + + attr_accessor :idx,:parent_id + + def isImage? + not (content_type =~ /^image/).nil? + end + + def isText? + not (content_type =~ /^text\/plain/).nil? + end + + def isHtml? + not (content_type =~ /^text\/html/).nil? + end + + def getSize + body.raw_source.size + end + + end + +end diff --git a/themes/olive/stylesheets/style.css b/themes/olive/stylesheets/style.css index ffa0545..13770ff 100755 --- a/themes/olive/stylesheets/style.css +++ b/themes/olive/stylesheets/style.css @@ -241,7 +241,6 @@ p { /* forms */ .form input.text_field, .form textarea.text_area { - width: 100%; border:1px solid #CFCFCF; } @@ -417,10 +416,6 @@ div.param_group label.label { margin-right: 5px; } -div.params { - margin-bottom: 15px; -} - div.params div.group { margin-bottom: 10px; } @@ -453,8 +448,7 @@ div.params div.group div.fieldWithErrors label.label, div.params div.group label font-size: 14px; } -div.params input.text_field, div.params textarea.text_area { - width: 100%; +div.params input, div.params textarea, div.params select { border:1px solid #CFCFCF; } @@ -518,3 +512,29 @@ span.attachment pre { span.attachment span.title { font-weight: bold; } + +div.images { + margin: 15px 0 5px; +} + +div.images span.title { + font-weight: bold; + display: block; + font-size: 14px; + margin-bottom: 5px; +} + +div.images div.image { + margin: 5px; + padding: 2px; +} + +div.images div.image div.desc { + font-weight: normal; + font-size: 10px; + padding: 2px; +} + +div.params input,div.params select,div.params textarea { + width: 100% +} diff --git a/themes/olive/views/folders/_create.html.erb b/themes/olive/views/folders/_create.html.erb new file mode 100755 index 0000000..627455c --- /dev/null +++ b/themes/olive/views/folders/_create.html.erb @@ -0,0 +1,7 @@ +<%= form_tag(folders_create_path) %> +
-<%= t(:version) %>: Build 20110826 +<%= t(:version) %>: Build 20110901
diff --git a/themes/olive/views/folders/_refresh.html.erb b/themes/olive/views/folders/_refresh.html.erb new file mode 100755 index 0000000..5932f29 --- /dev/null +++ b/themes/olive/views/folders/_refresh.html.erb @@ -0,0 +1,7 @@ +<%= form_tag(folders_refresh_path) %> +