diff --git a/README b/README index 6a4374f..c41a035 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Installation Guide Requirements - * Ruby 1.8.7 + * Ruby 1.8.7 * Rails 2.3.2 Installation @@ -14,18 +14,21 @@ Installation LOCALCONFIG = { :imap_server => 'your.imap.server' - } + } end 3. Configure SMTP settings # initializers/smtp_settings.rb - ActionMailer::Base.smtp_settings = { - :address => "mail.example.com.py", - :port => 26, - :authentication => :plain, - :enable_starttls_auto => true, - :user_name => "emilio@example.com.py", - :password => "yourpass" + ActionMailer::Base.smtp_settings = { + :address => "mail.example.com.py", + :port => 26, + :authentication => :plain, + :enable_starttls_auto => true, + :user_name => "emilio@example.com.py", + :password => "yourpass" } - 4 Use it + 4. Prepare config/database.yml file (see config/database.yml.example) + 5. Migrate database (rake db:migrate) + + 6. Use it diff --git a/app/controllers/webmail_controller.rb b/app/controllers/webmail_controller.rb index 565d8be..2500697 100644 --- a/app/controllers/webmail_controller.rb +++ b/app/controllers/webmail_controller.rb @@ -6,55 +6,55 @@ require 'ezcrypto' class WebmailController < ApplicationController include ImapUtils - + # Administrative functions before_filter :login_required before_filter :obtain_cookies_for_search_and_nav, :only=>[:messages] before_filter :load_imap_session after_filter :close_imap_session - + layout "public", :except => [:view_source, :download] - + # model :filter, :expression, :mail_pref, :customer - + BOOL_ON = "on" - + def index redirect_to(:action=>"messages") end - + def error_connection end - + def refresh @mailbox.reload @folders = @mailbox.folders redirect_to(:action=>'messages') end - + def messages session["return_to"] = nil @search_field = params['search_field'] @search_value = params['search_value'] - + # handle sorting - tsort session field contains last reverse or no for field # and lsort - last sort field if session['tsort'].nil? or session['lsort'].nil? session['lsort'] = "DATE" session['tsort'] = {"DATE" => true, "FROM" => true, "SUBJECT" => true, "TO" => false} end - + case operation_param when t(:copy) # copy msg_ids = [] - messages_param.each { |msg_id, bool| + messages_param.each { |msg_id, bool| msg_ids << msg_id.to_i if bool == BOOL_ON and dst_folder != @folder_name } if messages_param - folder.copy_multiple(msg_ids, dst_folder) if msg_ids.size > 0 + folder.copy_multiple(msg_ids, dst_folder) if msg_ids.size > 0 when t(:move) # move msg_ids = [] - messages_param.each { |msg_id, bool| + messages_param.each { |msg_id, bool| msg_ids << msg_id.to_i if bool == BOOL_ON and dst_folder != @folder_name } if messages_param - folder.move_multiple(msg_ids, dst_folder) if msg_ids.size > 0 + folder.move_multiple(msg_ids, dst_folder) if msg_ids.size > 0 when t(:delete) # delete msg_ids = [] messages_param.each { |msg_id, bool| msg_ids << msg_id.to_i if bool == BOOL_ON } if messages_param @@ -67,10 +67,10 @@ class WebmailController < ApplicationController session['lsort'] = sort_query = params["scc"] session['tsort'][sort_query] = (session['tsort'][sort_query]? false : true) @search_field, @search_value = session['search_field'], session['search_value'] - when t(:search) # search + when t(:search) # search session['search_field'] = @search_field session['search_value'] = @search_value - when t(:show_all) # search + when t(:show_all) # search session['search_field'] = @search_field = nil session['search_value'] = @search_value = nil else @@ -78,7 +78,7 @@ class WebmailController < ApplicationController @search_field = session['search_field'] @search_value = session['search_value'] end - + sort_query = session['lsort'] reverse_sort = session['tsort'][sort_query] query = ["ALL"] @@ -89,42 +89,50 @@ class WebmailController < ApplicationController @pages = Paginator.new self, 0, get_mail_prefs.wm_rows, @page @messages = folder.messages_search([@search_field, @search_value], sort_query + (reverse_sort ? ' desc' : ' asc')) else + + logger.info "total #{folder.total}" + logger.info "prews #{get_mail_prefs.wm_rows}" + logger.info "@page #{@page.inspect}" + logger.info "========================folder #{folder.messages.count}" + @pages = Paginator.new self, folder.total, get_mail_prefs.wm_rows, @page @messages = folder.messages(@pages.current.first_item - 1, get_mail_prefs.wm_rows, sort_query + (reverse_sort ? ' desc' : ' asc')) + logger.info "========================folder after #{folder.messages.count}" + end - + end - + def delete @msg_id = msg_id_param.to_i folder.delete(@msg_id) redirect_to(:action=>"messages") end - + def reply # not ready at all @msg_id = msg_id_param.to_i @imapmail = folder.message(@msg_id) fb = @imapmail.full_body - @tmail = TMail::Mail.parse(fb) - + @tmail = TMail::Mail.parse(fb) + @mail = prepare_mail @mail.reply(@tmail, fb, get_mail_prefs.mail_type) - + render :action => 'compose' end - + def forward @msg_id = msg_id_param.to_i @imapmail = folder.message(@msg_id) fb = @imapmail.full_body - @tmail = TMail::Mail.parse(fb) - + @tmail = TMail::Mail.parse(fb) + @mail = prepare_mail @mail.forward(@tmail, fb) - + render :action => 'compose' end - + def compose if @mail.nil? operation = operation_param @@ -133,13 +141,13 @@ class WebmailController < ApplicationController encmail = @mail.send_mail get_imap_session @mailbox.message_sent(encmail) - + # delete temporary files (attachments) @mail.delete_attachments() render :action => :mailsent elsif operation == t(:add) @mail = create_mail - if params['attachment'] + if params['attachment'] attachment = CDF::Attachment.new(@mail) attachment.file = params['attachment'] end @@ -149,7 +157,7 @@ class WebmailController < ApplicationController end end end - + def empty # empty trash folder (works for any one else :-)) folder.messages(0, -1).each{ |message| folder.delete(message) @@ -157,50 +165,50 @@ class WebmailController < ApplicationController folder.expunge redirect_to(:action=>"messages") end - + def message @msg_id = msg_id_param @imapmail = folder.message(@msg_id) folder.mark_read(@imapmail.uid) if @imapmail.unread @mail = TMail::Mail.parse(@imapmail.full_body) end - + def download msg_id = msg_id_param imapmail = folder.message(msg_id) - mail = TMail::Mail.parse(imapmail.full_body) - + mail = TMail::Mail.parse(imapmail.full_body) + if mail.multipart? - get_parts(mail).each { |part| - return send_part(part) if part.header and part.header['content-type']['name'] == params['ctype'] + get_parts(mail).each { |part| + return send_part(part) if part.header and part.header['content-type']['name'] == params['ctype'] } render("webmail/noattachment") - else + else render("webmail/noattachment") - end + end end - + def prefs @customer = Customer.find(logged_customer) @mailpref = MailPref.find_or_create_by_customer_id logged_customer - + if params['op'] == _('Save') if params['customer'] @customer.fname = params['customer']['fname'] @customer.lname = params['customer']['lname'] @customer.save end - @mailpref.attributes = params["mailpref"] + @mailpref.attributes = params["mailpref"] @mailpref.save session["wmimapseskey"] = nil redirect_to(:action=>"messages") end end - + # Message filters management def filters end - + def filter if params['op'] @filter = Filter.new(params['filter']) @@ -209,7 +217,7 @@ class WebmailController < ApplicationController case params['op'] when _('Add') @filter.expressions << Expression.new - when _('Save') + when _('Save') if params['filter']['id'] and params['filter']['id'] != "" @sf = Filter.find(params['filter']['id']) @sf.name, @sf.destination_folder = @filter.name, @filter.destination_folder @@ -228,11 +236,11 @@ class WebmailController < ApplicationController @expressions = @filter.expressions else @filter = Filter.find(params["id"]) if params["id"] - @expressions = @filter.expressions + @expressions = @filter.expressions end @destfolders = get_to_folders end - + def filter_delete Filter.delete(params["id"]) # reindex other filters @@ -246,7 +254,7 @@ class WebmailController < ApplicationController @user.serialize_to_file redirect_to :action=>"filters" end - + def filter_up filt = @user.filters.find(params['id']) ufilt = @user.filters.find_all("order_num = #{filt.order_num - 1}").first @@ -257,7 +265,7 @@ class WebmailController < ApplicationController @user.serialize_to_file redirect_to :action=>"filters" end - + def filter_down filt = Filter.find(params["id"]) dfilt = @user.filters[filt.order_num] @@ -268,7 +276,7 @@ class WebmailController < ApplicationController @user.serialize_to_file redirect_to :action=>"filters" end - + def filter_add @filter = Filter.new @filter.expressions << Expression.new @@ -277,58 +285,58 @@ class WebmailController < ApplicationController render "filter" end # end of filters - + def view_source @msg_id = msg_id_param.to_i @imapmail = folder.message(@msg_id) @msg_source = CGI.escapeHTML(@imapmail.full_body).gsub("\n", "
") end - + def auto_complete_for_mail_to auto_complete_responder_for_contacts params[:mail][:to] end - + def auto_complete_for_mail_cc auto_complete_responder_for_contacts params[:mail][:cc] end - + def auto_complete_for_mail_bcc auto_complete_responder_for_contacts params[:mail][:bcc] end - + private - + def auto_complete_responder_for_contacts(value) # first split by "," and take last name searchName = value.split(',').last.strip - + # if there are 2 names search by them if searchName.split.size > 1 fname, lname = searchName.split.first, searchName.split.last conditions = ['customer_id = ? and LOWER(fname) LIKE ? and LOWER(lname) like ?', logged_customer, fname.downcase + '%', lname.downcase + '%'] else conditions = ['customer_id = ? and LOWER(fname) LIKE ?', logged_customer, searchName.downcase + '%'] - end + end @contacts = Contact.find(:all, :conditions => conditions, :order => 'fname ASC',:limit => 8) render :partial => 'contacts' end - + protected - + def additional_scripts() @additional_css = ["webmail/webmail"] @additional_js = ["webmail"] end - + private - + def get_to_folders res = Array.new @folders.each{|f| res << f unless f.name == CDF::CONFIG[:mail_sent] or f.name == CDF::CONFIG[:mail_inbox] } res end - - + + def create_mail m = CDF::Mail.new(user.mail_temporary_path) if params["mail"] @@ -343,24 +351,24 @@ class WebmailController < ApplicationController end else m.from, m.content_type = user.friendlly_local_email, get_mail_prefs.mail_type - end + end m.customer_id = logged_customer m end - + def prepare_mail m = CDF::Mail.new(user.mail_temporary_path) m.from, m.content_type = user.friendlly_local_email, get_mail_prefs.mail_type m end - - + + def send_part(part) if part.content_type == "text/html" disposition = "inline" elsif part.content_type.include?("image/") - disposition = "inline" - else + disposition = "inline" + else disposition = "attachment" end headers['Content-Length'] = part.body.size @@ -369,48 +377,48 @@ class WebmailController < ApplicationController headers['Content-Disposition'] = disposition << %(; filename="#{part.header['content-type']['name']}") render :text => part.body end - + def get_parts(mail) parts = Array.new parts << mail - mail.parts.each { |part| + mail.parts.each { |part| if part.multipart? - parts = parts.concat(get_parts(part)) + parts = parts.concat(get_parts(part)) elsif part.content_type and part.content_type.include?("rfc822") parts = parts.concat(get_parts(TMail::Mail.parse(part.body))) << part - else + else parts << part end - } - parts + } + parts end - + def obtain_cookies_for_search_and_nav @srch_class = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'open') - @srch_img_src = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'opened') + @srch_img_src = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'opened') @ops_class = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'open') - @ops_img_src = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'opened') - end - + @ops_img_src = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'opened') + end + ################################################################### ### Some fixed parameters and session variables ################################################################### def folder @folders[@folder_name] end - + def msg_id_param params["msg_id"] end - + def messages_param params["messages"] end - + def dst_folder params["cpdest"] end - + def operation_param params["op"] end diff --git a/config/environment.rb b/config/environment.rb index d4f6f88..f134880 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -4,7 +4,7 @@ # (Use only when you can't set environment variables through your web/app server) # ENV['RAILS_ENV'] = 'production' -RAILS_GEM_VERSION = '2.3.11' unless defined? RAILS_GEM_VERSION +#RAILS_GEM_VERSION = '2.3.11' unless defined? RAILS_GEM_VERSION # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') @@ -34,7 +34,7 @@ Rails::Initializer.run do |config| # Make Active Record use UTC-base instead of local time config.active_record.default_timezone = :utc - config.i18n.default_locale = "es-ES" + #config.i18n.default_locale = "en" # Use Active Record's schema dumper instead of SQL when creating the test database # (enables use of different database adapters for development and test environments) @@ -65,6 +65,9 @@ rescue LoadError STDERR.puts 'WARNING: config/site.rb not found, using default settings from ' + default_config_path end +#if CONFIG[:locale] is nil then I18n.default_locale will be used +I18n.default_locale = CDF::CONFIG[:locale] + require 'tmail_patch' $KCODE = 'u' require 'jcode' diff --git a/config/locales/pl-PL.yml b/config/locales/pl-PL.yml new file mode 100644 index 0000000..9435a5b --- /dev/null +++ b/config/locales/pl-PL.yml @@ -0,0 +1,70 @@ +pl-PL: + mailr: Mailr + email: E-mail + password: Hasło + log_in: Zaloguj + wrong_email_or_password: Podano nieprawidłowy login lub hasło. + mailbox: Poczta + folders: Foldery + folder: Folder + empty: Pusty + logout: Wyloguj + compose: Nowa wiadomość + preferences: Ustawienia + filters: Filtry + contacts: Kontakty + search: Szukaj + search_txt: Szukaj w polu wiadomości + refresh: Odśwież + operations: Akcje + operations_txt: Akcje na zaznaczonych wiadomościach + delete: Usuń + copy: Skopiuj + move: Przenieś + mark_read: Zaznacz jako przeczytane + mark_unread: Zaznacz jako nieprzeczytane + destination_txt: Miejsce docelowe dla akcji + for: ciągu znaków + to: Do + subject: Temat + date: Data + size: Rozmiar + from: Od + show_all: Pokaż wszystkie + pages: Strony + first: Pierwsza + prev: Poprzednia + next: Następna + last: Ostatnia + back_to_list: Powrót do listy + back_to_message: Powrót do wiadomości + reply: Odpowiedz + forward: Przekaż + delete: Usuń + view_source: Pokaż źródło + add_filter: Dodaj filtr + cc: Cc + bcc: Bcc + send: Wyslij + choose_address: Wybierz adres z kontaktów + compose_txt: Utwórz nową wiadomość + attachment: Załącznik + add: Dodaj + first_name: Imię + last_name: Nazwisko + send_type: Format wiadomości wychodzącej + messages_per_page: Ilość wiadomości na stronie + check_external_mail: Check external mail? + check_external_mail_txt: Note that by selecting this option webmail system will try to log you using your original email on a local server. + save: Zapisz + cancel: Anuluj + add_one_contact: Dodaj jeden kontakt + add_multiple: Dodaj wiele + name: Nazwa + add_folder: Dodaj folder + total_messages: Total messages + unseen: Unseen + add_edit_folder: Zarządzanie folderami + user_logged_out: Użytkownik został wylogowany + please_login: Logowanie + add_to_contacts: Dodaj do kontaktów diff --git a/lib/webmail/mail2screen.rb b/lib/webmail/mail2screen.rb index 0ded836..5504cc0 100644 --- a/lib/webmail/mail2screen.rb +++ b/lib/webmail/mail2screen.rb @@ -3,7 +3,7 @@ module Mail2Screen def mail2html(mail, msg_id) footer = "" parsed_body = create_body(mail, msg_id, footer) - + ret = "\n" ret << "\n" ret << " \n" @@ -14,7 +14,7 @@ module Mail2Screen if @mail.bcc_addrs ret << " \n" end - ret << " \n" if footer != '' ret << " \n" @@ -26,7 +26,7 @@ module Mail2Screen ret << parsed_body ret << "\n" end - + def create_body(mail, msg_id, footer) charset = (mail.charset.nil? ? 'iso-8859-1' : mail.charset) if mail.multipart? @@ -38,7 +38,7 @@ module Mail2Screen ret << create_body(part, msg_id, footer) end } - return ret + return ret else mail.parts.each { |part| if part.multipart? @@ -55,13 +55,13 @@ module Mail2Screen elsif part.content_type.include?("image/") ctype = part.header['content-type'] ret << add_image(ctype, msg_id) - elsif part.content_type.include?("message/rfc822") + elsif part.content_type.include?("message/rfc822") ret << "
#{_('Follows attached message')}:
" << mail2html(TMail::Mail.parse(part.body), msg_id) end end } return ret - end + end else ret = "" if mail.content_type == "text/plain" or mail.content_type.nil? @@ -72,24 +72,24 @@ module Mail2Screen return ret end end - + def add_text(part, encoding, charset) - CGI.escapeHTML(decode_part_text("#{part}", encoding, charset)).gsub(/\r\n/,"
").gsub(/\r/, "
").gsub(/\n/,"
") + CGI.escapeHTML(decode_part_text("#{part}", encoding, charset)).gsub(/\r\n/,"
").gsub(/\r/, "
").gsub(/\n/,"
") end - def add_html(part, encoding, charset) + def add_html(part, encoding, charset) strip_html(decode_part_text("#{part}", encoding, charset)) end - + def decode_part_text(part_str, encoding, charset) # Parse mail header, text = "", "" - + # Get header and body #Content-type: text/plain; charset="ISO-8859-1" - #Content-transfer-encoding: quoted-printable + #Content-transfer-encoding: quoted-printable isBody = false - part_str.each_line { |line| + part_str.each_line { |line| if isBody text << line else @@ -105,7 +105,7 @@ module Mail2Screen ret = from_qp(text) elsif not(encoding.nil?) and encoding.downcase == "base64" ret = "#{text.unpack("m")}" - else + else ret = text end # manage charset @@ -118,9 +118,9 @@ module Mail2Screen RAILS_DEFAULT_LOGGER.debug("Exception occured #{ex}\n#{ex.backtrace.join('\n')}") return ret end - end + end end - + def add_attachment(content_type, msg_id) filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name']) if filename == "" @@ -129,28 +129,28 @@ module Mail2Screen " #{filename}" end end - + def add_image(content_type, msg_id) filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name']) "

#{filename}
" end - + def friendly_address(addr) addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.strip == "") ? "#{addr.mailbox}@#{addr.host}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.mailbox}@#{addr.host}>") : ((addr.name.nil? or addr.name.strip == "") ? "#{addr.spec}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.spec}>") end - + def friendly_address_or_name(addr) - if addr.kind_of?(Net::IMAP::Address) - ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.mailbox}@#{addr.host}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s)) + if addr.kind_of?(Net::IMAP::Address) + ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.mailbox}@#{addr.host}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s)) else ((addr.nil? or addr.to_s == "") ? "#{addr.to_s}" : (mime_encoded?(addr.to_s) ? mime_decode(addr.to_s): addr.to_s)) end end - + def add_to_contact(addr, msg_id) - " Agregar a contactos" + " "+t(:add_to_contacts) end - + def short_address(addresses) ret = "" addresses.each { |addr| #split(/,\s*/) @@ -159,7 +159,7 @@ module Mail2Screen } unless addresses.nil? ret end - + def address(addresses, msg_id) ret = "" addresses.each { |addr| #split(/,\s*/)
#{t :from}:#{address(mail.from_addrs, @msg_id)}
#{t :bcc}:#{address(mail.bcc_addrs, @msg_id)}
#{t :subject}:#{h(mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject)}\n" + ret << "
#{t :subject}:#{h(mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject)}\n" ret << "
#{t :date}:#{h message_date(mail.date)}
#{image_tag('attachment.png')}#{footer}