start to switch to rails 3.2.2

This commit is contained in:
Wojciech Todryk 2012-03-03 18:53:39 +01:00
parent 244942a78f
commit 74c23fa0d1
253 changed files with 648 additions and 17155 deletions

20
.gitignore vendored Executable file → Normal file
View file

@ -1,5 +1,15 @@
.bundle
db/*.sqlite3
log/*.log
tmp/
config/database.yml
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
# Ignore bundler config
/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

View file

@ -1,5 +0,0 @@
* Luben Manolov <luben.manolov@gmail.com>
* Nick Penkov <nick.penkov@gmail.com>
* Eugene Korbut
* Emilio Blanco
* Wojciech Todryk <wojciech(at)todryk(dot).pl>

19
CHANGES
View file

@ -1,19 +0,0 @@
## Changes
#### 0.8.6
* new calendar view
#### 0.8.5
* servers view
* identity modification
#### 0.8.4
* calendar view as separate gem
* adding bluecloth for rendering markdown text
#### 0.8.3
* export, imports of contact

45
Gemfile Executable file → Normal file
View file

@ -1,10 +1,39 @@
source 'http://rubygems.org'
source 'https://rubygems.org'
gem 'rails', '~>3.0.7'
gem 'rails', '3.2.2'
gem 'mysql2' , '~>0.2.7'
gem 'will_paginate', '~> 3.0.beta'
gem 'themes_for_rails'
gem "ezcrypto", "~> 0.7.2"
gem "calendar_view", "~> 0.0.5"
gem 'bluecloth', '>= 2.0.0'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'mysql2'
gem 'json'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer'
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# To use Jbuilder templates for JSON
# gem 'jbuilder'
# Use unicorn as the app server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug'

112
Gemfile.lock Normal file
View file

@ -0,0 +1,112 @@
GEM
remote: https://rubygems.org/
specs:
actionmailer (3.2.2)
actionpack (= 3.2.2)
mail (~> 2.4.0)
actionpack (3.2.2)
activemodel (= 3.2.2)
activesupport (= 3.2.2)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.1)
rack (~> 1.4.0)
rack-cache (~> 1.1)
rack-test (~> 0.6.1)
sprockets (~> 2.1.2)
activemodel (3.2.2)
activesupport (= 3.2.2)
builder (~> 3.0.0)
activerecord (3.2.2)
activemodel (= 3.2.2)
activesupport (= 3.2.2)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.2)
activemodel (= 3.2.2)
activesupport (= 3.2.2)
activesupport (3.2.2)
i18n (~> 0.6)
multi_json (~> 1.0)
arel (3.0.2)
builder (3.0.0)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.2.0)
erubis (2.7.0)
execjs (1.3.0)
multi_json (~> 1.0)
hike (1.2.1)
i18n (0.6.0)
journey (1.0.3)
jquery-rails (2.0.1)
railties (>= 3.2.0, < 5.0)
thor (~> 0.14)
json (1.6.5)
mail (2.4.1)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.17.2)
multi_json (1.1.0)
mysql2 (0.3.11)
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.1)
rack (>= 0.4)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
rails (3.2.2)
actionmailer (= 3.2.2)
actionpack (= 3.2.2)
activerecord (= 3.2.2)
activeresource (= 3.2.2)
activesupport (= 3.2.2)
bundler (~> 1.0)
railties (= 3.2.2)
railties (3.2.2)
actionpack (= 3.2.2)
activesupport (= 3.2.2)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2.2)
rdoc (3.12)
json (~> 1.4)
sass (3.1.15)
sass-rails (3.2.4)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
sprockets (2.1.2)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.31)
uglifier (1.2.3)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
PLATFORMS
ruby
DEPENDENCIES
coffee-rails (~> 3.2.1)
jquery-rails
json
mysql2
rails (= 3.2.2)
sass-rails (~> 3.2.3)
uglifier (>= 1.0.3)

2
Rakefile Executable file → Normal file
View file

@ -1,7 +1,7 @@
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
require 'rake'
Mailr::Application.load_tasks

20
TODO
View file

@ -1,20 +0,0 @@
## Todo
app/controllers/folders_controller.rb:
* [ 30] [TODO] recreate local copy of folders
* [ 99] [TODO] save system folders
app/controllers/messages_controller.rb:
* [101] [FIXME] missing fields and support arrays
app/controllers/messages_ops_controller.rb:
* [249] [FIXME] edit does not support attachments
* [304] [TODO] check if email address is valid if not get address from contacts
app/models/prefs.rb:
* [ 19] [TODO] move refresh to prefs and make refresh page with messages

View file

@ -1,24 +0,0 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

View file

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -0,0 +1,15 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

View file

@ -0,0 +1,13 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require_tree .
*/

96
app/controllers/application_controller.rb Executable file → Normal file
View file

@ -1,99 +1,3 @@
require 'yaml'
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :load_defaults,:current_user,:set_locale
before_filter :plugins_configuration
def load_defaults
$defaults ||= YAML::load(File.open(Rails.root.join('config','defaults.yml')))
end
################################# protected section ###########################################
protected
def theme_resolver
if @current_user.nil?
$defaults['theme']
else
@current_user.prefs.theme || $defaults['theme']
end
end
def set_locale
if @current_user.nil?
I18n.locale = $defaults['locale'] || I18n.default_locale
else
I18n.locale = @current_user.prefs.locale.to_sym || I18n.default_locale
end
end
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def check_current_user
if @current_user.nil?
session["return_to"] = request.fullpath
redirect_to :controller => 'user', :action => 'login'
return false
end
end
def selected_folder
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")
if not @selected_folder.nil?
@current_folder = @current_user.folders.find_by_full_name(@selected_folder)
end
end
def prepare_compose_buttons
@buttons = []
@buttons << {:text => 'sendout',:scope=>:compose,:image => 'email.png'}
@buttons << {:text => 'save',:scope=>:compose,:image => 'save.png'}
end
def create_message_with_params
@message = Message.new(params[:message])
# if params[:message]
# @message.update_attributes(params[:message])
# end
files = Dir.glob(File.join($defaults["msg_upload_dir"],@current_user.username + "*"))
@attachments = []
files.each do |f|
@attachments << {:name => File.basename(f).gsub!(/#{@current_user.username}_/,"") , :size => File.stat(f).size }
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
##################################### private section ##########################################
private
def plugins_configuration
WillPaginate::ViewHelpers.pagination_options[:previous_label] = t(:previous_page,:scope=>:common)
WillPaginate::ViewHelpers.pagination_options[:next_label] = t(:next_page,:scope=>:common)
end
end

View file

@ -1,135 +0,0 @@
require 'tempfile'
class ContactsController < ApplicationController
before_filter :check_current_user,:selected_folder, :get_current_folders
before_filter :get_contacts, :only => [:index]
before_filter :prepare_ops_buttons, :prepare_export_import_buttons,:only => [:index]
theme :theme_resolver
def index
end
def ops
if params["create_new"]
redirect_to(new_contact_path)
return
end
if !params["cids"]
flash[:warning] = t(:no_selected,:scope=>:contact)
else
if params["delete_selected"]
params["cids"].each do |id|
@current_user.contacts.find_by_id(id).destroy
end
elsif params["compose_to_selected"]
redirect_to :controller=>'messages',:action=>'compose',:cids=>params["cids"]
return
end
end
redirect_to(contacts_path)
end
#problem http://binary10ve.blogspot.com/2011/05/migrating-to-rails-3-got-stuck-with.html
#def destroy
# @current_user.contacts.find(params[:id]).destroy
# redirect_to(contacts_path)
#end
def new
@contact = Contact.new
end
def edit
@contact = @current_user.contacts.find(params[:id])
render 'edit'
end
def create
@contact = @current_user.contacts.build(params[:contact])
if @contact.valid?
@contact.save
flash[:notice] = t(:was_created,:scope=>:contact)
redirect_to(contacts_path)
else
render 'new'
end
end
def update
@contact = @current_user.contacts.find(params[:id])
if @contact.update_attributes(params[:contact])
redirect_to(contacts_path)
else
render 'edit'
end
end
def external
if params["export"]
redirect_to :action => 'export'
return
elsif params["import"]
begin
raise t(:no_file_chosen,:scope=>:common) if not params[:upload]
raise t(:no_tmp_dir,:scope=>:common) if not File.exists?($defaults["msg_upload_dir"])
tmp_file = Tempfile.new($defaults["contact_tmp_filename"],$defaults["msg_upload_dir"])
tmp_file.write(params[:upload][:datafile].read)
tmp_file.flush
tmp_file.rewind
tmp_file.readlines.each do |line|
next if line =~ /^#/
Contact.import(@current_user,line)
end
rescue ActiveRecord::RecordInvalid => e
flash[:error] = {:title => e.to_s,:info => e.record.inspect + e.record.errors.inspect}
rescue Exception => e
flash[:error] = e.to_s
else
flash[:notice] = t(:were_imported,:scope=>:contact)
end
end
redirect_to :action => 'index'
end
def export
contacts = @current_user.contacts
s = ""
contacts.each do |c|
s += c.export + "\r\n"
end
headers['Content-type'] = "text/csv"
headers['Content-Disposition'] = %(attachment; filename="contacts.csv")
render :text => s
end
####################################### protected section ################################
protected
def prepare_ops_buttons
@buttons = []
@buttons << {:text => 'compose_to_selected',:scope=> 'contact', :image => 'email.png'}
@buttons << {:text => 'create_new',:scope=> 'contact', :image => 'plus.png'}
@buttons << {:text => 'delete_selected',:scope=>'contact',:image => 'minus.png'}
end
def prepare_export_import_buttons
@ei_buttons = []
@ei_buttons << {:text => 'import',:scope=>'contact',:image => 'right.png'}
@ei_buttons << {:text => 'export',:scope=>'contact',:image => 'left.png'}
end
####################################### private section ##################################
private
def get_contacts
@contacts = Contact.getPageForUser(@current_user,params[:page],params[:sort_field],params[:sort_dir])
end
end

View file

@ -1,172 +0,0 @@
require 'imap_mailbox'
require 'imap_session'
class FoldersController < ApplicationController
include ImapMailboxModule
include ImapSessionModule
before_filter :check_current_user,:selected_folder, :get_current_folders
before_filter :open_imap_session, :except => [:index,:show_hide,:system]
after_filter :close_imap_session, :except => [:index,:show_hide,:system]
before_filter :get_folders
before_filter :prepare_buttons_to_folders
theme :theme_resolver
def index
#before_filter
end
def create
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[:folder][:parent].empty?
@mailbox.create_folder(params[:folder][:target])
else
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][:target])
end
rescue Exception => e
flash[:error] = t(:can_not_create,:scope=>:folder) + ' (' + e.to_s + ')'
render 'index'
return
end
flash[:notice] = t(:was_created,:scope=>:folder)
redirect_to :action => 'index'
end
end
def delete
if params[:folder][:delete].empty?
flash[:warning] = t(:to_delete_empty,:scope=>:folder)
render "index"
else
begin
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)
if @current_folder.eql? folder
session[:selected_folder] = nil
end
folder.destroy
rescue Exception => e
flash[:error] = t(:can_not_delete,:scope=>:folder) + ' (' + e.to_s + ')'
render 'index'
return
end
flash[:notice] = t(:was_deleted,:scope=>:folder)
redirect_to :action => 'index'
end
end
def system
logger.custom('sss',params[:folder].inspect)
@folders.each do |f|
logger.custom('s',f.inspect)
if f.isSystem?
f.setNone
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
# 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
session[:selected_folder] = params[:id]
redirect_to :controller => 'messages', :action => 'index'
end
def refresh_status
@folders_shown.each do |f|
@mailbox.set_folder(f.full_name)
folder_status = @mailbox.status
f.update_attributes(:total => folder_status['MESSAGES'], :unseen => folder_status['UNSEEN'])
end
redirect_to :controller=> 'messages', :action => 'index'
end
def emptybin
begin
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)
end
@mailbox.expunge
trash_folder.messages.destroy_all
trash_folder.update_attributes(:unseen => 0, :total => 0)
rescue Exception => e
flash[:error] = "#{t(:imap_error,:scope=>:common)} (#{e.to_s})"
end
redirect_to :controller => 'messages', :action => 'index'
end
############################################# protected section #######################################
protected
def prepare_buttons_to_folders
@buttons = []
@buttons << {:text => 'show_hide',:scope=>'folder',:image => 'flag.png'}
@buttons << {:text => 'refresh',:scope=>'folder',:image => 'refresh.png'}
end
def get_folders
@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

View file

@ -1,53 +0,0 @@
class InternalController < ApplicationController
before_filter :check_current_user ,:selected_folder, :get_current_folders, :only => [:about]
theme :theme_resolver
layout "simple"
ERRORS = [
:internal_server_error,
:not_found,
:unprocessable_entity
].freeze
ERRORS.each do |e|
define_method e do
@title = t(e,:scope=>:internal)
@error = t(e,:scope=>:internal)
render 'error'
end
end
def error
@title = t(:unspecified_error,:scope=>:internal)
@error = params[:error] || t(:unspecified_error,:scope=>:internal)
end
def imaperror
@title = t(:imap_error,:scope => :internal)
@error = params[:error] || t(:unspecified_error, :scope => :internal)
logger.error "!!! InternalControllerImapError: " + @error
render 'error'
end
def loginfailure
reset_session
flash[:error] = t(:login_failure,:scope=>:user)
@current_user = nil
redirect_to :controller=>'user', :action => 'login'
end
def onlycanlogins
reset_session
flash[:error] = t(:only_can_logins,:scope=>:user)
@current_user = nil
redirect_to :controller=>'user', :action => 'login'
end
def about
render 'internal/about', :layout => 'application'
end
end

View file

@ -1,133 +0,0 @@
require 'tempfile'
class LinksController < ApplicationController
before_filter :check_current_user,:selected_folder, :get_current_folders
before_filter :get_links, :only => [:index]
before_filter :prepare_ops_buttons, :only => [:index]
#, :prepare_export_import_buttons,:only => [:index]
theme :theme_resolver
def index
end
def ops
if params["create_new"]
redirect_to(new_link_path)
return
end
if !params["ids"]
flash[:warning] = t(:no_selected,:scope=>:link)
else
if params["delete_selected"]
params["ids"].each do |id|
@current_user.links.find_by_id(id).destroy
end
end
end
redirect_to(links_path)
end
#problem http://binary10ve.blogspot.com/2011/05/migrating-to-rails-3-got-stuck-with.html
#def destroy
# @current_user.contacts.find(params[:id]).destroy
# redirect_to(contacts_path)
#end
def new
@link = Link.new
end
def edit
@link = @current_user.links.find(params[:id])
render 'edit'
end
def create
@link = @current_user.links.build(params[:link])
if @link.valid?
@link.save
flash[:notice] = t(:was_created,:scope=>:link)
redirect_to(links_path)
else
render 'new'
end
end
def update
@link = @current_user.links.find(params[:id])
if @link.update_attributes(params[:link])
redirect_to(links_path)
else
render 'edit'
end
end
def external
if params["export"]
redirect_to :action => 'export'
return
elsif params["import"]
begin
raise t(:no_file_chosen,:scope=>:common) if not params[:upload]
raise t(:no_tmp_dir,:scope=>:common) if not File.exists?($defaults["msg_upload_dir"])
tmp_file = Tempfile.new($defaults["contact_tmp_filename"],$defaults["msg_upload_dir"])
tmp_file.write(params[:upload][:datafile].read)
tmp_file.flush
tmp_file.rewind
tmp_file.readlines.each do |line|
next if line =~ /^#/
Contact.import(@current_user,line)
end
rescue ActiveRecord::RecordInvalid => e
flash[:error] = {:title => e.to_s,:info => e.record.inspect + e.record.errors.inspect}
rescue Exception => e
flash[:error] = e.to_s
else
flash[:notice] = t(:were_imported,:scope=>:contact)
end
end
redirect_to :action => 'index'
end
def export
contacts = @current_user.contacts
s = ""
contacts.each do |c|
s += c.export + "\r\n"
end
headers['Content-type'] = "text/csv"
headers['Content-Disposition'] = %(attachment; filename="contacts.csv")
render :text => s
end
####################################### protected section ################################
protected
def prepare_ops_buttons
@buttons = []
@buttons << {:text => 'create_new',:scope=> 'link', :image => 'plus.png'}
@buttons << {:text => 'delete_selected',:scope=>'link',:image => 'minus.png'}
end
def prepare_export_import_buttons
@ei_buttons = []
@ei_buttons << {:text => 'import',:scope=>'link',:image => 'right.png'}
@ei_buttons << {:text => 'export',:scope=>'link',:image => 'left.png'}
end
####################################### private section ##################################
private
def get_links
@links = Link.getPageForUser(@current_user,params[:page],params[:sort_field],params[:sort_dir])
end
end

View file

@ -1,210 +0,0 @@
require 'imap_session'
require 'imap_mailbox'
require 'imap_message'
require 'mail'
require 'mail_plugin_extension'
class MessagesController < 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, :only => [:compose]
before_filter :get_system_folders, :only => [:index]
before_filter :create_message_with_params, :only => [:compose]
before_filter :prepare_multi1_buttons, :only => [:index,:show]
before_filter :prepare_multi2_buttons, :only => [:index]
before_filter :prepare_multi3_buttons, :only => [:show]
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
@messages = []
folder_status = @mailbox.status
@current_folder.update_attributes(:total => folder_status['MESSAGES'], :unseen => folder_status['UNSEEN'])
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
(uids_remote-uids_local).each_slice($defaults["imap_fetch_slice"].to_i) do |slice|
messages = @mailbox.uid_fetch(slice, ImapMessageModule::IMAPMessage.fetch_attr)
messages.each do |m|
Message.createForUser(@current_user,@current_folder,m)
end
end
@messages = Message.getPageForUser(@current_user,@current_folder,params[:page],params[:sort_field],params[:sort_dir])
end
def compose
#before filter :prepare_compose_buttons, :create_message_with_params
@operation = :new
if params["cid"].present?
contact = @current_user.contacts.find_by_id(params["cid"])
if not contact.nil?
@message.to_addr = contact.email
end
elsif params["cids"].present?
contacts = []
params["cids"].each do |c|
contact = @current_user.contacts.find_by_id(c)
if not contact.nil?
contacts << contact.email
end
end
@message.to_addr = contacts.join(';')
end
end
def show
@images = []
@attachments = []
@text_part = nil
@html_part = nil
@message = @current_user.messages.where('folder_id = ? and uid = ?',@current_folder,params[:id]).first
@message.update_attributes(:unseen => false)
imap_message = @mailbox.fetch_body(@message.uid)
mail = Mail.new(imap_message)
@plain_header = mail.header.to_s
# FIXME missing fields and support arrays
#@from = mail.From.addrs.presence
#@to = mail.To.addrs.presence
@from = @message.from_addr
@to = @message.to_addr
@cc = mail.Cc.presence
@bcc = mail.Bcc.presence
#@subject = mail.Subject
@date = mail.date.presence
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? and @current_user.prefs.msg_image_view_as.to_sym.eql?(:thumbnail)
@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? and @current_user.prefs.msg_image_view_as.to_sym.eql?(:thumbnail)
@images << part
elsif part.isHtml?
@html_part = part.decoded_and_charseted
else
@attachments << part
end
end
end
def html_body
message = @current_user.messages.where('folder_id = ? and uid = ?',@current_folder,params[:id]).first
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)
else
if @body=~/cid:([\w@\.]+)/
attachments = mail.attachments
if not attachments.size.zero?
for idx in 0..attachments.size - 1
@body.gsub!(/cid:#{attachments[idx].cid}/,attachment_download_path(message.uid,idx))
end
end
end
end
render 'html_body',:layout => 'html_body'
end
def attachment
attachments = []
message = @current_user.messages.where('folder_id = ? and uid = ?',@current_folder,params[:id]).first
mail = Mail.new(@mailbox.fetch_body(message.uid))
if mail.multipart? == true
attachments = mail.attachments
else
attachments << Mail::Part.new(mail)
end
a = attachments[params[:idx].to_i]
headers['Content-type'] = a.main_type + "/" + a.sub_type
headers['Content-Disposition'] = %(attachment; filename="#{a.filename}")
render :text => a.decoded
end
############################################# protected section ##########################################
protected
def prepare_multi2_buttons
@multi2_buttons = []
@multi2_buttons << {:text => 'trash',:scope=>:message,:image => 'trash.png'}
@multi2_buttons << {:text => 'set_unread',:scope=>:message,:image => 'unseen.png'}
@multi2_buttons << {:text => 'set_read',:scope=>:message,:image => 'seen.png'}
end
def prepare_multi1_buttons
@multi1_buttons = []
@multi1_buttons << {:text => 'copy',:scope=>:message,:image => 'copy.png'}
@multi1_buttons << {:text => 'move',:scope=>:message,:image => 'move.png'}
end
def prepare_multi3_buttons
@multi3_buttons = []
@multi3_buttons << {:text => 'show_header',:scope=>:show,:image => 'zoom.png'}
@multi3_buttons << {:text => 'trash',:scope=>:show,:image => 'trash.png'}
@multi3_buttons << {:text => 'reply',:scope=>:show,:image => 'reply.png'}
end
end

View file

@ -1,354 +0,0 @@
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]
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[:notice] = 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)
File.delete(path) if File.exist?(path)
end
flash[:notice] = t(:was_saved,:scope => :compose)
end
redirect_to :controller => 'messages', :action => 'index'
end
#FIXME edit does not support attachments
def edit
old_message = @current_user.messages.where('folder_id = ? and uid = ?',@current_folder,params[:uids].first).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.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 = :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.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

View file

@ -1,55 +0,0 @@
class PrefsController < ApplicationController
before_filter :check_current_user,:selected_folder
before_filter :get_current_folders
before_filter :get_prefs, :only => [:look,:update_look]
theme :theme_resolver
def update_look
if params[:prefs]
@prefs.update_attributes(params[:prefs])
end
flash[:notice] = t(:were_saved,:scope=>:prefs)
redirect_to :action => 'look'
end
def update_servers
redirect_to :action => 'servers'
end
def update_identity
if params[:user]
@current_user.first_name = params[:user][:first_name]
@current_user.last_name = params[:user][:last_name]
@current_user.domain = params[:user][:domain]
if @current_user.valid?
@current_user.save
flash[:notice] = t(:were_saved,:scope=>:prefs)
redirect_to :action => 'identity'
else
render 'prefs/identity'
end
end
end
def look
end
def identity
end
def servers
@servers = @current_user.servers
end
############################# protected section ##################################
def get_prefs
@prefs = @current_user.prefs
end
end

View file

@ -1,75 +0,0 @@
class UserController < ApplicationController
theme :theme_resolver
layout "simple"
def login
end
def logout
reset_session
flash[:notice] = t(:logged_out,:scope=>:user)
redirect_to :action => "login"
end
def authenticate
if not $defaults["only_can_logins"].nil?
if not $defaults["only_can_logins"].include?(params[:user][:login])
redirect_to :controller => 'internal', :action => 'onlycanlogins'
return false
end
end
user = User.find_by_login(params[:user][:login])
if user.nil?
redirect_to :action => 'unknown' ,:login=> params[:user][:login]
else
session[:user_id] = user.id
user.set_cached_password(session,params[:user][:password])
if session["return_to"]
redirect_to(session["return_to"])
session["return_to"] = nil
else
redirect_to :controller=> 'messages', :action=> 'index'
end
end
end
def loginfailure
end
def setup
@user = User.new
@server = Server.new
end
def unknown
end
def create
@user = User.new
@user.login = params[:user][:login]
@user.first_name = params[:user][:first_name]
@user.last_name = params[:user][:last_name]
@server = Server.new
@server.name = params[:server][:name]
if @user.valid? and @server.valid?
@user.save
#@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
render "setup"
end
end
end

332
app/helpers/application_helper.rb Executable file → Normal file
View file

@ -1,334 +1,2 @@
require 'iconv'
module ApplicationHelper
def form_field(object,field,flabel,example,val)
model_name = eval(object.class.model_name)
html = ""
html << "<div class=\"param_group\">"
if not object.errors[field.to_sym].empty?
html << "<div class=\"fieldWithErrors\">"
end
html << "<label class=\"label\">"
flabel.nil? ? html << model_name.human_attribute_name(field) : html << t(flabel.to_sym)
html << "</label>"
if not object.errors[field.to_sym].empty?
html << "<span class=\"error\"> "
html << object.errors[field.to_sym].to_s
html << "</span>"
html << "</div>"
end
html << "<input id=\""
html << object.class.name.downcase+"_"+field
html << "\""
html << " name=\"#{object.class.name.downcase}[#{field}]\""
html << " type=\"text\" class=\"text_field\" value=\""
value = val || object.instance_eval(field) || ""
html << value
html << "\"/>"
html << "<span class=\"description\">"
html << t(:example,:scope=>:common)
html << ": "
html << example
html << "</span>"
html << "</div>"
end
def show_param_view(object,field,value)
model_name = eval(object.class.model_name)
html = ""
html << "<div class=\"group clearfix\">"
html << "<label class=\"label\">#{model_name.human_attribute_name(field)}: </label>"
html << value
html << "</div>"
html
end
def area_field(object,field,flabel,example,val,cols,rows)
model_name = eval(object.class.model_name)
html = ""
html << "<div class=\"group\">"
if not object.errors[field.to_sym].empty?
html << "<div class=\"fieldWithErrors\">"
end
html << "<label class=\"label\">"
flabel.nil? ? html << model_name.human_attribute_name(field) : html << t(flabel.to_sym)
html << "</label>"
if not object.errors[field.to_sym].empty?
html << "<span class=\"error\">"
html << object.errors[field.to_sym].to_s
html << "</span>"
html << "</div>"
end
name = object.class.name.downcase + '[' + field + ']'
id = object.class.name.downcase+"_"+field
value = val || object.instance_eval(field) || ""
html << "<textarea id=\"#{id}\" name=\"#{name}\" class=\"text_area\" cols=\"#{cols}\" rows=\"#{rows}\">#{value}</textarea>"
desc = t(:example,:scope=>:common) + ": " + example
html << "<span class=\"description\">#{desc}</span>"
html << "</div>"
end
def form_button(text,image)
html = ""
html << "<div class=\"group\">"
html << "<button class=\"button\" type=\"submit\">"
html << "<img src=\""
html << current_theme_image_path(image)
html << "\" alt=\""
html << t(text.to_sym)
html << "\" />"
html << t(text.to_sym)
html << "</button></div>"
end
def single_action(text,scope,image)
html = ""
html << "<div class=\"actiongroup clearfix\">"
html << "<button class=\"button\" name=\"#{text}\" type=\"submit\">"
html << "<img src=\""
html << current_theme_image_path(image)
html << "\" alt=\""
html << t(text.to_sym, :scope => scope.to_sym)
html << "\" />"
html << t(text.to_sym, :scope => scope.to_sym)
html << "</button></div>"
end
def single_action_onclick(text,scope,image,onclick)
html = ""
html << "<div class=\"actiongroup clearfix\">"
html << "<button class=\"button\" type=\"submit\" onclick=\"window.location='"
html << onclick
html << "'\">"
html << "<img src=\""
html << current_theme_image_path(image)
html << "\" alt=\""
html << t(text.to_sym, :scope => scope.to_sym)
html << "\" />"
html << t(text.to_sym, :scope => scope.to_sym)
html << "</button>"
html << "</div>"
end
def group_action(buttons)
html = ""
html << "<div class=\"actiongroup clearfix\">"
buttons.each do |b|
html << "<button class=\"button\" type=\"submit\" name=\"#{b[:text]}\">"
html << "<img src=\""
html << current_theme_image_path(b[:image])
html << "\" alt=\""
html << t(b[:text].to_sym,:scope=>b[:scope].to_sym)
html << "\" />"
html << t(b[:text].to_sym,:scope=>b[:scope].to_sym)
html << "</button> "
end
html << "</div>"
end
def group_action_text(buttons,text)
html = ""
html << "<div class=\"group\">"
buttons.each do |b|
html << "<button class=\"button\" type=\"submit\" name=\"#{b[:text]}\">"
html << "<img src=\""
html << current_theme_image_path(b[:image])
html << "\" alt=\""
html << t(b[:text].to_sym,:scope=>b[:scope].to_sym)
html << "\" />"
html << t(b[:text].to_sym,:scope=>b[:scope].to_sym)
html << "</button> "
end
html << text
html << "</div>"
end
def form_buttons(buttons)
html = ""
html << "<div class=\"group\">"
buttons.each do |b|
html << "<button class=\"button\" type=\"submit\" name=\"#{b[:text]}\">"
html << "<img src=\""
html << current_theme_image_path(b[:image])
html << "\" alt=\""
html << t(b[:text].to_sym)
html << "\" />"
html << t(b[:text].to_sym)
html << "</button> "
end
html << "</div>"
end
def form_button_value(text,image,onclick)
html = ""
html << "<div class=\"group\">"
html << "<button class=\"button\" type=\"submit\" onclick=\"window.location='"
html << onclick
html << "'\">"
html << "<img src=\""
html << current_theme_image_path(image)
html << "\" alt=\""
html << text
html << "\" />"
html << t(text.to_sym)
html << "</button></div>"
end
def simple_input_field(name,id,label,value)
html = ""
html << "<div class=\"param_group\">"
html << "<label class=\"label\">#{label}</label>"
html << "<input name=\"#{name}[#{id}]\" id=\"#{name}_#{id} class=\"text_field\" type=\"text\" value=\"#{value}\">"
html << "</div>"
end
def select_field(name,object,label,blank)
html = ""
html << "<div class=\"group\">"
html << "<label class=\"label\">#{label}</label>"
html << select(name, name, object.all.collect {|p| [ p.name, p.id ] }, { :include_blank => (blank == true ? true : false)})
html << "</div>"
end
def select_field_table(object,field,table_choices,choice,blank)
model_name = eval(object.class.model_name)
html = ""
html << "<div class=\"param_group\">"
html << "<label class=\"label\">#{model_name.human_attribute_name(field)}</label>"
html << select(object.class.to_s.downcase, field, options_for_select(table_choices,choice), {:include_blank => blank})
html << "</div>"
end
def select_field_table_t(object,field,table_choices,choice,blank)
model_name = eval(object.class.model_name)
html = ""
html << "<div class=\"param_group\">"
html << "<label class=\"label\">#{model_name.human_attribute_name(field)}</label>"
t = []
table_choices.each do |c|
t << [t(c.to_sym,:scope=>:prefs),c.to_s]
end
html << select(object.class.to_s.downcase, field, options_for_select(t,choice), {:include_blank => blank})
html << "</div>"
end
#def form_simle_field(name,label,value)
# html = ""
# html << "<div class=\"group\">"
# html << "<label class=\"label\">#{label}</label>"
# html << "<input class=\"text_field\" type=\"text\" value=\"#{value}\">"
# html << "</div>"
#end
#def nav_to_folders
# link_to( t(:folders,:scope=>:folder), :controller=>:folders, :action=>:index )
#end
#
#def nav_to_messages
# link_to( t(:messages,:scope=>:message), :controller=>:messages, :action=>:index )
#end
#
#def nav_to_compose
# link_to( t(:compose,:scope=>:compose), :controller=>:messages, :action=>:compose )
#end
#
#def nav_to_contacts
# link_to( t(:contacts,:scope=>:contact), contacts_path )
#end
#
#def nav_to_prefs
# link_to( t(:prefs,:scope=>:prefs), prefs_look_path )
#end
def single_navigation(label,scope)
s = ""
s += "<ul>"
s += "<li class=\"first active\">#{link_to(t(label,:scope=>scope),'#')}</li>"
s += "<li class=\"last\">&nbsp;</li>"
s += "</ul>"
end
def main_navigation(active)
instance_variable_set("@#{active}", "active")
s = ""
s += "<ul>"
s += "<li class=\"first #{@messages_tab}\">#{link_to( t(:messages,:scope=>:message), messages_path )}</li>"
s += "<li class=\"#{@compose_tab}\">#{link_to( t(:compose,:scope=>:compose), compose_path )}</li>"
s += "<li class=\"#{@folders_tab}\">#{link_to( t(:folders,:scope=>:folder), folders_path )}</li>"
s += "<li class=\"#{@contacts_tab}\">#{link_to( t(:contacts,:scope=>:contact), contacts_path )}</li>"
s += "<li class=\"#{@prefs_tab}\">#{link_to( t(:prefs,:scope=>:prefs), prefs_look_path )}</li>"
s += "<li class=\"last #{@links_tab}\">#{link_to( t(:links,:scope=>:link), links_path )}</li>"
s += "</ul>"
end
def prefs_navigation(active)
instance_variable_set("@#{active}", "active")
s = ""
s += "<ul>"
s += "<li class=\"first #{@look_tab}\">#{link_to( t(:look,:scope=>:prefs), prefs_look_path )}</li>"
s += "<li class=\"#{@identity_tab}\">#{link_to( t(:identity,:scope=>:prefs), prefs_identity_path )}</li>"
s += "<li class=\"last #{@servers_tab}\">#{link_to( t(:servers,:scope=>:prefs), prefs_servers_path )}</li>"
s += "</ul>"
end
def multi_select(id, name, objects, selected_objects, label, value,joiner,content = {})
options = ""
objects.each do |o|
selected = selected_objects.include?(o) ? " selected=\"selected\"" : ""
option_value = escape_once(o.send(value))
text = [option_value]
unless content[:text].nil?
text = []
content[:text].each do |t|
text << o.send(t)
end
text = text.join(joiner)
end
text.gsub!(/^\./,'')
bracket = []
unless content[:bracket].nil?
content[:bracket].each do |b|
bracket << o.send(b)
end
bracket = bracket.join(joiner)
end
option_content = bracket.empty? ? "#{text}" : "#{text} (#{bracket})"
options << "<option value=\"#{option_value}\"#{selected}>&nbsp;&nbsp;#{option_content}&nbsp;&nbsp;</option>\n"
end
"<div class=\"param_group\"><label class=\"label\">#{label}</label><select multiple=\"multiple\" size=10 id=\"#{id}\" name=\"#{name}\">\n#{options}</select></div>"
end
def force_charset(text)
begin
Iconv.iconv("UTF-8",$defaults["msg_unknown_charset"],text)
rescue
text
end
end
def content_for_sidebar
s = render :partial => 'sidebar/logo'
s += render :partial => 'folders/list'
s += render :partial => 'sidebar/calendar_view'
s += render :partial => 'internal/version'
s
end
def boolean_answer(answer)
answer == true ? t(:true_answer,:scope=>:common) : t(:false_answer,:scope=>:common)
end
end

View file

@ -1,17 +0,0 @@
module ContactsHelper
def contacts_table_header
html = ""
$defaults["contacts_table_fields"].each do |f|
html << "<th>"
if params[:sort_field] == f
params[:sort_dir].nil? ? dir = 'desc' : dir = nil
end
html << link_to(Contact.human_attribute_name(f), {:controller => 'contacts',:action => 'index',:sort_field => f,:sort_dir => dir}, {:class=>"header"})
html << "</th>"
end
html
end
end

View file

@ -1,66 +0,0 @@
module FolderHelper
def folder_link(folder)
folder.parent.empty? ? name = folder.name : name = folder.parent.gsub(/\./,'#') + "#" + folder.name
if folder.isInbox?
name_shown = t(:inbox_name,:scope => :folder)
elsif folder.isSent?
name_shown = t(:sent_name,:scope => :folder)
elsif folder.isDrafts?
name_shown = t(:drafts_name,:scope => :folder)
elsif folder.isTrash?
name_shown = t(:trash_name,:scope => :folder)
else
name_shown = folder.name.capitalize
end
s = link_to name_shown, folders_select_path(:id => name)
if folder.isTrash?
if not folder.total.zero?
s <<' ('
s << link_to(t(:emptybin,:scope=>:folder),folders_emptybin_path)
s << ')'
end
else
if !folder.unseen.zero?
s += ' (' + folder.unseen.to_s + ')'
end
end
s
end
def pretty_folder_name(folder)
if folder.nil?
t(:no_selected,:scope=>:folder)
else
if folder.isInbox?
t(:inbox_name,:scope => :folder)
elsif folder.isSent?
t(:sent_name,:scope => :folder)
elsif folder.isDrafts?
t(:drafts_name,:scope => :folder)
elsif folder.isTrash?
t(:trash_name,:scope => :folder)
else
folder.name.capitalize
end
end
end
def select_for_folders(name,id,collection,label,choice,blank)
html = ""
html << "<div class=\"param_group\">"
html << "<label class=\"label\">#{label}</label>"
html << simple_select_for_folders(name,id,collection,choice,blank)
html << "</div>"
end
def simple_select_for_folders(name,id,collection,choice,blank)
html = ""
html << select(name , id, options_from_collection_for_select(collection, 'id', 'full_name', choice),{ :include_blank => (blank == true ? true : false)})
html
end
end

View file

@ -1,2 +0,0 @@
module InternalHelper
end

View file

@ -1,17 +0,0 @@
module LinksHelper
def links_table_header
html = ""
$defaults["links_table_fields"].each do |f|
html << "<th>"
if params[:sort_field] == f
params[:sort_dir].nil? ? dir = 'desc' : dir = nil
end
html << link_to(Link.human_attribute_name(f), {:controller => 'links',:action => 'index',:sort_field => f,:sort_dir => dir}, {:class=>"header"})
html << "</th>"
end
html
end
end

View file

@ -1,113 +0,0 @@
module MessagesHelper
def size_formatter(size)
if size <= 2**10
"#{size} #{t(:bytes,:scope=>:common)}"
elsif size <= 2**20
sprintf("%.1f #{t(:kbytes,:scope=>:common)}",size.to_f/2**10)
else
sprintf("%.1f #{t(:mbytes,:scope=>:common)}",size.to_f/2**20)
end
end
def date_formatter(date)
date.nil? ? t(:no_date,:scope=>:message) : date.strftime("%Y-%m-%d %H:%M")
end
def address_formatter(addr,op)
s = ""
return s if addr.nil?
length = $defaults["msg_address_length"].to_i
case op
when :index
fs = addr.gsub(/\"/,"").split(/</)
fs[0].size.zero? ? s = fs[1] : s = fs[0]
s.length >= length ? s = s[0,length]+"..." : s
return h(s)
when :show
#addr = addr[0].charseted.gsub(/\"/,"")
return h(addr.gsub(/\"/,""))
when :raw
#fs = addr.gsub(/\"/,"").split(/</)
#fs[0].size.zero? ? s = fs[1] : s << fs[0] + " <" + fs[1] + ">"
s = h(addr)
return s
when :reply
return h(addr)
end
end
def body_formatter(body,op)
case op
when :reply
s = "\n\n\n"
body.gsub(/^\s+/,"").split(/\n/).each do |line|
s += ">" + line + "\n"
end
s
when :edit
return body
end
end
def subject_formatter(message,op)
case op
when :index
if message.subject.nil? or message.subject.size.zero?
s = t(:no_subject,:scope=>:message)
else
length = $defaults["msg_subject_length"].to_i
message.subject.length >= length ? s = message.subject[0,length]+"..." : s = message.subject
end
link_to s,{:controller => 'messages', :action => 'show', :id => message.uid} , :title => message.subject
when :show
if message.subject.nil? or message.subject.size.zero?
t(:no_subject,:scope=>:message)
else
message.subject
end
when :reply
if message.nil? or message.size.zero?
t(:reply_string,:scope=>:show)
else
t(:reply_string,:scope=>:show) + " " + message
end
end
end
def attachment_formatter(message)
message.content_type =~ /^text\/plain/ ? "" : image_tag(current_theme_image_path('star.png'))
end
def headers_links
#if @current_folder.hasFullName?(@folder_sent_name) || @current_folder.hasFullName?(@folder_drafts_name)
if @current_folder == @sent_folder || @current_folder == @drafts_folder
fields = $defaults["msgs_sent_view_fields"]
else
fields = $defaults["msgs_inbox_view_fields"]
end
html = ""
fields.each do |f|
html << "<th>"
if params[:sort_field] == f
params[:sort_dir].nil? ? dir = 'desc' : dir = nil
end
html << link_to(Message.human_attribute_name(f), {:controller => 'messages',:action => 'index',:sort_field => f,:sort_dir => dir}, {:class=>"header"})
html << "</th>"
end
html
end
def content_text_plain_for_render(text)
html = "<pre class=\"clearfix\">"
#html << text.gsub!(/\r\n/,"\n")
html << h(text)
html << "</pre>"
html
end
end

View file

@ -1,2 +0,0 @@
module MessagesOpsHelper
end

View file

@ -1,16 +0,0 @@
module PrefsHelper
def servers_table_header
html = ""
$defaults["servers_table_fields"].each do |f|
html << "<th>"
if params[:sort_field] == f
params[:sort_dir].nil? ? dir = 'desc' : dir = nil
end
html << link_to(Server.human_attribute_name(f), {:controller => 'prefs',:action => 'servers',:sort_field => f,:sort_dir => dir}, {:class=>"header"})
html << "</th>"
end
html
end
end

View file

@ -1,2 +0,0 @@
module UserHelper
end

0
public/stylesheets/.gitkeep → app/mailers/.gitkeep Executable file → Normal file
View file

0
themes/olive/images/.gitkeep → app/models/.gitkeep Executable file → Normal file
View file

View file

@ -1,54 +0,0 @@
class Contact < ActiveRecord::Base
validates_length_of :nick, :within => 5..15
validates_length_of :first_name,:last_name, :within => 3..20
validates_length_of :email, :within => 5..50
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
validates_length_of :info, :maximum => 100
validate :check_unique_nick, :on => :create
default_scope :order => 'nick ASC'
belongs_to :user
def self.getPageForUser(user,page,sort_field,sort_dir)
if sort_field
if Contact.attribute_method?(sort_field) == true
order = sort_field
sort_dir == 'desc' ? order += ' desc' : sort_dir
end
end
Contact.paginate :page => page , :per_page => $defaults["contacts_per_page"], :conditions=> ['user_id = ?', user.id],:order => order
end
def full_name
first_name + ' ' + last_name
end
def check_unique_nick
if !Contact.where('upper(nick) = ? and user_id = ?',nick.upcase,user_id).size.zero?
errors.add(:nick, :not_unique)
end
end
def export
fields = []
fields << nick.presence || ""
fields << first_name || ""
fields << last_name || ""
fields << email || ""
fields << info || ""
fields.join(';')
end
def self.import(user,line)
fields = line.split(/;/)
contact = user.contacts.build( :nick => fields[0].strip,
:first_name => fields[1].strip,
:last_name => fields[2].strip,
:email => fields[3].strip,
:info => fields[4].strip)
contact.save!
end
end

View file

@ -1,146 +0,0 @@
class Folder < ActiveRecord::Base
belongs_to :user
validates_presence_of :name, :on => :create
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
else
parent + delim + name
end
end
def depth
parent.split('.').size
end
def selected?(session_folder)
fields = session_folder.split("#")
fields[1].nil? ? fields.insert(0,"") : fields
(fields[1].downcase == name.downcase) && (fields[0].downcase == parent.downcase)
end
def update_stats
logger.info "MESS_BEFORE: "+messages.inspect
unseen = messages.where(:unseen => true).count
total = messages.count
logger.info "MESS: "+messages.inspect
logger.info "MESS: #{unseen} #{total}"
update_attributes(:unseen => unseen, :total => total)
end
def hasFullName?(folder_name)
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
def check_fill_params
self.total.nil? ? self.total = 0 : self.total
self.unseen.nil? ? self.unseen = 0 : self.unseen
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)
imapFolders.each do |name,data|
data.attribs.find_index(:Haschildren).nil? ? has_children = 0 : has_children = 1
name_fields = name.split(data.delim)
if name_fields.count > 1
name = name_fields.delete_at(name_fields.size - 1)
parent = name_fields.join(data.delim)
else
name = name_fields[0]
parent = ""
end
user.folders.create(
:name => name,
:parent => parent,
:haschildren => has_children,
:delim => data.delim,
:total => data.messages,
:unseen => data.unseen,
:sys => SYS_NONE)
end
end
def self.find_by_full_name(data)
folder = data.gsub(/\./,'#')
fields = folder.split("#")
nam = fields.delete_at(fields.size - 1)
fields.size.zero? == true ? par = "" : par = fields.join(".")
where(['name = ? and parent = ?',nam,par]).first
end
def self.refresh(mailbox,user)
user.folders.destroy_all
folders=mailbox.folders
Folder.createBulk(user,folders)
end
end

View file

@ -1,19 +0,0 @@
class Link < ActiveRecord::Base
validates_length_of :name, :within => 5..30
validates_length_of :url, :within => 5..150
validates_length_of :info, :maximum => 50
belongs_to :user
default_scope :order => 'name asc'
def self.getPageForUser(user,page,sort_field,sort_dir)
if sort_field
if Link.attribute_method?(sort_field) == true
order = sort_field
sort_dir == 'desc' ? order += ' desc' : sort_dir
end
end
Link.paginate :page => page , :per_page => $defaults["links_per_page"], :conditions=> ['user_id = ?', user.id],:order => order
end
end

View file

@ -1,72 +0,0 @@
require 'iconv'
require 'mail'
class Message < ActiveRecord::Base
belongs_to :user
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, :body,:cc_addr,:bcc_addr
attr_accessor :body
def self.addr_to_db(addr)
ret = ""
name = addr.name
name.nil? ? ret : ret << ApplicationController.decode_quoted(name)
ret << "<" + addr.mailbox + "@" + addr.host
ret
end
def self.getPageForUser(user,folder,page,sort_field,sort_dir)
order = 'date desc'
if sort_field
if Message.attribute_method?(sort_field) == true
order = sort_field
sort_dir == 'desc' ? order += ' desc' : sort_dir
end
end
Message.paginate :page => page , :per_page => user.prefs.msgs_per_page.to_i, :conditions=> ['user_id = ? and folder_id = ?', user.id,folder.id],:order => order
end
def self.createForUser(user,folder,message)
# envelope = imap_message.attr['ENVELOPE']
#
# 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)
mail = Mail.new(message.attr['RFC822.HEADER'])
mail.date.nil? ? date = nil : date = mail.date.to_s
mail.From.nil? ? from = nil : from = mail.From.charseted
mail.To.nil? ? to = nil : to = mail.To.charseted
mail.Subject.nil? ? subject = nil : subject = mail.Subject.charseted
#logger.custom('subject',mail.Subject.encoded)
#logger.custom('subject',subject)
#logger.custom('mail',mail.inspect)
create(
:user_id => user.id,
:folder_id => folder.id,
:msg_id => mail.message_id,
:uid => message.attr['UID'].to_i,
:from_addr => from,
:to_addr => to,
:subject => subject,
:content_type => mail.content_type,
:date => date,
:unseen => !(message.attr['FLAGS'].member? :Seen),
:size => message.attr['RFC822.SIZE']
)
end
def change_folder(folder)
update_attributes(:folder_id => folder.id)
end
end

View file

@ -1,19 +0,0 @@
class Prefs < ActiveRecord::Base
validates_presence_of :theme,:locale
has_one :user
protected
def self.create_default(user)
Prefs.create(:user_id => user.id,
:theme => $defaults['theme'],
:locale => $defaults['locale'],
:msgs_per_page => $defaults['msgs_per_page'],
:msg_send_type => $defaults['msg_send_type']
)
end
end
# TODO move refresh to prefs and make refresh page with messages

View file

@ -1,41 +0,0 @@
class Server < ActiveRecord::Base
validates_presence_of :name
belongs_to :user
#before_save :fill_params
def self.primary_for_imap
where(:for_imap=>true).first
end
def self.primary_for_smtp
where(:for_smtp=>true).first
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

View file

@ -1,64 +0,0 @@
require 'ezcrypto'
class User < ActiveRecord::Base
#acts_as_notes_owner
validates_presence_of :first_name,:last_name
validates_uniqueness_of :login
has_many :servers, :dependent => :destroy
has_one :prefs, :dependent => :destroy
has_many :folders, :dependent => :destroy
has_many :messages, :dependent => :destroy
has_many :contacts, :dependent => :destroy
has_many :links, :dependent => :destroy
def set_cached_password(session,password)
if $defaults['session_encryption']
session[:session_salt] = generate_salt
session[:user_password] = EzCrypto::Key.encrypt_with_password($defaults['session_password'], session[:session_salt], password)
else
session[:user_password] = password
end
end
def get_cached_password(session)
if $defaults['session_encryption']
EzCrypto::Key.decrypt_with_password($defaults['session_password'], session[:session_salt], session[:user_password])
else
session[:user_password]
end
end
def generate_salt
(0...8).map{65.+(rand(25)).chr}.join
end
def name
first_name + " " + last_name
end
def full_id
(name + " <" + email + ">") if email
end
def email
if login =~ /\@/
login
else
(login + "@" + domain) if domain.presence
end
end
def username
login.gsub(/\@/,"_").gsub(/\./,"_")
end
def has_domain?
return domain if domain.presence
if login =~ /\@/
login.split(/\@/)[1]
end
end
end

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Mailr</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

0
config.ru Executable file → Normal file
View file

52
config/application.rb Executable file → Normal file
View file

@ -2,9 +2,12 @@ require File.expand_path('../boot', __FILE__)
require 'rails/all'
# If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module Mailr
class Application < Rails::Application
@ -13,47 +16,44 @@ module Mailr
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
#config.plugins = [ :acts_as_notes_owner, :all ]
config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
config.time_zone = 'Warsaw'
#FIXME time zone move to config
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# JavaScript files you want as :defaults (application.js is always included).
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Use SQL instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Enforce whitelist mode for mass assignment.
# This will create an empty whitelist of attributes available for mass-assignment for all models
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
# parameters by using an attr_accessible or attr_protected declaration.
# config.active_record.whitelist_attributes = true
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
end
end
class ActiveSupport::BufferedLogger
def custom(desc,t)
info "\n**** #{desc} *****"
info t
info "**********************\n\n"
end
end
class MailrException < Exception
end

0
config/boot.rb Executable file → Normal file
View file

42
config/database.yml Normal file
View file

@ -0,0 +1,42 @@
# MySQL. Versions 4.1 and 5.0 are recommended.
#
# Install the MYSQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
adapter: mysql2
encoding: utf8
reconnect: false
database: mailr_development
pool: 5
username: root
password:
host: localhost
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
encoding: utf8
reconnect: false
database: mailr_test
pool: 5
username: root
password:
host: localhost
production:
adapter: mysql2
encoding: utf8
reconnect: false
database: mailr_production
pool: 5
username: root
password:
host: localhost

View file

@ -1,53 +0,0 @@
version: 0.8.7
theme: olive
locale: pl
themes: [olive]
locales: [en, pl]
msgs_per_page_table: [15, 20, 25, 30, 35, 40, 45, 50]
msg_send_type: [html, text]
msg_image_view_as: [attachment, thumbnail]
msg_image_thumbnail_size: [128x128, 128x96, 192x192, 192x144, 256x256, 256x192]
contacts_table_fields: [nick, first_name, last_name, email, info]
contacts_per_page: 25
links_table_fields: [name, url, info]
links_per_page: 30
servers_table_fields: [name, port, use_ssl, use_tls, for_imap, for_smtp, auth]
msgs_per_page: 20
msgs_refresh_time: 300
msgs_send_type: html
msgs_update_time: 600
msgs_inbox_view_fields: [from_addr, subject, date, size]
msgs_sent_view_fields: [to_addr, subject, date, size]
msg_subject_length: 50
msg_address_length: 35
msg_search_fields: [subject, from, to]
msg_upload_dir: "tmp/uploads"
contact_tmp_filename: contact_import
# if encoding can not be get from data
msg_unknown_charset: ISO-8859-2
imap_debug: true
imap_use_ssl: 'false'
imap_port: 143
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
# array of logins which only can login to application, comment it to allow everyone to login
only_can_logins: [somelogin1, somelogin2]

1
config/environment.rb Executable file → Normal file
View file

@ -3,4 +3,3 @@ require File.expand_path('../application', __FILE__)
# Initialize the rails application
Mailr::Application.initialize!

19
config/environments/development.rb Executable file → Normal file
View file

@ -3,15 +3,14 @@ Mailr::Application.configure do
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = false
config.action_view.debug_rjs = true
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
@ -22,5 +21,17 @@ Mailr::Application.configure do
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
end
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
end

44
config/environments/production.rb Executable file → Normal file
View file

@ -1,7 +1,6 @@
Mailr::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# The production environment is meant for finished, "live" apps.
# Code is not reloaded between requests
config.cache_classes = true
@ -9,31 +8,46 @@ Mailr::Application.configure do
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to Rails.root.join("public/assets")
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
#config.action_dispatch.x_sendfile_header = "X-Sendfile"
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# For nginx:
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
# If you have no front-end server that supports something like X-Sendfile,
# just comment this out and Rails will serve the files
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Prepend all log lines with the following tags
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Disable Rails's static asset server
# In production, Apache or nginx will already do this
config.serve_static_assets = false
# Enable serving of images, stylesheets, and javascripts from an asset server
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
@ -46,4 +60,8 @@ Mailr::Application.configure do
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
# config.active_record.auto_explain_threshold_in_seconds = 0.5
end

12
config/environments/test.rb Executable file → Normal file
View file

@ -7,7 +7,11 @@ Mailr::Application.configure do
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Log error messages when you accidentally call methods on nil.
# Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
# Log error messages when you accidentally call methods on nil
config.whiny_nils = true
# Show full error reports and disable caching
@ -25,10 +29,8 @@ Mailr::Application.configure do
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr

0
config/initializers/backtrace_silencers.rb Executable file → Normal file
View file

5
config/initializers/inflections.rb Executable file → Normal file
View file

@ -8,3 +8,8 @@
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
#
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.acronym 'RESTful'
# end

0
config/initializers/mime_types.rb Executable file → Normal file
View file

2
config/initializers/secret_token.rb Executable file → Normal file
View file

@ -4,4 +4,4 @@
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Mailr::Application.config.secret_token = 'f07b5830035b1471d3c008debde5c152077eaff97f0dfcebaf265fe96db24dc5af46eb27e149e3077df89d7dbe2eb088ab7ef7b0e8b496d7ca005e31f6dc3017'
Mailr::Application.config.secret_token = '014b3111b40bea36f7c0ab07ff2ae820f71b19bb67970baf1f7b44dc1555aae92a68395db757548058884dd4884b1267823d4d44a783160a595e2668d2e904a8'

0
config/initializers/session_store.rb Executable file → Normal file
View file

View file

@ -1,16 +0,0 @@
require 'action_dispatch/middleware/show_exceptions'
module ActionDispatch
class ShowExceptions
private
def render_exception_with_template(env, exception)
body = InternalController.action(rescue_responses[exception.class.name]).call(env)
log_error(exception)
body
rescue
render_exception_without_template(env, exception)
end
alias_method_chain :render_exception, :template
end
end

View file

@ -0,0 +1,14 @@
# Be sure to restart your server when you modify this file.
#
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters :format => [:json]
end
# Disable root element in JSON by default.
ActiveSupport.on_load(:active_record) do
self.include_root_in_json = false
end

66
config/locales/en.yml Executable file → Normal file
View file

@ -1,63 +1,5 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
activerecord:
attributes:
prefs:
theme: Theme
locale: Locale
msgs_per_page: Messages per page
msg_send_type: Message send format
contact:
compose_to_selected: Compose to selected
delete_selected: Delete selected
modifying: Modifying contact
creating_new: Creating new contact
create_new: Create new contact
contacts: Contacts
contact: Contact
no_selected: No contact selected
total_entries: Total contacts entries
no_entries: No contacts
was_created: Contact was created
are_you_sure_to_delete_contact: Are You sure to delete contact?
prefs:
prefs: Preferences
folder:
folders: Folders
no_shown: No folders shown
parent: Parent folder
to_create: Folder to create
to_delete: Folder to delete
shown: Shown folders
emptybin: Empty
current: Current folder
no_selected: No folder selected
to_create_empty: No folder name
max_depth: Maximum folder depth reached
can_not_create: Can not create folder
was_created: Folder was created
to_delete_empty: No folder to delete
can_not_delete: Can not delete folder
was_deleted: Folder was deleted
message:
messages: Messages
compose:
compose: Compose
user:
login_failure: Login failure. Bad email or password
logged_out: User was logged out
setup_done: Setup done. Please login in
must_be_unique: must be unique
some_add_info: some additional information
example: example
refresh: Refresh
create: Create
delete: Delete
show_hide: Show/Hide
mailr: Mailr
save: Save
hello: "Hello world"

View file

@ -1,160 +0,0 @@
en:
activerecord:
attributes:
prefs:
theme: Theme
locale: Locale
msgs_per_page: Messages per page
msg_send_type: Message send format
contact:
compose_to_selected: Compose to selected
delete_selected: Delete selected
modifying: Modifying contact
creating_new: Creating new contact
create_new: Create new contact
contacts: Contacts
contact: Contact
no_selected: No contact selected
total_entries: Total contacts entries
no_entries: No contacts
was_created: Contact was created
are_you_sure_to_delete_contact: Are You sure to delete contact?
prefs:
prefs: Preferences
folder:
folders: Folders
no_shown: No folders shown
parent: Parent folder
to_create: Folder to create
to_delete: Folder to delete
shown: Shown folders
emptybin: Empty
current: Current folder
no_selected: No folder selected
message:
messages: Messages
compose:
compose: Compose
must_be_unique: must be unique
some_add_info: some additional information
example: example
refresh: Refresh
create: Create
delete: Delete
show_hide: Show/Hide
mailr: Mailr
email: Email
password: Password
log_in: Log In
wrong_email_or_password: Wrong email or password specified.
mailbox: Mailbox
empty: Empty
logout: Logout
filters: Filters
search: Search
search_txt: Search in message field
operations: Operations
operations_txt: Operations on marked messages
copy: copy
move: move
mark_read: mark read
mark_unread: mark unread
destination_txt: Destination for move and copy operations
for: for
to: To
subject: Subject
date: Date
size: Size
from: From
show_all: Show all
pages: Pages
first: First
prev: Prev
next: Next
last: Last
back_to_list: Back to list
back_to_message: Back to message
reply: Reply
forward: Forward
delete: Delete
view_source: View source
add_filter: Add filter
cc: CC
bcc: BCC
send: Send
choose_address: Choose addresses from contacts
compose_txt: Compose new mail
attachment: Attachment
add: Add
first_name: First name
last_name: Last name
send_type: Send type message
messages_per_page: Messages per page
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: Save
cancel: Cancel
add_one_contact: Add one contact
add_multiple: Add multiple
name: name
add_folder: Add folder
total_messages: Total messages
unseen: Unseen
please_login: Log in
site_link: https://github.com/lmanolov/mailr
user_logged_out: User was logged out
unknown_user_title: Unknown user
unknown_user_flash: Your email identifier was not found in database
unknown_user_login: Go to login page and try to login once more.
unknown_user_setup: Go to setup page and do the setup of Your mail account.
setup_title: Setup
server_name: Server name
setup_done: Setup done. Please log in
login_failure: Login failure. Bad email or password
general_error: General error
unspecified_error: Unspecified error occured
imap_error: IMAP Error
folder_to_create: Folder to create
subscribe_unsubscribe: (Un)Subscribe
folders_subscribed_selected: Folders subscribed
messages: Messages
folder_to_create_empty: Folder to create is empty
folder_was_created: Folder was created
can_not_create_folder: Can not create folder
folder_max_depth: Maximum folder depth reached
folder_to_delete_empty: Folder to delete empty
folder_was_deleted: Folder was deleted
can_not_delete_folder: Can not delete folder
system_folder: System folder
refresh_folders: Refresh folders
show_hide: Show/Hide
page_not_found: Page not found
bytes: Bytes
kbytes: Kb
mbytes: MB
previous_page: Previous page
next_page: Next page
copy: Copy
move: Move
checked_messages: checked messages
to: to
to_folder: folder
set_read: Set read
set_unread: Set unread
search: Search
in_message_field: in message field
string: string
total_messages: Total messages
no_messages_in: No messages in folder
no_subject: No subject
no_messages_selected: No messages selected

View file

@ -1,91 +0,0 @@
es-ES:
mailr: Mailr
email: Email
password: Contrase&ntilde;a
log_in: Iniciar sesi&oacute;n
wrong_email_or_password: Email o contrase&ntilde;a incorrecta
mailbox: Buzon de Correo
folders: Carpetas
folder: Carpeta
empty: Vaciar
logout: Cerrar sesi&oacute;n
compose: Redactar
preferences: Opciones
filters: Filtros
contacts: Contactos
search: Buscar
search_txt: Buscar en el campo
refresh: Refrescar
operations: Operaciones
operations_txt: Operaciones en mensajes marcados
delete: borrar
copy: copiar
move: mover
junk: Basura
sent: Enviados
inbox: Bandeja de Entrada
trash: Basura
drafts: Borradores
mark_read: marcar como leido
mark_unread: marcar comono leido
destination_txt: Destino para operaciones de copiado y movido
for: para
to: Para
subject: Asunto
date: Fecha
size: Tama&ntilde;o
from: De
show_all: Mostrar todos
pages: P&aacute;ginas
first: Primero
prev: Previo
next: Siguiente
last: &Uacute;ltimo
back_to_list: Volver a la lista
back_to_message: Volver al mensaje
reply: Responder
forward: Reenviar
view_source: Ver fuente
add_filter: Agregar filtro
cc: CC
bcc: BCC
send: Enviar
choose_address: Elegir direcci&oacute;n desde contactos
choose: Elegir
compose_txt: Componer nuevo correo
groups: Grupos
attachment: Adjunto
add: Agregar
first_name: Nombre
last_name: Apellido
send_type: Enviar mensaje tipo
messages_per_page: Mensajes por p&aacute;gina
check_external_mail: Comprobar correos externos?
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: Guardar
save_and_add_another: Guardar y agregar otro
cancel: Cancelar
add_one_contact: Agregar un contacto
add_multiple: Agregar multiples
add_multiple_contacts: Agregar multiples contactos
name: nombre
add_folder: Agregar carpeta
total_messages: Mensajes totales
unseen: No leidos
edit_create_contact: Editar o crear contacto
back_to_contacts: Volver a contactos
email_exists: Una cuenta con ese correo electr&oacute;nico ya existe.
delete_contact_question: "Desea borrar este contacto? {{name}} - {{email}}"
validate_fname_error: Por favor, ingrese un nombre (2 a 20 caracteres)
validate_lname_error: Por favor, ingrese un apellido (2 a 20 caracteres)
validate_email_error: Por favor, ingrese una direcci&oacute;n email v&aacute;lida.
contact_cannot_be_changed: El email del contacto no puede ser cambiado
csv_file: Archivo separado por comas(CSV)
tab_file: Archivo separado por tabulaciones
select_file: Selecionar archivo
import: Importar
back_to_folders: Volver a carpetas
add_edit_folder: agregar/editar
user_logged_out: Sesi&oacute;n cerrada correctamente
please_login: Por favor, inicie sesi&oacute;n
want_to_empty_trash_message: ¿Realmente quieres vaciar la papelera?

View file

@ -1,227 +0,0 @@
pl:
date:
day_names: [Niedziela, Poniedziałek, Wtorek, Środa, Czwartek, Piątek, Sobota]
abbr_day_names: [Ni, Po, Wt, Śr, Cz, Pi, So]
month_names: [~, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień]
abbr_month_names: [~, Sty, Lut, Mar, Kwi, Maj, Czer, Lip, Sier, Wrze, Paź, Lis, Grudz]
order: [ :year, :month, :day ]
activerecord:
errors:
messages:
blank: "nie może być pust(a/e/y) "
too_short: "za krótki(e) (min. %{count} znak(i/ów)) "
too_long: "za długi(e) (max. %{count} znak(i/ów)) "
invalid: "ma niepoprawny format "
not_unique: "musi być unikalny "
taken: "musi być unikalny"
record_invalid: Nieprawidłowy format danych
models:
contact: Kontakt
server: Serwer
link: Sznurek
attributes:
link:
name: Nazwa
url: Adres
info: Informacje
contact:
nick: Pseudonim
first_name: Imię
last_name: Nazwisko
email: E-mail
info: Informacje dodatkowe
prefs:
theme: Temat
locale: Ustawienia językowe
msgs_per_page: Ilość wiadomości wyświetlanych na stronie
msg_send_type: Format wysyłanej wiadomości
msg_image_view_as: Prezentuj obraz jako
msg_image_thumbnail_size: Rozmiar miniaturki obrazu
message:
from_addr: Od
to_addr: Do
subject: Temat
size: Rozmiar
date: Data
body: Treść
cc_addr: Dw
bcc_addr: UDw
user:
email: E-mail
password: Hasło
first_name: Imię
last_name: Nazwisko
domain: Domena
server:
name: Nazwa serwera
port: Port
use_ssl: SSL?
use_tls: TLS?
for_imap: IMAP?
for_smtp: SMTP?
auth: Metoda autoryzacji
contact:
compose_to_selected: Napisz do wybranych
delete_selected: Usuń wybrane
modifying: Modyfikacja kontaktu
creating_new: Nowy kontakt
create_new: Utwórz nowy kontakt
contacts: Kontakty
contact: Kontakt
no_selected: Nie wybrano żadnego kontaktu
total_entries: Liczba kontaktów
no_entries: Brak kontaktów
was_created: Kontakt został utworzony
are_you_sure_to_delete_contact: Czy na pewno chcesz usunąć kontakt?
export: Export
import: Import
were_imported: Kontakty zostały zaimportowane
format_error: Nieprawidłowy format kontaktu
link:
link: Sznurek
links: Sznurki
create_new: Utwórz nowy sznurek
no_entries: Brak sznurków
total_entries: Liczba sznurków
delete_selected: Usuń wybrane
prefs:
prefs: Ustawienia
look: Wygląd
identity: Tożsamość
servers: Serwery
were_saved: Ustawienia zostały zapisane
thumbnail: Miniaturka
attachment: Załącznik
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: Wyświetlane foldery
emptybin: Opróżnij
current: Folder bieżący
no_selected: Nie wybrano żadnego folderu
to_create_empty: Nie podano nazwy folderu
max_depth: Osiągnięto maksymalne zagnieżdzenie fodlderów
can_not_create: Nie można utworzyć folderu
was_created: Folder został utworzony
to_delete_empty: Nie wybrano folderu do usunięcia
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
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_hide: Pokaż/Ukryj
refresh: Odśwież
message:
messages: Wiadomości
no_selected: Nie wybrano żadnej wiadomości
total: Liczba wszystkich wiadomości
checked: zaznaczone wiadomości
set_read: Ustaw jako przeczytane
set_unread: Ustaw jako nieprzeczytane
no_in: Nie ma żadnych wiadomości w bieżącym folderze
no_subject: Brak tematu
no_content: Wiadomość nie zawiera treści
attachments: Załączniki
content: Treść wiadomości
header_source: Nagłówek wiadomości
show_header: Pokaż nagłówek
edit: Edycja
images: Obrazy
delete: Usuń zaznaczone
move: Przenieś
copy: Skopiuj
trash: Usuń zaznaczone
no_date: Brak daty
compose:
compose: Nowa wiadomość
new_message: Nowa wiadomość
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ść
was_sent: Wiadomość została wysłana
was_saved: Wiadomość została zapisana w katalogu roboczym
not_configured_smtp: Brak konfiguracji SMTP
select_file: Wybierz plik
delete_marked: Usuń zaznaczone
upload: Wyślij plik
sendout: Wyślij
save: Zapisz w katalogu roboczym
show:
reply: Odpowiedz
show_header: Pokaż nagłówek
delete: Usuń
reply_string: "Odp: "
trash: Usuń
user:
login_failure: Nieudane logowanie. Podano błędny e-mail lub hasło.
logged_out: Użytkownik wylogowany
setup_done: Konfiguracja zakończona. Proszę się zalogować.
please_login: Logowanie
unknown_title: Nieznany użytkownik
unknown_flash: Twój identyfikator użytkownika nie został odnaleziony w bazie
unknown_login: Idź do strony logowania i zaloguj sie jeszcze raz
unknown_setup: Idź do strony konfiguracyjnej i skonfiguruj swój dostęp
setup: Konfiguracja
login: Logowanie
only_can_logins: Podany identyfikator użytkownika nie uprawnia do korzystania z aplikacji
logout: Wyloguj
has_no_domain: Użytkownik nie ma ustawionej domeny
internal:
imap_error: Błąd protokołu IMAP
unspecified_error: Nieoczekiwany błąd
not_found: Nie znaleziono żądanej strony
internal_server_error: Błąd aplikacji
unprocessable_entity: Błąd procesowania
about: Informacje o programie
current_version: Aktualna wersja
general_error: Błąd aplikacji
common:
false_answer: Nie
true_answer: Tak
file_format_error: Błędny format pliku
no_tmp_dir: Brak katalogu tymczasowego
must_be_unique: musi być unikalny
some_add_info: jakieś dodatkowe informacje
example: przykład
create: Utwórz
delete: Usuń
mailr: MailR
save: Zapisz
copy: Skopiuj
move: Przenieś
to: do
previous_page: Poprzednia
next_page: Następna
bytes: B
kbytes: kB
mbytes: MB
site_link: https://github.com/lmanolov/mailr
no_data: Brak danych
download: Pobierz
view: Pokaż
version: Wersja
set: Ustaw
no_file_chosen: Nie wybrano żadnego pliku
calendar: Kalendarz

113
config/routes.rb Executable file → Normal file
View file

@ -1,79 +1,58 @@
Mailr::Application.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
namespace :prefs do
post "update_look"
post "update_identity"
post "update_servers"
end
match "prefs/look" => "prefs#look", :as => :prefs_look
match "prefs/identity" => "prefs#identity", :as => :prefs_identity
match "prefs/servers" => "prefs#servers", :as => :prefs_servers
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
namespace :contacts do
post "ops"
get "export"
end
match "/external" => "contacts#external", :as => :contacts_external
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
resources :contacts
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
namespace :links do
post "ops"
get "export"
end
#match "/external" => "contacts#external", :as => :contacts_external
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
resources :links
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
namespace :folders do
post "create"
post "delete"
post "system"
post "show_hide"
post "refresh"
get "refresh_status"
get "emptybin"
end
match "/folders/index" => 'folders#index', :as => :folders
match "/folders/select/:id" => 'folders#select', :as => :folders_select
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
namespace :internal do
get "error"
get "imaperror"
get "loginfailure"
get "onlycanlogins"
end
match "/internal/about" => 'internal#about' ,:as => :about
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'
match "/messages_ops/single" => 'messages_ops#single'
match "/messages_ops/multi" => 'messages_ops#multi'
match "/messages_ops/sendout_or_save" => 'messages_ops#sendout_or_save' ,:as =>:sendout_or_save
match "/messages_ops/upload" => 'messages_ops#upload',:as => :upload
match "/messages_ops/edit/:id" => 'messages_ops#edit', :as => :edit
match "/messages_ops/composed" => 'messages_ops#composed', :as => :composed
# See how all your routes lay out with "rake routes"
root :to => "messages#index"
match "/messages/index" => 'messages#index', :as => :messages
match "/messages/compose" => 'messages#compose', :as => :compose
match "/messages/compose/:cid" => 'messages#compose', :as => :compose_contact
match "/messages/show/:id" => 'messages#show'
match "/messages/html_body/:id" => 'messages#html_body' , :as => :html_body
match "/messages/attachment/:id/:idx" => 'messages#attachment', :as => :attachment_download
namespace :user do
get "logout"
post "authenticate"
post "create"
get "login"
get "setup"
get "unknown"
end
match "/user/setup/:login" => 'user#setup'
themes_for_rails
#match '*a', :to => 'internal#not_found'
#match ':controller(/:action(/:id(.:format)))'
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
end

View file

@ -1,15 +0,0 @@
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :email
t.string :first_name
t.string :last_name
t.timestamps
end
end
def self.down
drop_table :users
end
end

View file

@ -1,14 +0,0 @@
class CreateServers < ActiveRecord::Migration
def self.up
create_table :servers do |t|
t.string :name
t.string :port
t.references :user
t.timestamps
end
end
def self.down
drop_table :servers
end
end

View file

@ -1,14 +0,0 @@
class CreatePrefs < ActiveRecord::Migration
def self.up
create_table :prefs do |t|
t.string :theme
t.string :locale
t.references :user
t.timestamps
end
end
def self.down
drop_table :prefs
end
end

View file

@ -1,11 +0,0 @@
class AddParamsToPrefs < ActiveRecord::Migration
def self.up
add_column :prefs, :msgs_per_page, :string
add_column :prefs, :msg_send_type, :string
end
def self.down
remove_column :prefs, :msg_send_type
remove_column :prefs, :msgs_per_page
end
end

View file

@ -1,9 +0,0 @@
class AddUseSslToServers < ActiveRecord::Migration
def self.up
add_column :servers, :use_ssl, :boolean
end
def self.down
remove_column :servers, :use_ssl, :boolean
end
end

View file

@ -1,17 +0,0 @@
class CreateFolders < ActiveRecord::Migration
def self.up
create_table :folders do |t|
t.string :name
t.string :delim
t.string :attribs
t.integer :messages
t.integer :new
t.references :user
t.timestamps
end
end
def self.down
drop_table :folders
end
end

View file

@ -1,11 +0,0 @@
class RenameAttribsInFolders < ActiveRecord::Migration
def self.up
rename_column :folders,:attribs,:haschildren
change_column :folders,:haschildren,:boolean
end
def self.down
change_column :folders,:haschildren,:string
rename_column :folders,:haschildren,:attribs
end
end

View file

@ -1,9 +0,0 @@
class ChangeNewInFolder < ActiveRecord::Migration
def self.up
rename_column :folders,:new,:unseen
end
def self.down
rename_column :folders,:unseen,:new
end
end

View file

@ -1,9 +0,0 @@
class AddColumnToFolder < ActiveRecord::Migration
def self.up
add_column :folders, :parent, :string
end
def self.down
remove_column :folders, :parent
end
end

View file

@ -1,9 +0,0 @@
class AddColumnMsgsToFolder < ActiveRecord::Migration
def self.up
add_column :folders, :msgs_updated_at, :datetime
end
def self.down
remove_column :folders, :msgs_updated_at
end
end

View file

@ -1,23 +0,0 @@
class CreateMessages < ActiveRecord::Migration
def self.up
create_table :messages ,:id => false do |t|
t.integer :folder_id
t.integer :user_id
t.string :msg_id
t.string :from
t.string :to
t.string :subject
t.string :content_type
t.integer :uid
t.integer :size
t.boolean :unread
t.datetime :date
t.timestamps
end
end
def self.down
drop_table :messages
end
end

View file

@ -1,11 +0,0 @@
class AddShownToFolders < ActiveRecord::Migration
def self.up
add_column :folders, :shown, :boolean
add_column :folders, :alter_name, :string
end
def self.down
remove_column :folders, :alter_name
remove_column :folders, :shown
end
end

View file

@ -1,9 +0,0 @@
class RenameMEssagesInFolder < ActiveRecord::Migration
def self.up
rename_column :folders,:messages,:total
end
def self.down
rename_column :folders,:total,:messages
end
end

View file

@ -1,9 +0,0 @@
class RenameUnseenInMessage < ActiveRecord::Migration
def self.up
rename_column :messages, :unread, :unseen
end
def self.down
rename_column :messages, :unseen, :unread
end
end

View file

@ -1,17 +0,0 @@
class CreateContacts < ActiveRecord::Migration
def self.up
create_table :contacts do |t|
t.string :nick
t.string :email
t.string :first_name
t.string :last_name
t.string :info
t.references :user
t.timestamps
end
end
def self.down
drop_table :contacts
end
end

View file

@ -1,11 +0,0 @@
class RenameFromColumnInMessages < ActiveRecord::Migration
def self.up
rename_column :messages, :from, :from_addr
rename_column :messages, :to, :to_addr
end
def self.down
rename_column :messages, :from_addr, :from
rename_column :messages, :to_addr, :to
end
end

View file

@ -1,9 +0,0 @@
class RemoveMsgsUpdateFromMessages < ActiveRecord::Migration
def self.up
remove_column :folders, :msgs_updated_at
end
def self.down
add_column :folders, :msgs_updated_at, :datetime
end
end

View file

@ -1,13 +0,0 @@
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

View file

@ -1,9 +0,0 @@
class AddDomainToUsers < ActiveRecord::Migration
def self.up
add_column :users, :domain, :string
end
def self.down
remove_column :users, :domain
end
end

View file

@ -1,9 +0,0 @@
class AddTypeToFolders < ActiveRecord::Migration
def self.up
add_column :folders, :sys, :integer
end
def self.down
remove_column :folders, :sys
end
end

View file

@ -1,9 +0,0 @@
class AddAuthToServers < ActiveRecord::Migration
def self.up
add_column :servers, :auth, :string
end
def self.down
remove_column :servers, :auth
end
end

View file

@ -1,11 +0,0 @@
class AddMsgParamsToPrefs < ActiveRecord::Migration
def self.up
add_column :prefs, :msg_image_view_as, :string
add_column :prefs, :msg_image_thumbnail_size, :string
end
def self.down
remove_column :prefs, :msg_image_thumbnail_size
remove_column :prefs, :msg_image_view_as
end
end

View file

@ -1,9 +0,0 @@
class RenameEmailInUser < ActiveRecord::Migration
def self.up
rename_column :users, :email, :login
end
def self.down
rename_column :users, :login, :email
end
end

View file

@ -1,17 +0,0 @@
class CreateLinks < ActiveRecord::Migration
def self.up
create_table :links do |t|
t.integer :user_id
t.integer :lgroup_id
t.string :name
t.string :url
t.string :info
t.timestamps
end
end
def self.down
drop_table :links
end
end

View file

@ -1,103 +0,0 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110927091830) do
create_table "contacts", :force => true do |t|
t.string "nick"
t.string "email"
t.string "first_name"
t.string "last_name"
t.string "info"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "events", :force => true do |t|
t.integer "user_id"
t.integer "priority"
t.text "description"
t.string "category"
t.datetime "start"
t.datetime "stop"
t.boolean "allday"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "folders", :force => true do |t|
t.string "name"
t.string "delim"
t.boolean "haschildren"
t.integer "total"
t.integer "unseen"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "parent"
t.boolean "shown"
t.string "alter_name"
t.integer "sys"
end
create_table "messages", :id => false, :force => true do |t|
t.integer "folder_id"
t.integer "user_id"
t.string "msg_id"
t.string "from_addr"
t.string "to_addr"
t.string "subject"
t.string "content_type"
t.integer "uid"
t.integer "size"
t.boolean "unseen"
t.datetime "date"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "prefs", :force => true do |t|
t.string "theme"
t.string "locale"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "msgs_per_page"
t.string "msg_send_type"
t.string "msg_image_view_as"
t.string "msg_image_thumbnail_size"
end
create_table "servers", :force => true do |t|
t.string "name"
t.string "port"
t.integer "user_id"
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|
t.string "login"
t.string "first_name"
t.string "last_name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "domain"
end
end

2
db/seeds.rb Executable file → Normal file
View file

@ -4,4 +4,4 @@
# Examples:
#
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
# Mayor.create(:name => 'Daley', :city => cities.first)
# Mayor.create(:name => 'Emanuel', :city => cities.first)

0
doc/README_FOR_APP Executable file → Normal file
View file

View file

View file

@ -1,23 +0,0 @@
require 'net/imap'
module ImapFolderModule
class IMAPFolder
attr_reader :utf7_name
attr_reader :delim
attr_reader :attribs
attr_reader :name
attr_accessor :messages
attr_accessor :unseen
def initialize(utf7_name,delim,attribs)
@utf7_name = utf7_name
@name = Net::IMAP.decode_utf7 utf7_name
@delim = delim
@attribs = attribs
end
end
end

View file

@ -1,207 +0,0 @@
require 'net/imap'
require 'imap_folder'
module ImapMailboxModule
class IMAPError < RuntimeError
end
class IMAPMailbox
attr_reader :connected
attr_accessor :sfolder
attr_accessor :logger
def initialize(logger,debug)
@sfolder = ''
@folders = {}
@connected = false
@logger = logger
Net::IMAP.debug = true
end
def connect(server,username,password)
server_name = server.name
server_port = server.port
server_use_ssl = server.use_ssl
unless @connected
begin
@imap = Net::IMAP.new(server_name, server_port, server_use_ssl)
rescue Net::IMAP::ByeResponseError => bye
begin
System.sleep($defaults["imap_bye_timeout_retry_seconds"])
@imap = Net::IMAP.new(server_name, server_port, server_use_ssl)
rescue Exception => ex
raise IMAPError, ex.inspect
end
rescue Exception => ex
raise IMAPError, ex.inspect
end
@username = username
begin
@imap.login(username, password)
@connected = true
rescue Exception => ex
raise IMAPError, ex.inspect
end
end
end
def disconnect
if @connected
@imap.logout
@imap.disconnect
@imap = nil
@connected = false
end
end
def folders
@folders = {}
folders = @imap.list('', '*')
if folders
folders.each do |f|
folder = ImapFolderModule::IMAPFolder.new(f.name,f.delim,f.attr)
status = @imap.status(folder.name, ["MESSAGES", "UNSEEN"])
folder.messages = status["MESSAGES"]
folder.unseen = status["UNSEEN"]
@folders[folder.name] = folder
end
end
@folders
end
def create_folder(name)
begin
@imap.create(Net::IMAP.encode_utf7(name))
rescue Exception => e
raise e
end
end
def fetch_uids
begin
uids = []
imap_uids = @imap.fetch(1..-1, "UID")
imap_uids.each do |u|
uids << u.attr['UID']
end
return uids
rescue Exception => e
raise e
end
end
def delete_folder(name)
begin
@imap.delete(Net::IMAP.decode_utf7(name))
rescue Exception => e
raise e
end
end
def fetch(range,attribs)
begin
@imap.fetch(range,attribs)
rescue Exception => e
raise e
end
end
def uid_fetch(range,attribs)
begin
@imap.uid_fetch(range,attribs)
rescue Exception => e
raise e
end
end
def set_folder(folder_name)
begin
if folder_name != @sfolder
@imap.select(folder_name)
@sfolder = folder_name
end
rescue Exception => e
raise e
end
end
def status
begin
@imap.status(@sfolder, ["MESSAGES", "RECENT", "UNSEEN"])
rescue Exception => e
raise e
end
end
def fetch_body(uid)
begin
uid_fetch(uid,"BODY[]").first.attr["BODY[]"]
rescue Exception => e
raise e
end
end
def delete_message(uid)
begin
@imap.uid_store(uid.to_i, "+FLAGS", :Deleted)
rescue Exception => e
raise e
end
end
def expunge
begin
@imap.expunge
rescue Exception => e
raise e
end
end
def set_read(uid)
begin
@imap.uid_store(uid.to_i, "+FLAGS", :Seen)
rescue Exception => e
raise e
end
end
def set_unread(uid)
begin
@imap.uid_store(uid.to_i, "-FLAGS", :Seen)
rescue Exception => e
raise e
end
end
def copy_message(uid,dest_folder)
begin
@imap.uid_copy(uid.to_i, dest_folder)
rescue Exception => e
raise e
end
end
def move_message(uid,dest_folder)
begin
copy_message(uid,dest_folder)
delete_message(uid)
rescue Exception => e
raise e
end
end
def append(folder,message,flags)
begin
@imap.append(folder,message,flags)
rescue Exception => e
raise e
end
end
end
end

View file

@ -1,91 +0,0 @@
require 'net/imap'
module ImapMessageModule
class IMAPAddress
attr_accessor :name,:mailbox,:host
def initialize()
name = ""
mailbox = ""
host = ""
end
def self.from_address(addr)
a = IMAPAddress.new()
a.name = addr.name || ""
a.mailbox = addr.mailbox || ""
a.host = addr.host || ""
a
end
def to_db
name + "#" + mailbox + "#" + host
end
def self.parse(addr)
a = IMAPAddress.new()
f = addr.split("#")
a.name = f[0]
a.mailbox = f[1]
a.host = f[2]
a
end
def friendly
if name.empty?
mailbox + host
else
name
end
end
end
class IMAPMessage
@@fetch_attr = ['RFC822.HEADER', 'FLAGS', 'UID', 'RFC822.SIZE']
#@@fetch_attr = ['RFC822','FLAGS', 'UID', 'RFC822.SIZE']
# attr_accessor :envelope,:uid,:content_type,:size,:unseen,:from,:message_id,:to,:from,:subject,:date
#
# def initialize
# end
#
# def self.fromImap(message)
# m = IMAPMessage.new
# envelope = message.attr['ENVELOPE']
# m.envelope = envelope
# m.message_id = envelope.message_id
# m.date = envelope.date
# m.subject = envelope.subject
# m.uid = message.attr['UID']
# #content_type = m.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text'
# m.content_type = message.attr['BODYSTRUCTURE'].media_type.downcase
# m.size = message.attr['RFC822.SIZE']
# m.unseen = !(message.attr['FLAGS'].member? :Seen)
# m.from = IMAPAddress.from_address(envelope.from[0])
# m.to = IMAPAddress.from_address(envelope.to[0])
# m
# end
#
def self.fetch_attr
@@fetch_attr
end
#
# def from_to_db
# from.to_db
# end
#
# def to_to_db
# to.to_db
# end
end
end

View file

@ -1,25 +0,0 @@
require 'net/imap'
require 'imap_mailbox'
module ImapSessionModule
def open_imap_session
begin
@mailbox ||= ImapMailboxModule::IMAPMailbox.new(logger,$defaults["imap_debug"])
@mailbox.connect(@current_user.servers.primary_for_imap,@current_user.login, @current_user.get_cached_password(session))
rescue Exception => ex
redirect_to :controller => 'internal', :action => 'loginfailure'
end
end
def close_imap_session
return if @mailbox.nil? or not(@mailbox.connected)
@mailbox.disconnect
@mailbox = nil
end
def select_imap_folder
@mailbox.set_folder(@current_folder.full_name) if not @current_folder.nil?
end
end

View file

@ -1,114 +0,0 @@
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
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 Field
def charseted
begin
if value =~ /\=\?([\w\-]+)\?/
source_charset = $1
if source_charset.upcase == 'UTF-8'
return decoded
end
else
source_charset = $defaults["msg_unknown_charset"]
end
Iconv.iconv("UTF-8",source_charset,decoded).first
rescue
decoded
end
end
end
class Address
def charseted
begin
if value =~ /\=\?([\w\-]+)\?/
source_charset = $1
if source_charset.upcase == 'UTF-8'
return decoded
end
else
source_charset = $defaults["msg_unknown_charset"]
end
Iconv.iconv("UTF-8",source_charset,decoded).first
rescue
decoded
end
end
end
class Part
def filename_charseted
begin
if content_type =~ /\=\?([\w\-]+)\?/
source_charset = $1
if source_charset.upcase == 'UTF-8'
return filename
end
else
source_charset = $defaults["msg_unknown_charset"]
end
Iconv.iconv("UTF-8",source_charset,filename).first
rescue
filename
end
end
end
end

0
lib/tasks/.gitkeep Executable file → Normal file
View file

Some files were not shown because too many files have changed in this diff Show more