contacts done

from_scratch
Wojciech Todryk 2011-08-16 20:05:58 +02:00
parent 68b925ea5e
commit 217c7a2288
60 changed files with 1286 additions and 439 deletions

30
Gemfile
View File

@ -2,37 +2,7 @@ source 'http://rubygems.org'
gem 'rails', '3.0.7'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
#gem 'sqlite3-ruby',:require => 'sqlite3'
gem 'arel'
gem 'mysql2' , '0.2.7'
gem 'will_paginate', '~> 3.0.beta'
gem 'themes_for_rails'
gem "ezcrypto", "~> 0.7.2"
gem "mail"
#gem 'tmail'
# Use unicorn as the web server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
# gem 'ruby-debug'
# gem 'ruby-debug19', :require => 'ruby-debug'
# Bundle the extra gems:
# gem 'bj'
# gem 'nokogiri'
# gem 'sqlite3-ruby', :require => 'sqlite3'
# gem 'aws-s3', :require => 'aws/s3'
# Bundle gems for the local environment. Make sure to
# put test-only gems in this group so their generators
# and rake tasks are available in development mode:
# group :development, :test do
# gem 'webrat'
# end

View File

@ -72,9 +72,7 @@ PLATFORMS
ruby
DEPENDENCIES
arel
ezcrypto (~> 0.7.2)
mail
mysql2 (= 0.2.7)
rails (= 3.0.7)
themes_for_rails

View File

@ -8,7 +8,8 @@ class ApplicationController < ActionController::Base
#end
protect_from_forgery
before_filter :load_defaults,:set_locale,:current_user
before_filter :load_defaults,:current_user,:set_locale
before_filter :plugins_configuration
################################# protected section ###########################################
@ -30,7 +31,7 @@ class ApplicationController < ActionController::Base
if @current_user.nil?
I18n.locale = $defaults['locale'] || I18n.default_locale
else
I18n.locale = @current_user.prefs.locale || I18n.default_locale
I18n.locale = @current_user.prefs.locale.to_sym || I18n.default_locale
end
end
@ -52,15 +53,21 @@ class ApplicationController < ActionController::Base
def get_current_folders
@folders_shown = @current_user.folders.shown.order("name asc")
@current_folder = @current_user.folders.current(@selected_folder)
@current_folder = @current_user.folders.find_by_full_name(@selected_folder)
end
##################################### private section ##########################################
#private
private
def plugins_configuration
WillPaginate::ViewHelpers.pagination_options[:previous_label] = t(:previous_page)
WillPaginate::ViewHelpers.pagination_options[:next_label] = t(:next_page)
end
#def route_not_found
# render :text => 'What the fuck are you looking for ?', :status => :not_found
#end
end

View File

@ -2,12 +2,73 @@ class ContactsController < ApplicationController
before_filter :check_current_user,:selected_folder
before_filter :get_current_folders, :only => [:index]
before_filter :get_current_folders
before_filter :get_contacts, :only => [:index]
theme :theme_resolver
def index
flash[:notice] = 'Not implemented yet'
end
def ops
if !params["cids"]
flash[:warning] = t(:no_selected,:scope=>:contact)
else
if params["delete"]
params["cids"].each do |id|
@current_user.contacts.find_by_id(id).destroy
end
elsif params["compose"]
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
####################################### private section ##################################
private
def get_contacts
@contacts = Contact.getPageForUser(@current_user,params[:page],params[:sort_field],params[:sort_dir])
end
end

View File

@ -18,35 +18,35 @@ class FoldersController < ApplicationController
def create
if params["folder"].empty?
flash[:warning] = t(:folder_to_create_empty)
flash[:warning] = t(:to_create_empty,:scope=>:folder)
render "index"
else
begin
if params["parent_folder"].empty?
@mailbox.create_folder(params[:folder])
else
parent_folder = Folder.find(params["parent_folder"])
parent_folder = @current_user.folders.find(params["parent_folder"])
if parent_folder.depth >= $defaults["mailbox_max_parent_folder_depth"].to_i
raise Exception, t(:folder_max_depth)
raise Exception, t(:max_depth,:scope=>:folder)
end
@mailbox.create_folder(parent_folder.full_name + parent_folder.delim + params[:folder])
end
rescue Exception => e
flash[:error] = t(:can_not_create_folder) + ' (' + e.to_s + ')'
flash[:error] = t(:can_not_create,:scope=>:folder) + ' (' + e.to_s + ')'
render 'index'
return
end
redirect_to :action => 'refresh', :flash => t(:folder_was_created), :type => :notice
redirect_to :action => 'refresh', :flash => t(:was_created,:scope=>:folder), :type => :notice
end
end
# FIXME if you delete folder you should change current folder because if you go to messages/index you got nil
def delete
if params["folder"].empty?
flash[:warning] = t(:folder_to_delete_empty)
flash[:warning] = t(:to_delete_empty,:scope=>:folder)
render "index"
else
begin
folder = Folder.find(params["folder"])
folder = @current_user.folders.find(params["folder"])
system_folders = Array.new
system_folders << $defaults["mailbox_inbox"]
system_folders << $defaults["mailbox_trash"]
@ -55,13 +55,13 @@ class FoldersController < ApplicationController
if system_folders.include?(folder.full_name.downcase)
raise Exception, t(:system_folder)
end
@mailbox.delete_folder(Folder.find(params["folder"]).full_name)
@mailbox.delete_folder(folder.full_name)
rescue Exception => e
flash[:error] = t(:can_not_delete_folder) + ' (' + e.to_s + ')'
flash[:error] = t(:can_not_delete,:scope=>:folder) + ' (' + e.to_s + ')'
render 'index'
return
end
redirect_to :action => 'refresh', :flash => t(:folder_was_deleted), :type => :notice
redirect_to :action => 'refresh', :flash => t(:was_deleted,:scope=>:folder), :type => :notice
end
end
@ -82,9 +82,6 @@ class FoldersController < ApplicationController
def refresh
Folder.refresh(@mailbox,@current_user)
flash.keep
#if params[:flash]
# flash[params[:type]] = params[:flash]
#end
redirect_to :action => 'index'
end

View File

@ -23,7 +23,7 @@ class InternalController < ApplicationController
def loginfailure
reset_session
flash[:error] = t(:login_failure)
flash[:error] = t(:login_failure,:scope=>:user)
@current_user = nil
redirect_to :controller=>'user', :action => 'login'
end

View File

@ -11,75 +11,38 @@ class MessagesController < ApplicationController
before_filter :check_current_user ,:selected_folder
before_filter :get_current_folders, :only => [:index,:compose,:show]
before_filter :get_current_folders
before_filter :open_imap_session, :only => :refresh
after_filter :close_imap_session, :only => :refresh
before_filter :open_imap_session, :select_imap_folder
after_filter :close_imap_session
theme :theme_resolver
@@fetch_attr = ['ENVELOPE','BODYSTRUCTURE', 'FLAGS', 'UID', 'RFC822.SIZE']
def index
open_imap_session
####################
@messages = []
folder_status = @mailbox.status(@current_folder.full_name)
@current_folder.update_attributes(:messages => folder_status['MESSAGES'], :unseen => folder_status['UNSEEN'])
folder_status = @mailbox.status
@current_folder.update_attributes(:total => folder_status['MESSAGES'], :unseen => folder_status['UNSEEN'])
if folder_status['MESSAGES'].zero?
return
folder_status['MESSAGES'].zero? ? uids_remote = [] : uids_remote = @mailbox.fetch_uids
uids_local = @current_user.messages.where(:folder_id => @current_folder).collect(&:uid)
(uids_local-uids_remote).each do |uid|
@current_folder.messages.find_by_uid(uid).destroy
end
messages = @mailbox.fetch(@current_folder.full_name,1..-1, "UID")
logger.custom('mess',messages)
uids_to_be_fetched = []
messages.each do |m|
uids_to_be_fetched << m.attr['UID']
end
messages = []
@current_user.messages.destroy_all
uids_to_be_fetched.each_slice($defaults["imap_fetch_slice"].to_i) do |slice|
logger.custom('slice',slice.join(","))
messages = @mailbox.uid_fetch(@current_folder.full_name,slice, @@fetch_attr)
(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|
envelope = m.attr['ENVELOPE']
uid = m.attr['UID']
#content_type = m.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text'
content_type = m.attr['BODYSTRUCTURE'].media_type.downcase
size = m.attr['RFC822.SIZE']
unread = !(m.attr['FLAGS'].member? :Seen)
from = ImapMessageModule::IMAPAddress.from_address(envelope.from[0])
logger.custom('from',from.to_db)
logger.custom('enevelope_from',envelope)
logger.custom('body',m.attr['BODYSTRUCTURE'])
message = @current_user.messages.create(:folder_id => @current_folder.id,
:msg_id => envelope.message_id,
:uid => uid,
:from => from.to_db,
:to => envelope.to,
:subject => envelope.subject,
:content_type => content_type,
:date => envelope.date,
:unread => unread,
:size => size)
mess = ImapMessageModule::IMAPMessage.fromImap(m)
Message.createForUser(@current_user,@current_folder,mess)
end
end
@messages = Message.getPageForUser(@current_user,params['page'])
@messages = Message.getPageForUser(@current_user,@current_folder,params[:page],params[:sort_field],params[:sort_dir])
###############
close_imap_session
end
def folder
@ -92,20 +55,102 @@ class MessagesController < ApplicationController
end
def refresh
@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 :action => 'index'
end
def emptybin
begin
trash_folder = @current_user.folders.find_by_full_name($defaults["mailbox_trash"])
@mailbox.set_folder(trash_folder.full_name)
trash_folder.messages.each do |m|
logger.custom('id',m.inspect)
@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)} (#{e.to_s})"
end
redirect_to :action => 'index'
end
def ops
begin
if !params["uids"]
flash[:warning] = t(:no_selected,:scope=>:message)
elsif params["delete"]
params["uids"].each do |uid|
@mailbox.delete_message(uid)
@current_user.messages.find_by_uid(uid).destroy
end
@current_folder.update_stats
elsif params["set_unread"]
params["uids"].each do |uid|
@mailbox.set_unread(uid)
@current_user.messages.find_by_uid(uid).update_attributes(:unseen => 1)
end
elsif params["set_read"]
params["uids"].each do |uid|
@mailbox.set_read(uid)
@current_user.messages.find_by_uid(uid).update_attributes(:unseen => 0)
end
elsif params["trash"]
dest_folder = @current_user.folders.find_by_full_name($defaults["mailbox_trash"])
params["uids"].each do |uid|
@mailbox.move_message(uid,dest_folder.full_name)
message = @current_folder.messages.find_by_uid(uid)
message.change_folder(dest_folder)
end
@mailbox.expunge
dest_folder.update_stats
@current_folder.update_stats
elsif params["copy"]
if params["dest_folder"].empty?
flash[:warning] = t(:no_selected,:scope=>:folder)
else
dest_folder = find(params["dest_folder"])
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
elsif params["move"]
if params["dest_folder"].empty?
flash[:warning] = t(:no_selected,:scope=>:folder)
else
dest_folder = @current_user.folders.find(params["dest_folder"])
params["uids"].each do |uid|
@mailbox.move_message(uid,dest_folder.full_name)
message = @current_folder.messages.find_by_uid(uid)
message.change_folder(dest_folder)
end
@mailbox.expunge
dest_folder.update_stats
@current_folder.update_stats
end
end
rescue Exception => e
flash[:error] = "#{t(:imap_error)} (#{e.to_s})"
end
redirect_to :action => 'index'
end
def show
@message = Message.find(params[:id])
flash[:notice] = 'Not impelented yet'
open_imap_session
@body = @mailbox.fetch_body(@current_folder.full_name,@message.uid)
logger.custom('body',@body.inspect)
close_imap_session
@message = @current_user.messages.find(params[:id])
@message.update_attributes(:unseen => false)
flash[:notice] = 'Not implemented yet'
@body = @mailbox.fetch_body(@message.uid)
end
end

View File

@ -2,14 +2,25 @@ class PrefsController < ApplicationController
before_filter :check_current_user,:selected_folder
before_filter :get_current_folders, :only => [:index,:compose]
before_filter :get_current_folders
before_filter :get_prefs
theme :theme_resolver
def index
flash[:notice] = 'Not implemented yet'
@prefs = @current_user.prefs
end
def update
if params[:prefs]
@prefs.update_attributes(params[:prefs])
end
redirect_to :action => 'index'
end
############################################ private section #########################################
def get_prefs
@prefs = @current_user.prefs
end
end

View File

@ -8,7 +8,7 @@ class UserController < ApplicationController
def logout
reset_session
flash[:notice] = t(:user_logged_out)
flash[:notice] = t(:logged_out,:scope=>:user)
redirect_to :action => "login"
end
@ -44,19 +44,19 @@ class UserController < ApplicationController
def create
@user = User.new
@user.email = params["user_email"]
@user.first_name = params["user_first_name"]
@user.last_name = params["user_last_name"]
@user.email = params[:user][:email]
@user.first_name = params[:user][:first_name]
@user.last_name = params[:user][:last_name]
@server = Server.new
@server.name = params["server_name"]
@server.name = params[:server][:name]
if @user.valid? and @server.valid?
@user.save
@server.user_id = @user.id
@server.save
Prefs.create_default(@user.id)
flash[:notice] = t(:setup_done)
flash[:notice] = t(:setup_done,:scope=>:user)
redirect_to :action => 'login'
else
render "setup"

View File

@ -1,7 +1,7 @@
module ApplicationHelper
def form_field(object,field,flabel,example,val)
model_name = eval(object.class.model_name)
html = ""
html << "<div class=\"group\">"
if object.errors[field.to_sym]
@ -10,7 +10,7 @@ def form_field(object,field,flabel,example,val)
end
html << "<label class=\"label\">"
if flabel.nil?
html << t(field.to_sym)
html << model_name.human_attribute_name(field)
else
html << t(flabel.to_sym)
end
@ -21,9 +21,11 @@ def form_field(object,field,flabel,example,val)
html << "</span>"
html << "</div>"
end
html << "<input name=\""
html << "<input id=\""
html << object.class.name.downcase+"_"+field
html << "\" type=\"text\" class=\"text_field\" value=\""
html << "\""
html << " name=\"#{object.class.name.downcase}[#{field}]\""
html << " size=50 type=\"text\" class=\"text_field\" value=\""
value = object.instance_eval(field) || val || ""
html << value
html << "\"/>"
@ -43,7 +45,7 @@ def form_button(text,image)
html << "<img src=\""
html << current_theme_image_path(image)
html << "\" alt=\""
html << text
html << t(text.to_sym)
html << "\" />"
html << t(text.to_sym)
html << "</button></div>"
@ -66,7 +68,7 @@ end
def simple_input_field(name,label,value)
html = ""
html << "<div class=\"group\">"
html << "<div class=\"param_group\">"
html << "<label class=\"label\">#{label}</label>"
html << "<input name=\"#{name}\" class=\"text_field\" type=\"text\" value=\"#{value}\">"
html << "</div>"
@ -80,6 +82,15 @@ def select_field(name,object,label,blank)
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 form_simle_field(name,label,value)
# html = ""
# html << "<div class=\"group\">"
@ -89,23 +100,23 @@ end
#end
def nav_to_folders
link_to( t(:folders), :controller=>:folders, :action=>:index )
link_to( t(:folders,:scope=>:folder), :controller=>:folders, :action=>:index )
end
def nav_to_messages
link_to( t(:messages), :controller=>:messages, :action=>:index )
link_to( t(:messages,:scope=>:message), :controller=>:messages, :action=>:index )
end
def nav_to_compose
link_to( t(:compose), :controller=>:messages, :action=>:compose )
link_to( t(:compose,:scope=>:compose), :controller=>:messages, :action=>:compose )
end
def nav_to_contacts
link_to( t(:contacts), :controller=>:contacts, :action=>:index )
link_to( t(:contacts,:scope=>:contact), contacts_path )
end
def nav_to_prefs
link_to( t(:preferences), :controller=>:prefs, :action=>:index )
link_to( t(:prefs,:scope=>:prefs), prefs_path )
end
def main_navigation(active)

View File

@ -1,2 +1,17 @@
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,24 +1,40 @@
module FolderHelper
def folder_link(folder)
folder.parent.empty? ? name = folder.name : name = folder.parent.gsub(/\./,'#') + "#" + folder.name
s = link_to folder.name.capitalize, :controller => 'messages', :action => 'folder', :id => name
if !folder.unseen.zero?
s += ' (' + folder.unseen.to_s + ')'
s = link_to folder.name.capitalize, messages_folder_path(:id => name)
if folder.full_name.downcase == $defaults["mailbox_trash"].downcase
if not folder.total.zero?
s <<' ('
s << link_to(t(:emptybin,:scope=>:folder),messages_emptybin_path)
s << ')'
end
else
if !folder.unseen.zero?
s += ' (' + folder.unseen.to_s + ')'
end
end
s
end
def pretty_folder_name(folder)
folder.nil? ? t(:no_folder_selected) : folder.name.capitalize
folder.nil? ? t(:no_selected,:scope=>:folder) : folder.name.capitalize
end
def select_for_folders(name,id,object,label,blank)
html = ""
html << "<div class=\"group\">"
html << "<label class=\"label\">#{label}</label>"
html << select(name, id, object.all.collect {|p| [ p.parent.empty? ? p.name : p.parent+p.delim+p.name, p.id ] }, { :include_blank => (blank == true ? true : false)})
html << simple_select_for_folders(name,id,object,blank)
html << "</div>"
end
def simple_select_for_folders(name,id,object,blank)
html = ""
html << select(name, id, object.all.collect {|p| [ p.parent.empty? ? p.name : p.parent+p.delim+p.name, p.id ] }, { :include_blank => (blank == true ? true : false)})
html
end
end

View File

@ -19,9 +19,12 @@ module MessagesHelper
end
def subject_formatter(message)
length = $defaults["msg_subject_length"].to_i
logger.custom('l',length)
message.subject.length >= length ? s = message.subject[0,length]+"..." : s = message.subject
if 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.id
end
@ -29,5 +32,26 @@ module MessagesHelper
message.content_type == 'text' ? "" : "A"
end
def headers_links
if @current_folder.hasFullName?($defaults["mailbox_sent"])
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
end

35
app/models/contact.rb Executable file
View File

@ -0,0 +1,35 @@
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 => 50
validate_on_create :check_unique_nick
belongs_to :user
def self.getPageForUser(user,page,sort_field,sort_dir)
order = 'last_name asc'
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
end

View File

@ -3,6 +3,7 @@ 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
def full_name
if parent.empty?
@ -22,12 +23,23 @@ class Folder < ActiveRecord::Base
(fields[1].downcase == name.downcase) && (fields[0].downcase == parent.downcase)
end
def update_stats
unseen = messages.where(:unseen => true).count
total = messages.count
update_attributes(:unseen => unseen, :total => total)
end
def hasFullName?(folder_name)
full_name.downcase == folder_name.downcase
end
############################################## private section #####################################
private
def check_fill_params
self.messages.nil? ? self.messages = 0 : self.messages
self.total.nil? ? self.total = 0 : self.total
self.unseen.nil? ? self.unseen = 0 : self.unseen
self.msgs_updated_at.nil? ? self.msgs_updated_at = (DateTime.now-1) : self.msgs_updated_at
end
def self.createBulk(user,imapFolders)
@ -43,14 +55,22 @@ class Folder < ActiveRecord::Base
parent = ""
end
user.folders.create(:name=>name,:parent=>parent,:haschildren=>has_children,:delim=>data.delim,:messages => data.messages,:unseen => data.unseen)
user.folders.create(
:msgs_updated_at => DateTime.now-1,
:name => name,
:parent => parent,
:haschildren => has_children,
:delim => data.delim,
:total => data.messages,
:unseen => data.unseen)
end
end
def self.current(data)
folder = data.split("#")
nam = folder.delete_at(folder.size - 1)
folder.size.zero? == true ? par = "" : par = folder.join(".")
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
@ -64,4 +84,6 @@ class Folder < ActiveRecord::Base
Folder.createBulk(user,folders)
end
end

View File

@ -1,13 +1,37 @@
class Message < ActiveRecord::Base
belongs_to :user
belongs_to :folder
#cattr_reader :per_page
#@@per_page = $defaults["msgs_per_page"]
def self.getPageForUser(user,folder,page,sort_field,sort_dir)
def self.getPageForUser(user,page,order = "date desc")
#Message.paginate :page => page , :per_page => user.prefs.msgs_per_page.to_i, :conditions=> ['user_id = ?', user.id],:order => order
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 => 50, :conditions=> ['user_id = ?', user.id],:order => order
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,mess)
create(
:user_id => user.id,
:folder_id => folder.id,
:msg_id => mess.message_id,
:uid => mess.uid,
:from_addr => mess.from_to_db,
:to_addr => mess.to,
:subject => mess.subject,
:content_type => mess.content_type,
:date => mess.date,
:unseen => mess.unseen,
:size => mess.size)
end
def change_folder(folder)
update_attributes(:folder_id => folder.id)
end
end

View File

@ -15,3 +15,5 @@ class Prefs < ActiveRecord::Base
)
end
end
# TODO move refresh to prefs and make refresh page with messages

View File

@ -8,6 +8,7 @@ class User < ActiveRecord::Base
has_one :prefs, :dependent => :destroy
has_many :folders, :dependent => :destroy
has_many :messages, :dependent => :destroy
has_many :contacts, :dependent => :destroy
def set_cached_password(session,password)
if $defaults['session_encryption']

View File

@ -1,12 +1,23 @@
theme: olive
locale: en
locale: pl
themes: [olive]
locales: [en, pl]
msgs_per_page_table: [15, 20, 25, 30, 35, 40, 45, 50]
msg_send_type: [html, text]
contacts_table_fields: [nick, first_name, last_name, email, info]
contacts_per_page: 25
msgs_per_page: 20
msgs_refresh_time: 300
msgs_send_type: html
msgs_update_time: 300
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: 45
msg_search_fields: [subject, from, to]
imap_debug: true
imap_use_ssl: 'false'
@ -20,7 +31,7 @@ session_password: asDD3s2@sAdc983#
mailbox_max_parent_folder_depth: 3
mailbox_inbox: INBOX
mailbox_trash: Trash
mailbox_sent: Sent
mailbox_drafts: Drafts
mailbox_trash: INBOX.Trash
mailbox_sent: INBOX.sent
mailbox_drafts: INBOX.drafts

View File

@ -1,102 +1,63 @@
en:
mailr: Mailr
email: Email
password: Password
log_in: Log In
wrong_email_or_password: Wrong email or password specified.
mailbox: Mailbox
folders: Folders
folder: Folder
empty: Empty
logout: Logout
compose: Compose
preferences: Preferences
filters: Filters
contacts: Contacts
search: Search
search_txt: Search in message field
refresh: Refresh
operations: Operations
operations_txt: Operations on marked messages
delete: delete
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
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
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
refresh: Refresh
create: 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
delete: Delete
show_hide: Show/Hide
page_not_found: Page not found
bytes: Bytes
kbytes: Kb
mbytes: MB
previous_page: Previous page
next_page: Next page
mailr: Mailr
save: Save

160
config/locales/en.yml.old Executable file
View File

@ -0,0 +1,160 @@
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,77 +1,122 @@
pl:
mailr: Mailr
email: E-mail
password: Hasło
log_in: Zaloguj
wrong_email_or_password: Podano nieprawidłowy login lub hasło
mailbox: Poczta
folders: Foldery
folder: Folder
empty: Opróżnij
logout: Wyloguj
compose: Nowa wiadomość
preferences: Ustawienia
filters: Filtry
contacts: Kontakty
search: Szukaj
search_txt: ciąg znaków
refresh: Odśwież
operations: Akcje
operations_txt: Akcje na zaznaczonych wiadomościach
delete: Usuń
copy: Skopiuj
move: Przenieś
mark_read: Zaznacz jako przeczytane
mark_unread: Zaznacz jako nieprzeczytane
destination_txt: Miejsce docelowe dla akcji
for: ciągu znaków
to: Do
subject: Temat
date: Data
size: Rozmiar
from: Od
show_all: Pokaż wszystkie
pages: Strony
first: Pierwsza
prev: Poprzednia
next: Następna
last: Ostatnia
back_to_list: Powrót do listy
back_to_message: Powrót do wiadomości
reply: Odpowiedz
forward: Przekaż
delete: Usuń
view_source: Pokaż źródło
add_filter: Dodaj filtr
cc: Cc
bcc: Bcc
send: Wyślij
choose_address: Wybierz adres z kontaktów
compose_txt: Utwórz nową wiadomość
attachment: Załącznik
add: Dodaj
first_name: Imię
last_name: Nazwisko
send_type: Format wiadomości wychodzącej
messages_per_page: Ilość wiadomości na stronie
check_external_mail: Check external mail?
check_external_mail_txt: Note that by selecting this option webmail system will try to log you using your original email on a local server.
save: Zapisz
cancel: Anuluj
add_one_contact: Dodaj jeden kontakt
add_multiple: Dodaj wiele
name: Nazwa
add_folder: Dodaj folder
total_messages: Total messages
unseen: Unseen
add_edit_folder: Zarządzaj
user_logged_out: Użytkownik został wylogowany
please_login: Logowanie
add_to_contacts: Dodaj do kontaktów
want_to_empty_trash_message: Czy chcesz opróznic kosz?
site_link: https://github.com/lmanolov/mailr
marked_messages: zaznaczone wiadomości
to_folder: do folderu
message_field: Pole wiadomości
no_messages_found: Nie znaleziono żadnych wiadomości
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"
models:
contact: Kontakt
attributes:
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
message:
from_addr: Od
to_addr: Do
subject: Temat
size: Rozmiar
date: Data
user:
email: E-mail
password: Hasło
first_name: Imię
last_name: Nazwisko
server:
name: Nazwa serwera
contact:
compose_to_selected: Napisz do wybranych
delete_selected: Usuń wybrane
modifying: Modyfikacja kontaktu
creating_new: Tworzenie nowego kontaktu
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?
prefs:
prefs: Ustawienia
folder:
folders: Foldery
no_shown: Żadnych pokazanych folderów
parent: Folder nadrzędny
to_create: Folder do utworzenia
to_delete: Folder do usunięcia
shown: Foldery pokazane
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
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
compose:
compose: Nowa wiadomość
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
must_be_unique: musi być unikalny
some_add_info: jakieś dodatkowe informacje
example: przykład
refresh: Odśwież
create: Utwórz
delete: Usuń
show_hide: Pokaż/Ukryj
mailr: Mailr
save: Zapisz
imap_error: Błąd protokołu IMAP
unspecified_error: Nieoczekiwany błąd
page_not_found: Nie znaleziono żadanej strony
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
send: Wyślij

View File

@ -1,9 +1,13 @@
Mailr::Application.routes.draw do
get "prefs/index"
match "prefs/index" => "prefs#index", :as => :prefs
post "prefs/update"
get "contacts/index"
resources :contacts
post "contacts/ops"
#resources :folders
get "folders/index"
post "folders/create"
post "folders/delete"
@ -18,11 +22,12 @@ Mailr::Application.routes.draw do
root :to => "messages#index"
get "messages/index"
get "messages/refresh"
match 'messages/folder/:id' => 'messages#folder'
match 'messages/folder/:id' => 'messages#folder', :as => :messages_folder
post "messages/ops"
get "messages/compose"
get "messages/refresh"
match "messages/show/:id" => 'messages#show'
get "messages/emptybin"
get "user/logout"
post "user/authenticate"

View File

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

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

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

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

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

@ -10,19 +10,29 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110731185416) do
ActiveRecord::Schema.define(:version => 20110816120258) 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 "folders", :force => true do |t|
t.string "name"
t.string "delim"
t.boolean "haschildren"
t.integer "messages"
t.integer "total"
t.integer "unseen"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "parent"
t.datetime "msgs_updated_at"
t.boolean "shown"
t.string "alter_name"
end
@ -31,13 +41,13 @@ ActiveRecord::Schema.define(:version => 20110731185416) do
t.integer "folder_id"
t.integer "user_id"
t.string "msg_id"
t.string "from"
t.string "to"
t.string "from_addr"
t.string "to_addr"
t.string "subject"
t.string "content_type"
t.integer "uid"
t.integer "size"
t.boolean "unread"
t.boolean "unseen"
t.datetime "date"
t.datetime "created_at"
t.datetime "updated_at"

View File

@ -9,11 +9,11 @@ end
class IMAPMailbox
attr_reader :connected
attr_accessor :selected_folder
attr_accessor :sfolder
attr_accessor :logger
def initialize(logger)
@selected_folder = ''
@sfolder = ''
@folders = {}
@connected = false
@logger = logger
@ -80,6 +80,19 @@ class IMAPMailbox
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))
@ -88,18 +101,16 @@ class IMAPMailbox
end
end
def fetch(folder_name,range,attribs)
def fetch(range,attribs)
begin
set_folder(folder_name)
@imap.fetch(range,attribs)
rescue Exception => e
raise e
end
end
def uid_fetch(folder_name,range,attribs)
def uid_fetch(range,attribs)
begin
set_folder(folder_name)
@imap.uid_fetch(range,attribs)
rescue Exception => e
raise e
@ -107,18 +118,79 @@ class IMAPMailbox
end
def set_folder(folder_name)
if folder_name.downcase != @selected_folder.downcase
@imap.select(folder_name)
@selected_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(folder_name)
@imap.status(folder_name, ["MESSAGES", "RECENT", "UNSEEN"])
def status
begin
@imap.status(@sfolder, ["MESSAGES", "RECENT", "UNSEEN"])
rescue Exception => e
raise e
end
end
def fetch_body(folder_name,uid)
uid_fetch(folder_name,uid,"BODY[]").first.attr["BODY[]"]
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
end

View File

@ -43,5 +43,42 @@ class IMAPAddress
end
class IMAPMessage
@@fetch_attr = ['ENVELOPE','BODYSTRUCTURE', '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.to = envelope.to
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
end
def self.fetch_attr
@@fetch_attr
end
def from_to_db
from.to_db
end
end
end

View File

@ -18,4 +18,8 @@ def close_imap_session
@mailbox = nil
end
def select_imap_folder
@mailbox.set_folder(@current_folder.full_name) if not @current_folder.nil?
end
end

15
test/fixtures/contacts.yml vendored Executable file
View File

@ -0,0 +1,15 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
one:
nick: MyString
mail: MyString
fname: MyString
lname: MyString
info: MyString
two:
nick: MyString
mail: MyString
fname: MyString
lname: MyString
info: MyString

8
test/unit/contact_test.rb Executable file
View File

@ -0,0 +1,8 @@
require 'test_helper'
class ContactTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end

View File

@ -0,0 +1,16 @@
function toggleCheckBoxes(formName){
// toggle Check Boxes using Prototype Library
var form=$(formName);
var i=form.getElements('checkbox');
i.each(function(item)
{
item.checked = !item.checked;
}
);
// set our toggle box
$('togglechkbox').checked = !$('togglechkbox').checked;
}

View File

@ -110,7 +110,7 @@ body {
}
#main .block .content .inner {
padding: 0 15px 15px;
padding: 5px;
}
#main .main p.first {
@ -243,7 +243,7 @@ input.checkbox {
}
.form div.right {
width: 75%;
width: 70%;
float: right;
}

View File

@ -25,6 +25,9 @@
}
a:link, a:visited, a:hover, a:active, h1, h2, h3 { color: #A3AB74; }
#sidebar ul li.selected a { color: #5E634E; }
a { -moz-outline: none; }
body {
@ -365,6 +368,79 @@ input,select {
color: grey;
}
tr.unread td {
tr.unseen td {
font-weight:bold;
}
div.ops {
border: 1px solid #DACF77;
padding: 5px;
margin: 3px 0;
}
div.actions-bar div.header_info {
float: left;
color: #5E634E;
font-size: 22px;
margin: 0 10px;
font-weight: normal;
}
div.actions-bar div.header_info .other_info {
font-size: 12px;
}
th a.header {
color: white;
}
ul.navigation {
color: #A3AB74;
}
ul.folders {
font-size: 14px;
}
li.selected {
color: #5E634E;
font-weight: bold;
}
div.param_group {
margin: 5px 0;
font-size: 14px;
padding: 3px 0;
}
div.param_group label.label {
margin-right: 5px;
}
div.params {
margin-bottom: 15px;
}
div.params div.group {
margin-bottom:5px;
}
div.params div.group div.fieldWithErrors label.label {
font-weight: bold;
font-size: 14px;
}
div.params input.text_field, div.params textarea.text_area {
width: 100%;
border:1px solid #CFCFCF;
}
div.params div.group .description {
font-style: italic;
color: #8C8C8C;
font-size: .9em;
}
div.params div.group .fieldWithErrors .error {
color: red;
}

View File

@ -0,0 +1,9 @@
<div class="params">
<%= raw form_field(@contact,"nick",nil,"joe"+', '+t(:must_be_unique),@contact.nick) %>
<%= raw form_field(@contact,"first_name",nil,"Joe",@contact.first_name) %>
<%= raw form_field(@contact,"last_name",nil,"Doe",@contact.last_name) %>
<%= raw form_field(@contact,"email",nil,"joe.doe@domain.com",@contact.email) %>
<%= raw form_field(@contact,"info",nil,t(:some_add_info),@contact.info) %>
</div>
<%= raw form_button('save','tick.png') %>

View File

@ -0,0 +1,31 @@
<div class="inner">
<div class="actions-bar wat-cf">
<span class="other_info"> <%= t(:total_entries,:scope=>:contact) %>: <%= @contacts.total_entries %> / <%= link_to t(:create_new,:scope=>:contact), new_contact_path %></span>
</div>
<%= will_paginate @contacts %>
</div>
<table class="table">
<tbody>
<tr>
<th class="first"><input id="togglechkbox" class="checkbox toggle" type="checkbox" name="allbox" onclick=toggleCheckBoxes(this.form); /></th>
<%= raw contacts_table_header %>
<th class="last"></th>
</tr>
<% trclass = :even %>
<% @contacts.each do |c| %>
<tr class="<%= trclass.to_s %>">
<%= render :partial => 'contacts/row', :object => c %>
</tr>
<% trclass == :even ? trclass = :odd : trclass = :even %>
<% end %>
</tbody>
</table>
<div class="actions-bar wat-cf">
<%= will_paginate @contacts %>
</div>
</div>

View File

@ -0,0 +1,6 @@
<div id="ops" class="ops">
<p>
<%= submit_tag(t(:compose_to_selected,:scope => :contact), :name=> 'compose')%>
<%= submit_tag(t(:delete_selected,:scope => :contact), :name=>'delete')%>
</p>
</div>

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,7 @@
<td><%= check_box_tag "cids[]", row.id %></td>
<td nowrap="nowrap"><%= link_to row.nick,edit_contact_path(row) %></td>
<td nowrap="nowrap"><%= row.first_name %></td>
<td nowrap="nowrap"><%= row.last_name %></td>
<td nowrap="nowrap"><%= link_to row.email, {:controller => 'messages',:action => 'compose' , :cids => row.id.to_a} %></td>
<td colspan="2" nowrap="nowrap"><%= row.info %></td>

View File

@ -0,0 +1,30 @@
<% content_for :sidebar do %>
<%= render :partial => 'folders/list' %>
<% end %>
<% content_for :title do %>
- <%= t(:contacts,:scope=>:contact) %>
<% end %>
<div class="block" id="block-tables">
<div class="secondary-navigation">
<%= raw main_navigation(:contacts) %>
</div>
<div class="content">
<div class="inner">
<div class="actions-bar wat-cf">
<div class="header_info"><%= t(:modifying,:scope=>:contact) %></div>
</div>
<%= form_for(@contact) do |f| %>
<div class="columns wat-cf">
<div class="column left">
<%= render :partial => 'left' %>
</div>
<div class="column right">
<%= render :partial => 'right' %>
</div>
</div>
<% end %>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@
<% end %>
<% content_for :title do %>
- <%= t(:contacts) %>
- <%= t(:contacts,:scope=>:contact) %>
<% end %>
<div class="block" id="block-tables">
@ -11,8 +11,19 @@
<%= raw main_navigation(:contacts) %>
</div>
<div class="content">
<%= form_tag({:controller=>'messages', :action=>'ops'})%>
<%= form_tag(contacts_ops_path,{:name=>'contacts'})%>
<% if @contacts.size.zero? %>
<div class="actions-bar wat-cf">
<div class="header_info"><%= t(:no_entries,:scope=>:contact) %>
<%= content_tag(:span, link_to(raw('('+t(:create_new,:scope=>:contact)+')'),new_contact_path),:class=>"other_info") %>
</div>
<% else %>
<%= render :partial => 'ops' %>
<%= render :partial => 'list' %>
<% end %>
</form>
</div>
</div>

View File

@ -0,0 +1,30 @@
<% content_for :sidebar do %>
<%= render :partial => 'folders/list' %>
<% end %>
<% content_for :title do %>
- <%= t(:contacts,:scope=>:contact) %>
<% end %>
<div class="block" id="block-tables">
<div class="secondary-navigation">
<%= raw main_navigation(:contacts) %>
</div>
<div class="content">
<div class="inner">
<div class="actions-bar wat-cf">
<div class="header_info"><%= t(:creating_new,:scope=>:contact) %> </div>
</div>
<%= form_for(@contact) do |f| %>
<div class="columns wat-cf">
<div class="column left">
<%= render :partial => 'left' %>
</div>
<div class="column right">
<%= render :partial => 'right' %>
</div>
</div>
<% end %>
</div>
</div>
</div>

View File

@ -1,13 +1,13 @@
<div class="block">
<h3><%=t (:folders) %> <%= link_to t(:refresh), {:controller => 'messages', :action => 'refresh'}, :class=>'minor' %></h3>
<h3><%=t(:folders,:scope=>:folder) %> <%= link_to t(:refresh), messages_refresh_path, :class=>'minor' %></h3>
<div class="content">
<% if @folders_shown.size.zero? %>
<p><%= t(:no_folders_shown) %></p>
<p><%= t(:no_shown,:scope=>:folder) %></p>
<% else %>
<ul class="navigation">
<ul class="navigation folders">
<% @folders_shown.each do |folder| -%>
<% if folder == @current_folder %>
<li><b><%= raw folder_link(folder) %></b></li>
<li class="selected"><%= raw folder_link(folder) %></li>
<% else %>
<li><%= raw folder_link(folder) %></li>
<% end %>
@ -15,6 +15,6 @@
</ul>
<% end %>
<br/>
<%= raw form_button_value(t(:logout),'tick.png',url_for(:controller => :user, :action => :logout)) %>
<%= raw form_button_value('logout','tick.png',user_logout_path) %>
</div>
</div>

View File

@ -3,7 +3,7 @@
<% end %>
<% content_for :title do %>
- <%= t(:folders) %>
- <%= t(:folders,:scope=>:folder) %>
<% end %>
<div class="block" id="block-tables">
@ -14,23 +14,23 @@
<div class="inner">
<div class="columns wat-cf">
<div class="column left">
<%= form_tag({:controller=>'folders',:action=>'create'},:class=>'form') %>
<%= raw select_for_folders("","parent_folder",@folders,t(:parent_folder),true) %>
<%= raw simple_input_field("folder",t(:folder_to_create),"") %>
<%= raw form_button(t(:create),'tick.png') %>
<%= form_tag(folders_create_path,:class=>'form') %>
<%= raw select_for_folders("","parent_folder",@folders,t(:parent,:scope=>:folder),true) %>
<%= raw simple_input_field("folder",t(:to_create,:scope=>:folder),"") %>
<%= raw form_button('create','tick.png') %>
</form>
<%= form_tag({:controller=>'folders',:action=>'delete'},:class=>'form') %>
<%= raw select_for_folders("","folder",@folders,t(:folder_to_delete),true) %>
<%= raw form_button(t(:delete),'cross.png') %>
<%= form_tag(folders_delete_path,:class=>'form') %>
<%= raw select_for_folders("","folder",@folders,t(:to_delete,:scope=>:folder),true) %>
<%= raw form_button('delete','cross.png') %>
</form>
</div>
<div class="column right">
<%= form_tag({:controller=>'folders',:action=>'refresh'},:class=>'form') %>
<%= raw form_button(t(:refresh_folders),'tick.png') %>
<%= form_tag(folders_refresh_path,:class=>'form') %>
<%= raw form_button('refresh','tick.png') %>
</form>
<%= form_tag({:controller=>'folders',:action=>'show_hide'},:class=>'form') %>
<%= raw multi_select("", 'folders_to_show[]', @folders, @folders_shown,t(:folders_shown),:id,"",{:text => [:parent,:delim,:name]}) %>
<%= raw form_button(t(:show_hide),'tick.png') %>
<%= form_tag(folders_show_hide_path,:class=>'form') %>
<%= raw multi_select("", 'folders_to_show[]', @folders, @folders_shown,t(:shown,:scope=>:folder),:id,"",{:text => [:parent,:delim,:name]}) %>
<%= raw form_button('show_hide','tick.png') %>
</form>
</div>
</div>

View File

@ -13,6 +13,7 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<%=stylesheet_link_tag current_theme_stylesheet_path('style') %>
<%=javascript_include_tag :defaults %>
<%=javascript_include_tag current_theme_javascript_path('mailr') %>
</head>
<body>

View File

@ -1,35 +1,30 @@
<div class="inner">
<% WillPaginate::ViewHelpers.pagination_options[:previous_label] = t(:previous_page) %>
<% WillPaginate::ViewHelpers.pagination_options[:next_label] = t(:next_page) %>
<div class="actions-bar wat-cf">
<div class="header_info"><%= t(:current,:scope=>:folder) %>: <%= pretty_folder_name(@current_folder) %>
<span class="other_info">(<%= t(:total,:scope=>:message) %>: <%= @messages.total_entries %>)</span>
</div>
<%= will_paginate @messages %>
</div>
<form>
<table class="table">
<tbody>
<tr>
<th class="first"><input class="checkbox toggle" type="checkbox"></th>
<th class="first"><input id="togglechkbox" class="checkbox toggle" type="checkbox" name="allbox" onclick=toggleCheckBoxes(this.form); /></th>
<th><%= raw('&nbsp;') %></th>
<th><%= t(:from) %></th>
<th><%= t(:subject) %></th>
<th><%= t(:date) %></th>
<th><%= t(:size) %></th>
<%= raw headers_links %>
<th class="last"></th>
</tr>
<% trclass = :even %>
<% @messages.each do |m| %>
<% m.unread == true ? unread = "unread" : unread = "" %>
<tr class="<%= trclass.to_s %> <%= unread %>">
<% m.unseen == true ? unseen = "unseen" : unseen = "" %>
<tr class="<%= trclass.to_s %> <%= unseen %>">
<%= render :partial => 'messages/row', :object => m %>
</tr>
<% trclass == :even ? trclass = :odd : trclass = :even %>
<% end %>
</tbody>
</table>
</form>
<div class="actions-bar wat-cf">
<%= will_paginate @messages %>

View File

@ -1,15 +1,14 @@
<div id="ops">
<div id="ops" class="ops">
<p>
<%= submit_tag(t(:copy), :name=> 'op')%>
<%= submit_tag(t(:move), :name=>'op')%>
<%= t :marked_messages %>
<%= t :to_folder %>
<%= raw select_for_folders("","parent_folder",@folders_shown,t(:parent_folder),true) %>
</p>
<p>
<%= t :marked_messages %>
<%= submit_tag(t(:delete), :name=>'op')%>
<%= submit_tag(t(:mark_read), :name=>'op')%>
<%= submit_tag(t(:mark_unread), :name=>'op')%>
<%= submit_tag(t(:copy), :name=> 'copy')%>
<%= submit_tag(t(:move), :name=>'move')%>
<%= t(:checked,:scope=>:message) %>
<%= t(:to_folder,:scope=>:folder) %>
<%= raw simple_select_for_folders("","dest_folder",@folders_shown,true) %>
<br/>
<%= submit_tag(t(:delete), :name=>'trash')%>
<%= submit_tag(t(:set_read,:scope=>:message), :name=>'set_read')%>
<%= submit_tag(t(:set_unread,:scope=>:message), :name=>'set_unread')%>
<%= t(:checked,:scope=>:message) %>
</p>
</div>

View File

@ -1,6 +1,6 @@
<td><%= check_box_tag "uids[]", row.uid %></td>
<td><%= attachment_formatter(row) %></td>
<td nowrap="nowrap"><%= address_formatter(row.from) %></td>
<td nowrap="nowrap"><%= address_formatter(row.from_addr) %></td>
<td nowrap="nowrap"><%= subject_formatter(row) %></td>
<td nowrap="nowrap"><%= date_formatter(row.date) %></td>
</td><td nowrap="nowrap"><%= size_formatter(row.size) %></td><td><%= raw('&nbsp;') %>

View File

@ -1,7 +1,10 @@
<div id="search" class="ops">
<p>
<%= t :message_field %>
<select name="search_field">
<%= options_for_select(CDF::CONFIG[:mail_search_fields], @search_field)%>
</select> <label for="search_value"> <%= t :search_txt %>
</label> <input type="text" name="search_value" value="<%=@search_value%>" size='16' id='search_value'/> <%= submit_tag(t(:search), :name=>'op')%> <%= submit_tag(t(:show_all), :name=>'op')%>
<%= t(:search) %>
<%= t(:in_message_field) %>
<select name="search_field"><%= options_for_select($defaults["msg_search_fields"])%></select>
<%= t(:string) %>
<input type="text" name="search_value" value="" size='16' id='search_value'/>
<%= submit_tag(t(:search), :name=>'search')%>
</p>
</div>

View File

@ -3,15 +3,15 @@
<% end %>
<% content_for :title do %>
- <%= t(:compose) %>
- <%= t(:compose,:scope=>:compose) %>
<% end %>
<div class="block" id="block-tables">
<div class="secondary-navigation">
<%= raw main_navigation(:compose) %>
</div>
<div class="content">
<%= form_tag({:controller=>'messages', :action=>'ops'})%>
<div class="content"><%= params.inspect %>
<%= form_tag(messages_ops_path)%>
</form>
</div>

View File

@ -3,7 +3,7 @@
<% end %>
<% content_for :title do %>
- <%= t(:messages) %>
- <%= t(:messages,:scope=>:message) %>
<% end %>
<div class="block" id="block-tables">
@ -11,22 +11,18 @@
<%= raw main_navigation(:messages) %>
</div>
<div class="content">
<%= form_tag({:controller=>'messages', :action=>'ops'})%>
<% #render :partial => 'search' %>
<%= render :partial => 'ops' %>
<%= raw form_button(t(:ops),'tick.png') %>
<%= form_tag({:controller=>'messages', :action=>'ops'},{:name=>'messages'})%>
<% if @current_folder.nil? %>
<h2><%= t(:no_folder_selected) %></h2>
<% else %>
<h2><%= t(:current) %>: <%= pretty_folder_name(@current_folder) %></h2>
<h2><%= t(:no_selected,:scope=>:folder) %></h2>
<% end %>
<% if @messages.size.zero? %>
<%= t(:no_messages) %>
<div class="actions-bar wat-cf">
<div class="header_info"><%= t(:no_in,:scope=>:message) %></div>
</div>
<% else %>
<%= render :partial => 'ops' %>
<%= render :partial => 'list' %>
<% end %>

View File

@ -0,0 +1,8 @@
<div class="params">
<%= raw select_field_table(@prefs, "msgs_per_page", $defaults["msgs_per_page_table"],@prefs.msgs_per_page,false) %>
<%= raw select_field_table(@prefs, "theme", $defaults["themes"],@prefs.theme,false) %>
<%= raw select_field_table(@prefs, "locale", $defaults["locales"],@prefs.locale,false) %>
<%= raw select_field_table(@prefs, "msg_send_type", $defaults["msg_send_type"],@prefs.msg_send_type,false) %>
</div>
<%= raw form_button('save','tick.png') %>

View File

@ -0,0 +1 @@

View File

@ -3,7 +3,7 @@
<% end %>
<% content_for :title do %>
- <%= t(:preferences) %>
- <%= t(:prefs,:scope=>:prefs) %>
<% end %>
<div class="block" id="block-tables">
@ -11,10 +11,15 @@
<%= raw main_navigation(:prefs) %>
</div>
<div class="content">
<%= form_tag({:controller=>'messages', :action=>'ops'})%>
<%= @prefs.inspect %>
<div class="inner"> <%= form_tag(prefs_update_path,:name=>'prefs') %>
<div class="columns wat-cf">
<div class="column left">
<%= render :partial => 'prefs/left' %>
</div>
<div class="column right">
<%= render :partial => 'prefs/right' %>
</div>
</div></form>
</div>
</div>
</div>

View File

@ -1,12 +1,12 @@
<% content_for :title do %>
<%= t(:please_login) %>
<%= t(:login,:scope=>:user) %>
<% end %>
<div id="box">
<div class="block">
<div id="logo"><a href="/"><img src="<%= current_theme_image_path('logo_small.png')%>" alt="Mailr"/></a>
</div>
<h2><%= t(:please_login) %></h2>
<h2><%= t(:login,:scope=>:user) %></h2>
<div class="content login">
<div class="flash">
<% if flash[:error] %>
@ -18,7 +18,7 @@
<form action="<%=url_for(:controller => 'user', :action => 'authenticate')%>" method="post" class="form login">
<div class="group wat-cf">
<div class="left">
<label class="label right"><%= t(:email) %></label>
<label class="label right"><%= User.human_attribute_name('email') %></label>
</div>
<div class="right">
<%= text_field "user", "email" %>
@ -26,7 +26,7 @@
</div>
<div class="group wat-cf">
<div class="left">
<label class="label right"><%= t(:password) %></label>
<label class="label right"><%= User.human_attribute_name('password') %></label>
</div>
<div class="right">
<%= password_field "user", "password" %></td>

View File

@ -1,19 +1,19 @@
<% content_for :title do %>
<%= t(:setup_title) %>
<%= t(:setup,:scope=>:user) %>
<% end %>
<div id="box">
<div class="block">
<div id="logo"><a href="/"><img src="<%= current_theme_image_path('logo_small.png')%>" alt="Mailr"/></a>
<div id="logo"><a href="/"><img src="<%= current_theme_image_path('logo_small.png')%>" alt="<%= t(:mailr) %>"/></a>
</div>
<h2><%= t(:setup_title) %></h2>
<h2><%= t(:setup,:scope=>:user) %></h2>
<div class="content">
<form action="<%=url_for(:controller => 'user', :action => 'create')%>" method="post" class="form">
<%= raw form_field(@user,"email",nil,"joe.doe@domain.domain",params['email']) %>
<%= raw form_field(@user,"email",nil,"joe.doe@domain.domain",params[:user].nil? ? params[:email] : params[:user][:email]) %>
<%= raw form_field(@user,"first_name",nil,"Joe","") %>
<%= raw form_field(@user,"last_name",nil,"Doe","") %>
<%= raw form_field(@server,"name","server_name","domain.domain","") %>
<%= raw form_button(t(:send),"tick.png") %>
<%= raw form_field(@server,"name",nil,"server.domain","") %>
<%= raw form_button('send',"tick.png") %>
</form>
</div>
</div>

View File

@ -1,16 +1,16 @@
<% content_for :title do %>
<%= t(:unknown_user_title) %>
<%= t(:unknown_title,:scope=>:user) %>
<% end %>
<div id="box">
<div class="block" id="block-login">
<div id="logo"><a href="/"><img src="<%= current_theme_image_path('logo_small.png')%>" alt="Mailr"/></a>
</div>
<h2><%= t(:unknown_user_title) %></h2>
<h2><%= t(:unknown_title,:scope=>:user) %></h2>
<div class="content">
<div class="flash"><div class="message warning"><p><%= t(:unknown_user_flash) %></p></div></div>
<p><%= t(:unknown_user_login) %> -> <%= link_to "Login",:controller => "user",:action =>"login" %></p>
<p><%= t(:unknown_user_setup) %> -> <%= link_to "Setup",:controller => "user",:action => "setup",:email => params['email'] %></p>
<div class="flash"><div class="message warning"><p><%= t(:unknown_flash,:scope=>:user) %></p></div></div>
<p><%= t(:unknown_login,:scope=>:user) %> -> <%= link_to t(:login,:scope=>:user),user_login_path %></p>
<p><%= t(:unknown_setup,:scope=>:user) %> -> <%= link_to t(:setup,:scope=>:user),:controller => "user",:action => "setup",:email => params['email'] %></p>
</div>
</div>
</div>