init import from old mailr project (http://svn.littlegreen.org/mailr/trunk)
This commit is contained in:
commit
51b79e7298
640 changed files with 34651 additions and 0 deletions
68
components/contacts/contact.rb
Normal file
68
components/contacts/contact.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
require 'cdfutils'
|
||||
require_association 'contact_group'
|
||||
|
||||
class Contact < ActiveRecord::Base
|
||||
|
||||
has_and_belongs_to_many :groups, :class_name => "ContactGroup", :join_table => "contact_contact_groups", :association_foreign_key => "contact_group_id", :foreign_key => "contact_id"
|
||||
|
||||
# Finder methods follow
|
||||
def Contact.find_by_user(user_id)
|
||||
find(:all, :conditions => ["customer_id = ?", user_id], :order => "fname asc", :limit => 10)
|
||||
end
|
||||
|
||||
def Contact.find_by_user_email(user_id, email)
|
||||
find(:first, :conditions => ["customer_id = #{user_id} and email = ?", email])
|
||||
end
|
||||
|
||||
def Contact.find_by_group_user(user_id, grp_id)
|
||||
result = Array.new
|
||||
find(:all, :conditions => ["customer_id = ?", user_id], :order => "fname asc").each { |c|
|
||||
begin
|
||||
c.groups.find(grp_id)
|
||||
result << c
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
end
|
||||
}
|
||||
result
|
||||
end
|
||||
|
||||
def Contact.find_by_user_letter(user_id, letter)
|
||||
find_by_sql("select * from contacts where customer_id=#{user_id} and substr(UPPER(fname),1,1) = '#{letter}' order by fname")
|
||||
end
|
||||
|
||||
def full_name
|
||||
"#{fname} #{lname}"
|
||||
end
|
||||
|
||||
def show_name
|
||||
"#{fname} #{lname}"
|
||||
end
|
||||
|
||||
def full_address
|
||||
"#{fname} #{lname}<#{email}>"
|
||||
end
|
||||
|
||||
protected
|
||||
def validate
|
||||
errors.add 'fname', _('Please enter your first name (2 to 20 characters).') unless self.fname =~ /^.{2,20}$/i
|
||||
errors.add 'lname', _('Please enter your surname (2 to 20 characters).') unless self.lname =~ /^.{2,20}$/i
|
||||
|
||||
# Contact e-mail cannot be changed
|
||||
unless self.new_record?
|
||||
old_record = Contact.find(self.id)
|
||||
errors.add 'email', _('Contacts email cannot be changed.') unless old_record.email == self.email
|
||||
end
|
||||
end
|
||||
|
||||
def validate_on_create
|
||||
# Contact e-mail cannot be changed, so we only need to validate it on create
|
||||
errors.add 'email', _('Please enter a valid email address.') unless valid_email?(self.email)
|
||||
# Already existing e-mail in contacts for this user is not allowed
|
||||
if self.new_record?
|
||||
if Contact.find_first("email = '#{email}' and customer_id = #{customer_id}")
|
||||
errors.add('email', _('An account for your email address already exists.'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
79
components/contacts/contact/add.rhtml
Normal file
79
components/contacts/contact/add.rhtml
Normal file
|
@ -0,0 +1,79 @@
|
|||
<h1><%=_('Edit/Create contact')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><span><%= _('Contacts') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_contact_list%></li>
|
||||
<% if ret = @session["return_to"] %>
|
||||
<li><%=link_to(_('Back to message'), ret) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
|
||||
<%=
|
||||
form_tag(
|
||||
link_contact_save,
|
||||
'method' => 'post',
|
||||
'class' => 'two_columns'
|
||||
)
|
||||
%>
|
||||
<%= form_input(:hidden_field, 'contact', 'id') %>
|
||||
<%= form_input(:hidden_field, 'contact', 'customer_id') %>
|
||||
|
||||
<table>
|
||||
<%= form_input(:text_field, 'contact', 'fname', _('First name'), 'class'=>'two_columns') %>
|
||||
<%= form_input(:text_field, 'contact', 'lname', _('Last name'), 'class'=>'two_columns') %>
|
||||
<%= form_input((@contact.new_record? ? :text_field : :read_only_field), 'contact', 'email', _('E-mail'), 'class'=>'two_columns')%>
|
||||
</table>
|
||||
|
||||
<% for group in @contactgroups %>
|
||||
<input id="groups[<%=group.id%>]" type="hidden" name="groups[<%=group.id%>]" value="<%=@groups[group.id]%>">
|
||||
<% end %>
|
||||
<% if not(@contactgroups.empty?) %>
|
||||
<%=_('Contact belong to these groups')%>:
|
||||
<table class="list">
|
||||
<tr>
|
||||
<%
|
||||
end
|
||||
col = 1
|
||||
for group in @contactgroups %>
|
||||
<th>
|
||||
<input id="groups[<%=group.id%>]" type="checkbox" name="groups[<%=group.id%>]" value="<%=@groups[group.id]%>" onclick="toggleCheckbox(this)"
|
||||
<%=@groups[group.id] == 1 ? " checked " : " " %> >
|
||||
<%=group.name %>
|
||||
</th>
|
||||
<% if col%2 == 0 %>
|
||||
</tr>
|
||||
<tr>
|
||||
<% end
|
||||
col = col + 1 %>
|
||||
<% end %>
|
||||
<% if col%2 == 0 and not(@contactgroups.empty?) %>
|
||||
<th> </th>
|
||||
<% end %>
|
||||
<% if not(@contactgroups.empty?) %>
|
||||
</tr>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<table class="edit">
|
||||
<tr>
|
||||
<td colspan=2 class="buttonBar">
|
||||
<input type="submit" name="paction" value="<%=_('Save')%>"/>
|
||||
<input type="submit" name="paction" value="<%=_('Save and add another')%>"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<%= end_form_tag %>
|
||||
</div>
|
||||
</div>
|
26
components/contacts/contact/add_multiple.rhtml
Normal file
26
components/contacts/contact/add_multiple.rhtml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<h1><%=_('Add multiple contacts')%></h1>
|
||||
<% if @flash["errors"] and not @flash["errors"].empty?%>
|
||||
<%= _('Errors')%>
|
||||
<ul>
|
||||
<% @flash["errors"].each do |message| %>
|
||||
<li><%= message %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<form action="<%=link_import_preview%>" enctype="multipart/form-data" method="post">
|
||||
<%= radio_button("contact", "file_type", "1")%> <%= _('Comma-separated (CSV) file')%>
|
||||
<%= radio_button("contact", "file_type", "2")%> <%= _('Tab-delimited text file')%>
|
||||
<table>
|
||||
<tr>
|
||||
<th><label for="contact[data]"><%=_('Select file')%></label></th>
|
||||
<td><input type="file" name="contact[data]"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2>
|
||||
<input type="submit" value="<%=_('Import')%>"/>
|
||||
<input type="button" value="<%= _('Back to contacts')%>" onclick="window.location='<%=link_contact_list%>'">
|
||||
<input type="button" value="<%= _('Back to folders')%>" onclick="window.location='<%=link_main_index%>'">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
11
components/contacts/contact/choose.rhtml
Normal file
11
components/contacts/contact/choose.rhtml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<script language="javascript">
|
||||
<% for to in @tos %>
|
||||
respondTo("<%=to.full_address%>", "<%=to.id%>");
|
||||
<% end %>
|
||||
<% for cc in @ccs %>
|
||||
respondCC("<%=cc.full_address%>");
|
||||
<% end %>
|
||||
<% for bcc in @bccs %>
|
||||
respondBCC("<%=bcc.full_address%>");
|
||||
<% end %>
|
||||
</script>
|
43
components/contacts/contact/import_preview.rhtml
Normal file
43
components/contacts/contact/import_preview.rhtml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<h1><%= _('Contacts You Are About To Import')%></h1>
|
||||
|
||||
<% if @flash["errors"] and not @flash["errors"].empty?%>
|
||||
<%= _('Errors')%>
|
||||
<ul>
|
||||
<% @flash["errors"].each do |message| %>
|
||||
<li><%= message %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<form action="<%=link_contact_import%>" method="post">
|
||||
|
||||
<table class="list">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th width="100px"><%= _('First name')%></th>
|
||||
<th width="100px"><%= _('Last name')%></th>
|
||||
<th><%= _('E-mail')%></th>
|
||||
</tr>
|
||||
<%
|
||||
for i in 0...@contacts.length
|
||||
contact = @contacts[i]
|
||||
%>
|
||||
<tr class="<%= alternator %>">
|
||||
<td><%=i+1%></td>
|
||||
<td><input type="text" name="contact[<%=i%>][fname]" value="<%=contact.fname%>" size="15" /></td>
|
||||
<td><input type="text" name="contact[<%=i%>][lname]" value="<%=contact.lname%>" size="15" /></td>
|
||||
<td><input type="text" name="contact[<%=i%>][email]" value="<%=contact.email%>" size="45" /></td>
|
||||
</tr>
|
||||
|
||||
<% end %>
|
||||
|
||||
<tr>
|
||||
<td colspan=4 class="buttonBar">
|
||||
<input type="submit" value="<%= _('Import')%>">
|
||||
<input type="button" value="<%= _('Choose another file')%>" onclick="window.location='<%=link_contact_add_multiple%>'">
|
||||
<input type="button" value="<%= _('Back to contacts')%>" onclick="window.location='<%=link_contact_list%>'">
|
||||
<input type="button" value="<%= _('Back to folders')%>" onclick="window.location='<%=link_main_index%>'">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
114
components/contacts/contact/list.rhtml
Normal file
114
components/contacts/contact/list.rhtml
Normal file
|
@ -0,0 +1,114 @@
|
|||
<h1><%= _('Contacts')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><span><%= _('Contacts') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_contact_add_one%></li>
|
||||
<li><%=link_contact_add_multiple%></li>
|
||||
<% if ret = @session["return_to"] %>
|
||||
<li><%=link_to(_('Back to message'), ret) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<% if @flash["alert"] %><ul><li><%= @flash["alert"] %></li></ul><% end %>
|
||||
<form action="<%=link_contact_choose%>?mode=<%=@mode%>" method="post">
|
||||
<input type="hidden" name="mode" value="<%=@mode%>"/>
|
||||
<% if @group_id and not @group_id.nil? %>
|
||||
<input type="hidden" name="group_id" value="<%=@group_id%>"/>
|
||||
<% end %>
|
||||
<table class="list">
|
||||
<tr>
|
||||
<td colspan="4" id="alphaListHeader">
|
||||
<%
|
||||
letters = CDF::CONFIG[:contact_letters]
|
||||
for letterIndex in 0...letters.size
|
||||
letter = letters[letterIndex] %>
|
||||
<%= link_to(letter, :controller=>"contact", :action=>"listLetter", :id=>letterIndex, :params=>{"mode"=>@mode, "group_id"=>(@group_id ? @group_id : nil)}) %>
|
||||
<% end %>
|
||||
<%= link_to(_('Show all'), :controller=>"contact", :action=>"list", :id=>(@group_id ? @group_id : nil), :params=>{"mode"=>@mode})%>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><%= @contact_pages.basic_html(self, 2, false, {"mode"=>@mode}) %></td>
|
||||
</tr>
|
||||
<% if @mode == "choose" %>
|
||||
<tr>
|
||||
<th><%= _('To CC BCC')%></th>
|
||||
<th><%= _('Name')%></th>
|
||||
<th><%= _('E-mail')%></th>
|
||||
</tr>
|
||||
<% for contact in @contacts %>
|
||||
<tr class="<%= alternator %>">
|
||||
<td><input type="checkbox" name="contacts_to[<%=contact.id%>]" value="1"/>
|
||||
<input type="checkbox" name="contacts_cc[<%=contact.id%>]" value="1"/>
|
||||
<input type="checkbox" name="contacts_bcc[<%=contact.id%>]" value="1"/></td>
|
||||
<td><%=contact.full_name%></td>
|
||||
<td><%=contact.email%></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<tr class="rowsep"><td colspan="3"><%=_('Groups')%>:</td></tr>
|
||||
<% for group in @contactgroups %>
|
||||
<tr class="<%= alternator %>">
|
||||
<td><input type="checkbox" name="groups_to[<%=group.id%>]" value="1"/>
|
||||
<input type="checkbox" name="groups_cc[<%=group.id%>]" value="1"/>
|
||||
<input type="checkbox" name="groups_bcc[<%=group.id%>]" value="1"/></td>
|
||||
<td><%=group.name%></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td colspan=3 class="buttonBar">
|
||||
<input type="submit" value="<%= _('choose')%>">
|
||||
<input type="button" value="<%= _('cancel')%>" onclick="javascript:window.close();">
|
||||
</td>
|
||||
</tr>
|
||||
<% elsif @mode == "groups"%>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th width="200px"><%= _('Name')%></th>
|
||||
<th><%= _('E-mail')%></th>
|
||||
</tr>
|
||||
<% for contact in @contacts %>
|
||||
<input type="hidden" id="contacts_for_group[<%=contact.id%>]" name="contacts_for_group[<%=contact.id%>]" value="<%=@contacts_for_group[contact.id]%>" >
|
||||
<tr class="<%= alternator %>">
|
||||
<td><input type="checkbox" id="contacts_for_group[<%=contact.id%>]" name="contacts_for_group[<%=contact.id%>]"
|
||||
value="<%=@contacts_for_group[contact.id]%>" onclick="toggleCheckbox(this)"
|
||||
<%=@contacts_for_group[contact.id] == 1 ? " checked " : " " %> ></td>
|
||||
<td><%=contact.full_name%></td>
|
||||
<td><%=contact.email%></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td colspan=2 class="buttonBar">
|
||||
<input type="submit" value="<%= _('Save')%>">
|
||||
<input type="button" value="<%= _('Back to groups')%>" onclick="window.location='<%=link_contact_group_list%>'">
|
||||
</td>
|
||||
</tr>
|
||||
<% else %>
|
||||
<tr>
|
||||
<th width="200px"><%= _('Name')%></th>
|
||||
<th><%= _('E-mail')%></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
<% for contact in @contacts %>
|
||||
<tr class="<%= alternator %>">
|
||||
<td><%= link_to(contact.full_name, :controller=>"/contacts/contact", :action => "edit", :id => contact.id ) %></td>
|
||||
<td><%= link_to( contact.email, :controller => "/webmail", :action => "compose", :params => { "mail[to]" => contact.email } ) %></td>
|
||||
<td><%= link_to(_('delete'), {:controller=>'/contacts/contact', :action=>'delete', :id=>contact.id}, {:confirm=>sprintf(_('DELETE CONTACT?\r\n\Name - %s\r\nE-mail - %s'), contact.show_name, contact.email)})%></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
398
components/contacts/contact_controller.rb
Normal file
398
components/contacts/contact_controller.rb
Normal file
|
@ -0,0 +1,398 @@
|
|||
class Contacts::ContactController < ApplicationController
|
||||
|
||||
uses_component_template_root
|
||||
|
||||
model :customer
|
||||
model :contact
|
||||
model :contact_group
|
||||
helper :pagination
|
||||
layout :select_layout
|
||||
|
||||
def index
|
||||
redirect_to(:action =>"list")
|
||||
end
|
||||
|
||||
def list
|
||||
@contact_pages = Paginator.new(self, Contact.count("customer_id = #{logged_user}"), CDF::CONFIG[:contacts_per_page], @params['page'])
|
||||
@contacts = Contact.find(:all, :conditions=>["customer_id = #{logged_user}"], :order=>['fname'], :limit=>CDF::CONFIG[:contacts_per_page], :offset=>@contact_pages.current.offset)
|
||||
|
||||
if @params["mode"] == "groups"
|
||||
if @params["id"] and not @params["id"].nil? and not @params["id"] == ''
|
||||
@group_id = @params["id"].to_i
|
||||
@contacts_for_group = Hash.new
|
||||
for contact in @contacts
|
||||
@contacts_for_group[contact.id] = 0 # initialize
|
||||
for gr in contact.groups
|
||||
if gr.contact_group_id.to_i == @group_id
|
||||
@contacts_for_group[contact.id] = 1 # checked
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def listLetter
|
||||
letters = CDF::CONFIG[:contact_letters]
|
||||
@contact_pages = Paginator.new(self, Contact.count(
|
||||
["customer_id = %s and substr(UPPER(fname),1,1) = '%s'", logged_user, letters[@params['id'].to_i]]), CDF::CONFIG[:contacts_per_page], @params['page'])
|
||||
@contacts = Contact.find(:all, :conditions=>["customer_id = %s and substr(UPPER(fname),1,1) = '%s'", logged_user, letters[@params['id'].to_i]],
|
||||
:order=>['fname'], :limit=>CDF::CONFIG[:contacts_per_page], :offset=>@contact_pages.current.offset)
|
||||
|
||||
if @params["mode"] == "groups"
|
||||
if @params["group_id"] and not @params["group_id"].nil? and not @params["group_id"] == ''
|
||||
@group_id = @params["group_id"].to_i
|
||||
@contacts_for_group = Hash.new
|
||||
for contact in @contacts
|
||||
@contacts_for_group[contact.id] = 0 # initialize
|
||||
for gr in contact.groups
|
||||
if gr.contact_group_id.to_i == @group_id
|
||||
@contacts_for_group[contact.id] = 1 # checked
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
render :action => "list"
|
||||
end
|
||||
|
||||
def add
|
||||
@contact = Contact.new
|
||||
@contact.customer_id = logged_user
|
||||
|
||||
# load related lists
|
||||
loadLists
|
||||
|
||||
# Init groups: because of checkbox
|
||||
# Set all to 0 => unchecked
|
||||
@groups = Hash.new
|
||||
@contactgroups.each {|g|
|
||||
@groups[g.id] = 0
|
||||
}
|
||||
end
|
||||
|
||||
def add_multiple
|
||||
@contact = Contact.new
|
||||
@contact["file_type"] = "1"
|
||||
end
|
||||
|
||||
def add_from_mail
|
||||
cstr = @params['cstr']
|
||||
retmsg = @params['retmsg']
|
||||
@session["return_to"] = url_for(:controller=>'/webmail/webmail',
|
||||
:action=>'folders',
|
||||
:msg_id=>retmsg)
|
||||
# parse string
|
||||
if i = cstr.index("<")
|
||||
name, email = cstr.slice(0, i), cstr.slice((i+1)..(cstr.strip().index(">")-1))
|
||||
fname = name.split().first
|
||||
lname = name.split().last if name.split().size() > 1
|
||||
else
|
||||
fname, lname, email = "", "", cstr
|
||||
end
|
||||
|
||||
if @contact = Contact.find_by_user_email(logged_user, email)
|
||||
# load related lists
|
||||
loadLists
|
||||
|
||||
@contact.fname, @contact.lname = fname, lname
|
||||
|
||||
# groups = @contact.groups
|
||||
@groups = Hash.new
|
||||
@contactgroups.each {|g|
|
||||
groupSelected = false
|
||||
@contact.groups.each {|gr|
|
||||
if gr.contact_group_id.to_i == g.id.to_i
|
||||
groupSelected = true
|
||||
break
|
||||
end
|
||||
}
|
||||
if groupSelected
|
||||
@groups[g.id] = 1 # checked
|
||||
else
|
||||
@groups[g.id] = 0 # unchecked
|
||||
end
|
||||
}
|
||||
else
|
||||
@contact = Contact.new("fname"=>fname, "lname" => lname, "email" => email)
|
||||
@contact.customer_id = logged_user
|
||||
|
||||
# load related lists
|
||||
loadLists
|
||||
|
||||
# Init groups: because of checkbox
|
||||
# Set all to 0 => unchecked
|
||||
@groups = Hash.new
|
||||
@contactgroups.each {|g|
|
||||
@groups[g.id] = 0
|
||||
}
|
||||
end
|
||||
render :action => "add"
|
||||
end
|
||||
|
||||
def import_preview
|
||||
file = @params["contact"]["data"]
|
||||
|
||||
flash["errors"] = Array.new
|
||||
|
||||
if file.size == 0
|
||||
flash["errors"] << _('You haven\'t selected file or the file is empty')
|
||||
@contact = Contact.new
|
||||
@contact["file_type"] = @params["contact"]["file_type"]
|
||||
render :action => "add_multiple"
|
||||
end
|
||||
|
||||
file_type = @params["contact"]["file_type"]
|
||||
if file_type.nil? or file_type == '1'
|
||||
separator = ','
|
||||
else
|
||||
separator = /\t/
|
||||
|
||||
end
|
||||
|
||||
@contacts = Array.new
|
||||
emails = Array.new
|
||||
|
||||
file.each {|line|
|
||||
cdata = line.strip.chomp.split(separator)
|
||||
cont = Contact.new
|
||||
cont.fname = cdata[0].to_s.strip.chomp
|
||||
cont.lname = cdata[1].to_s.strip.chomp
|
||||
cont.email = cdata[2].to_s.strip.chomp
|
||||
|
||||
# Check for duplicate emails in the file
|
||||
if emails.include?(cont.email)
|
||||
flash["errors"] << sprintf(_('Contact %'), file.lineno.to_s) + ": " + _('The e-mail duplicates the e-mail of another record!')
|
||||
else
|
||||
emails << cont.email
|
||||
end
|
||||
|
||||
@contacts << cont
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
def import
|
||||
contacts_count = @params["contact"].length
|
||||
contacts_to_import = @params["contact"]
|
||||
@contacts = Array.new
|
||||
emails = Array.new
|
||||
|
||||
flash["errors"] = Array.new
|
||||
|
||||
for i in 0...contacts_count
|
||||
contact = Contact.new
|
||||
contact.customer_id = logged_user
|
||||
contact.fname = contacts_to_import[i.to_s]["fname"]
|
||||
contact.lname = contacts_to_import[i.to_s]["lname"]
|
||||
contact.email = contacts_to_import[i.to_s]["email"]
|
||||
|
||||
begin
|
||||
# Check for duplicate emails in the submitted data
|
||||
if emails.include?(contact.email)
|
||||
flash["errors"] << sprintf(_('Contact %'), (i+1).to_s) + ": " + _('The e-mail duplicates the e-mail of another record!')
|
||||
else
|
||||
emails << contact.email
|
||||
end
|
||||
# Check if contact is valid
|
||||
contact.valid?
|
||||
rescue CDF::ValidationError => e
|
||||
if not contact.errors.empty?
|
||||
["fname", "lname", "email"].each do |attr|
|
||||
attr_errors = contact.errors.on(attr)
|
||||
attr_errors = [attr_errors] unless attr_errors.nil? or attr_errors.is_a? Array
|
||||
|
||||
if not attr_errors.nil?
|
||||
attr_errors.each do |msg|
|
||||
flash["errors"] << l(:contact_addmultiple_errorforcontact, (i+1).to_s) + ": " + l(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end # rescue
|
||||
|
||||
@contacts << contact
|
||||
end # for
|
||||
|
||||
# If there are validation errors - display them
|
||||
if not flash["errors"].nil? and not flash["errors"].empty?
|
||||
render :action => "import_preview"
|
||||
else
|
||||
# save
|
||||
begin
|
||||
for contact in @contacts
|
||||
Contact.create(contact.attributes)
|
||||
end
|
||||
# Set message for successful import
|
||||
flash["alert"] = Array.new
|
||||
flash["alert"] << l(:contact_addmultiple_success, @contacts.length.to_s)
|
||||
keep_flash()
|
||||
redirect_to(:action=>"list")
|
||||
rescue Exception => exc
|
||||
flash["errors"] << exc
|
||||
render :action => "import_preview"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def choose
|
||||
if @params["mode"] == "groups"
|
||||
save_groups
|
||||
end
|
||||
|
||||
@tos, @ccs, @bccs = Array.new, Array.new, Array.new
|
||||
|
||||
@params["contacts_to"].each{ |id,value| @tos << Contact.find(id) if value == "1" } if @params["contacts_to"]
|
||||
@params["contacts_cc"].each{ |id,value| @ccs << Contact.find(id) if value == "1" } if @params["contacts_cc"]
|
||||
@params["contacts_bcc"].each{ |id,value| @bccs << Contact.find(id) if value == "1" } if @params["contacts_bcc"]
|
||||
|
||||
@params["groups_to"].each{ |id,value|
|
||||
ContactGroup.find(id).contacts.each {|c| @tos << c} if value == "1" } if @params["groups_to"]
|
||||
@params["groups_cc"].each{ |id,value|
|
||||
ContactGroup.find(id).contacts.each {|c| @ccs << c} if value == "1" } if @params["groups_cc"]
|
||||
@params["groups_bcc"].each{ |id,value|
|
||||
ContactGroup.find(id).contacts.each {|c| @bccs << c} if value == "1" } if @params["groups_bcc"]
|
||||
end
|
||||
|
||||
def save_groups
|
||||
contacts_for_group = @params["contacts_for_group"]
|
||||
group_id = @params["group_id"]
|
||||
contact_group = ContactGroup.find(group_id)
|
||||
|
||||
|
||||
contacts_for_group.each { |contact_id,value|
|
||||
contact = Contact.find(contact_id)
|
||||
if value == "1" and not contact_group.contacts.include?(contact)
|
||||
contact_group.contacts << contact
|
||||
end
|
||||
if value == "0" and contact_group.contacts.include?(contact)
|
||||
contact_group.contacts.delete(contact)
|
||||
end
|
||||
}
|
||||
redirect_to(:action=>"list", :id=>group_id, :params=>{"mode"=>@params["mode"]})
|
||||
end
|
||||
|
||||
def edit
|
||||
@contact = Contact.find(@params["id"])
|
||||
# load related lists
|
||||
loadLists
|
||||
|
||||
# groups = @contact.groups
|
||||
@groups = Hash.new
|
||||
@contactgroups.each {|g|
|
||||
groupSelected = false
|
||||
@contact.groups.each {|gr|
|
||||
if gr.contact_group_id.to_i == g.id.to_i
|
||||
groupSelected = true
|
||||
break
|
||||
end
|
||||
}
|
||||
if groupSelected
|
||||
@groups[g.id] = 1 # checked
|
||||
else
|
||||
@groups[g.id] = 0 # unchecked
|
||||
end
|
||||
}
|
||||
render :action => "add"
|
||||
end
|
||||
|
||||
# Insert or update
|
||||
def save
|
||||
logger.info("BEGIN")
|
||||
if @params["contact"]["id"] == ""
|
||||
# New contact
|
||||
@contact = Contact.create(@params["contact"])
|
||||
else
|
||||
# Edit existing
|
||||
@contact = Contact.find(@params["contact"]["id"])
|
||||
@contact.attributes = @params["contact"]
|
||||
end
|
||||
|
||||
@contactgroups = ContactGroup.find_by_user(logged_user)
|
||||
# Groups displayed
|
||||
groups = @params['groups']
|
||||
tempGroups = Array.new
|
||||
tempGroups.concat(@contact.groups)
|
||||
|
||||
@contactgroups.each { |cgroup|
|
||||
includesCGroup = false
|
||||
tempGroups.each {|gr|
|
||||
if gr.contact_group_id.to_i == cgroup.id.to_i
|
||||
includesCGroup = true
|
||||
break
|
||||
end
|
||||
}
|
||||
if groups["#{cgroup.id}"] == "1" and not includesCGroup
|
||||
@contact.groups << cgroup
|
||||
end
|
||||
|
||||
if groups["#{cgroup.id}"] == "0" and includesCGroup
|
||||
@contact.groups.delete(cgroup)
|
||||
end
|
||||
}
|
||||
if @contact.save
|
||||
if @params["paction"] == _('Save')
|
||||
redirect_to :controller => "/contacts/contact", :action =>"list"
|
||||
else
|
||||
redirect_to :controller => "/contacts/contact", :action =>"add"
|
||||
end
|
||||
else
|
||||
loadLists
|
||||
@groups = Hash.new
|
||||
@contactgroups.each {|g|
|
||||
if @contact.groups.include?(g)
|
||||
@groups[g.id] = 1
|
||||
else
|
||||
@groups[g.id] = 0
|
||||
end
|
||||
}
|
||||
render :action => "add"
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
Contact.destroy(@params['id'])
|
||||
redirect_to(:action=>'list')
|
||||
end
|
||||
|
||||
protected
|
||||
def secure_user?() true end
|
||||
def additional_scripts()
|
||||
add_s = ''
|
||||
if action_name == "choose"
|
||||
add_s<<'<script type="text/javascript" src="/javascripts/global.js"></script>'
|
||||
add_s<<'<script type="text/javascript" src="/javascripts/contact_choose.js"></script>'
|
||||
end
|
||||
add_s
|
||||
end
|
||||
|
||||
def onload_function()
|
||||
if action_name == "choose"
|
||||
"javascript:respondToCaller();"
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
private
|
||||
def select_layout
|
||||
if @params["mode"] == "choose"
|
||||
@mode = "choose"
|
||||
@contactgroups = ContactGroup.find_by_user(logged_user)
|
||||
'chooser'
|
||||
elsif @params["mode"] == "groups"
|
||||
@mode = "groups"
|
||||
'public'
|
||||
else
|
||||
@mode = "normal"
|
||||
'public'
|
||||
end
|
||||
end
|
||||
|
||||
def loadLists
|
||||
if @contactgroups.nil?
|
||||
@contactgroups = ContactGroup.find_by_user(logged_user)
|
||||
end
|
||||
end
|
||||
end
|
25
components/contacts/contact_group.rb
Normal file
25
components/contacts/contact_group.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
class ContactGroup < ActiveRecord::Base
|
||||
has_and_belongs_to_many :contacts, :class_name => "Contact", :join_table => "contact_contact_groups", :association_foreign_key => "contact_id", :foreign_key => "contact_group_id"
|
||||
|
||||
def ContactGroup.find_by_user(user_id)
|
||||
find_by_sql("select * from contact_groups where customer_id = #{user_id} order by name asc")
|
||||
end
|
||||
|
||||
protected
|
||||
def validate
|
||||
errors.add('name', :contactgroup_name_invalid) unless self.name =~ /^.{1,50}$/i
|
||||
end
|
||||
|
||||
def validate_on_create
|
||||
if ContactGroup.find_first(["name = '#{name}' and customer_id = #{user_id}"])
|
||||
errors.add("name", _('Please enter group name (1 to 50 characters)'))
|
||||
end
|
||||
end
|
||||
|
||||
def validate_on_update
|
||||
if ContactGroup.find_first(["name = '#{name}' and customer_id = #{user_id} and id <> #{id}"])
|
||||
errors.add("name", _('You already have contact group with this name'))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
24
components/contacts/contact_group/edit.rhtml
Normal file
24
components/contacts/contact_group/edit.rhtml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<h1><%=_('Edit/Create Contact Group')%></h1>
|
||||
<%=
|
||||
form_tag(
|
||||
link_save,
|
||||
'method' => 'post',
|
||||
'class' => 'two_columns'
|
||||
)
|
||||
%>
|
||||
<%= form_input(:hidden_field, 'contactgroup', 'id') %>
|
||||
<%= form_input(:hidden_field, 'contactgroup', 'customer_id') %>
|
||||
|
||||
<table>
|
||||
<%= form_input(:text_field, 'contactgroup', 'name', _('Name'), 'class'=>'two_columns') %>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan=2 class="buttonBar">
|
||||
<input type="submit" name="Save" value="<%=_('Save')%>"/>
|
||||
<input type="button" value="<%=_('Back to groups')%>" onclick="window.location='<%=link_list%>'"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<%= end_form_tag %>
|
26
components/contacts/contact_group/list.rhtml
Normal file
26
components/contacts/contact_group/list.rhtml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<h1><%=_('Contact Groups')%></h1>
|
||||
|
||||
<form action="/contact_group/add" method="post">
|
||||
<%= hidden_field "contactgroup", "user_id" %>
|
||||
<table class="list">
|
||||
<tr>
|
||||
<th><%=_('Name')%></th>
|
||||
<th colspan=3> </th>
|
||||
</tr>
|
||||
<%
|
||||
for contactgroup in @contactgroups %>
|
||||
<tr class="even">
|
||||
<td><%= contactgroup.name %></td>
|
||||
<td><%= link_to(_('members'), :controller=>'contact', :action=>'list', :id=>contactgroup.id, :params=>{"mode"=>"groups"}) %></td>
|
||||
<td><%= link_to(_('edit'), :controller=>'/contacts/contact_group', :action=>'edit', :id=>contactgroup.id) %></td>
|
||||
<td><%= link_to(_('delete'), {:controller=>'/contacts/contact_group', :action=>'delete', :id=>contactgroup.id}, {:confirm=>sprintf(_('DELETE CONTACT GROUP \'%s\'?'), contactgroup.name)})%></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td colspan=2 class="buttonBar">
|
||||
<input type="submit" value="<%=_('Add Contact Group')%>"/>
|
||||
<input type="button" value="<%=_('Back to folders')%>" onclick="window.location='/webmail/folders'">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
60
components/contacts/contact_group_controller.rb
Normal file
60
components/contacts/contact_group_controller.rb
Normal file
|
@ -0,0 +1,60 @@
|
|||
class Contacts::ContactGroupController < ApplicationController
|
||||
|
||||
uses_component_template_root
|
||||
|
||||
model :contact_group
|
||||
layout 'public'
|
||||
|
||||
def index
|
||||
redirect_to(:action=>"list")
|
||||
end
|
||||
|
||||
def list
|
||||
@contactgroup = ContactGroup.new
|
||||
@contactgroup.customer_id = logged_user
|
||||
@contactgroups = ContactGroup.find_by_user(logged_user)
|
||||
end
|
||||
|
||||
def add
|
||||
@contactgroup = ContactGroup.new
|
||||
@contactgroup.customer_id = logged_user
|
||||
render("/contact_group/edit")
|
||||
end
|
||||
|
||||
def delete
|
||||
contactgroup = ContactGroup.find(@params["id"])
|
||||
contactgroup.destroy
|
||||
redirect_to(:action=>"list")
|
||||
end
|
||||
|
||||
def edit
|
||||
@contactgroup = ContactGroup.find(@params["id"])
|
||||
end
|
||||
|
||||
def save
|
||||
begin
|
||||
if @params["contactgroup"]["id"].nil? or @params["contactgroup"]["id"] == ""
|
||||
# New contactgroup
|
||||
@contactgroup = ContactGroup.create(@params["contactgroup"])
|
||||
else
|
||||
# Edit existing
|
||||
@contactgroup = ContactGroup.find(@params["contactgroup"]["id"])
|
||||
@contactgroup.attributes = @params["contactgroup"]
|
||||
end
|
||||
|
||||
if @contactgroup.save
|
||||
redirect_to(:action=>"list")
|
||||
else
|
||||
render "/contact_group/edit"
|
||||
end
|
||||
rescue CDF::ValidationError => e
|
||||
logger.info("RESCUE")
|
||||
@contactgroup = e.entity
|
||||
render("/contact_group/edit")
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def secure_user?() true end
|
||||
|
||||
end
|
4
components/contacts/contact_group_helper.rb
Normal file
4
components/contacts/contact_group_helper.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
module ContactGroupHelper
|
||||
def link_save() "/contact_group/save" end
|
||||
def link_list() "/contact_group/list" end
|
||||
end
|
40
components/contacts/contact_helper.rb
Normal file
40
components/contacts/contact_helper.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
module Contacts::ContactHelper
|
||||
def link_import_preview() "/contacts/contact/import_preview" end
|
||||
def link_main_index() "/webmail/webmail/folders" end
|
||||
def link_contact_save() "/contacts/contact/save" end
|
||||
def link_contact_import() "/contacts/contact/import" end
|
||||
def link_contact_choose() "/contacts/contact/choose" end
|
||||
|
||||
def link_contact_list
|
||||
link_to(_('List'), :controller => "/contacts/contact", :action => "list")
|
||||
end
|
||||
|
||||
def link_contact_add_one
|
||||
link_to(_('Add one contact'), :controller => "/contacts/contact", :action => "add")
|
||||
end
|
||||
|
||||
def link_contact_add_multiple
|
||||
link_to(_('Add multiple'), :controller => "/contacts/contact", :action => "add_multiple")
|
||||
end
|
||||
|
||||
def link_contact_group_list
|
||||
link_to(_('Groups'), :controller => "/contacts/contact_group", :action => "list")
|
||||
end
|
||||
|
||||
def link_folders
|
||||
link_to(_('Folders'), :controller=>"/webmail/webmail", :action=>"messages")
|
||||
end
|
||||
|
||||
def link_send_mail
|
||||
link_to(_('Compose'), :controller=>"/webmail/webmail", :action=>"compose")
|
||||
end
|
||||
|
||||
def link_mail_prefs
|
||||
link_to(_('Preferences'), :controller=>"/webmail/webmail", :action=>"prefs")
|
||||
end
|
||||
|
||||
def link_mail_filters
|
||||
link_to(_('Filters'), :controller=>"/webmail/webmail", :action=>"filters")
|
||||
end
|
||||
|
||||
end
|
32
components/contacts/customer.rb
Normal file
32
components/contacts/customer.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
require_dependency 'maildropserializator'
|
||||
class Customer < ActiveRecord::Base
|
||||
include MaildropSerializator
|
||||
|
||||
has_many :filters, :order => "order_num"
|
||||
has_one :mail_pref
|
||||
attr_accessor :password
|
||||
|
||||
def mail_temporary_path
|
||||
"#{CDF::CONFIG[:mail_temp_path]}/#{self.email}"
|
||||
end
|
||||
|
||||
def friendlly_local_email
|
||||
encode_email("#{self.fname} #{self.lname}", check_for_domain(email))
|
||||
end
|
||||
|
||||
def mail_filter_path
|
||||
"#{CDF::CONFIG[:mail_filters_path]}/#{self.email}"
|
||||
end
|
||||
|
||||
def local_email
|
||||
self.email
|
||||
end
|
||||
|
||||
def check_for_domain(email)
|
||||
if email and !email.nil? and !email.include?("@")
|
||||
email + "@" + CDF::CONFIG[:send_from_domain]
|
||||
else
|
||||
email
|
||||
end
|
||||
end
|
||||
end
|
18
components/layouts/chooser.rhtml
Normal file
18
components/layouts/chooser.rhtml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= @htmllang %>" lang="<%= @htmllang %>">
|
||||
<head>
|
||||
<title><%=@title%></title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=<%= @charset %>" />
|
||||
<script type="text/javascript" src="/javascripts/global.js"></script>
|
||||
<link rel="stylesheet" href="/stylesheets/admin.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="/stylesheets/tabs.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="/stylesheets/mailr.css" type="text/css" media="screen" />
|
||||
<%=@additional_scripts%>
|
||||
</head>
|
||||
<body id="bodyID" onload="<%=@onload_function%>">
|
||||
<%= @content_for_layout %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
26
components/layouts/public.rhtml
Normal file
26
components/layouts/public.rhtml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= @htmllang %>" lang="<%= @htmllang %>">
|
||||
<head>
|
||||
<title><%=_('Mailr')%></title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=<%= @charset %>" />
|
||||
<link rel="stylesheet" href="/stylesheets/admin.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="/stylesheets/tabs.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="/stylesheets/mailr.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript" src="/javascripts/global.js"></script>
|
||||
<script type="text/javascript" src="/javascripts/prototype.js"></script>
|
||||
<%=(@content_for_scripts ? @content_for_scripts : @additional_scripts )%>
|
||||
</head>
|
||||
<body id="bodyID" onload="<%=@onload_function%>">
|
||||
<div id="wholepage">
|
||||
<div id="container">
|
||||
<div id="logout"><%= link_to _('[Logout]'), :controller=>'/login', :action=>'logout' %></div>
|
||||
<div id="sidebar_outer">
|
||||
<div id="sidebar"><%= @content_for_sidebar %></div>
|
||||
</div>
|
||||
<div id="content"><%= @content_for_layout %></div>
|
||||
<br class="clear"/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
8
components/webmail/bounced_mail.rb
Normal file
8
components/webmail/bounced_mail.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
class BouncedMail < ActiveRecord::Base
|
||||
belongs_to :customer
|
||||
belongs_to :contact
|
||||
|
||||
def BouncedMail.find_by_customer_contact(cust_id, contact_id)
|
||||
find_all(["customer_id = ? and contact_id = ?", cust_id, cotact_id], ["msg_date desc"])
|
||||
end
|
||||
end
|
303
components/webmail/cdfmail.rb
Normal file
303
components/webmail/cdfmail.rb
Normal file
|
@ -0,0 +1,303 @@
|
|||
require 'tmail'
|
||||
require 'net/smtp'
|
||||
require 'mail_transform'
|
||||
|
||||
class CDF::Mail
|
||||
include ActionMailer::Quoting
|
||||
|
||||
def initialize(senderTempLocation)
|
||||
@attachments = Array.new
|
||||
@sender_temp_location = senderTempLocation
|
||||
@to_contacts = Array.new
|
||||
end
|
||||
|
||||
def customer_id() @customer_id end
|
||||
|
||||
def customer_id=(arg) @customer_id = arg end
|
||||
|
||||
def from() @from end
|
||||
|
||||
def from=(arg) @from = arg end
|
||||
|
||||
def to() @to end
|
||||
|
||||
def to=(arg) @to = arg end
|
||||
|
||||
def to_contacts() @to_contacts end
|
||||
|
||||
def to_contacts=(arg) @to_contacts = arg end
|
||||
|
||||
def toc=(arg)
|
||||
@to_contacts = Array.new
|
||||
arg.split(",").each { |token| @to_contacts << token.to_i unless token == "" or token.strip() == "undefined"} unless arg.nil? or arg == "undefined"
|
||||
end
|
||||
|
||||
def toc
|
||||
ret = String.new
|
||||
@to_contacts.each { |contact|
|
||||
ret << "," unless ret == ""
|
||||
if contact.kind_of?(Integer)
|
||||
ret << contact.to_s unless contact.nil? or contact == 0
|
||||
else
|
||||
ret << contact.id.to_s unless contact.nil? or contact.id.nil?
|
||||
end
|
||||
}
|
||||
ret
|
||||
end
|
||||
|
||||
def bcc() @bcc end
|
||||
|
||||
def bcc=(arg) @bcc = arg end
|
||||
|
||||
def cc() @cc end
|
||||
|
||||
def cc=(arg) @cc = arg end
|
||||
|
||||
def subject() @subject end
|
||||
|
||||
def subject=(arg) @subject = arg end
|
||||
|
||||
def attachments
|
||||
@attachments
|
||||
end
|
||||
|
||||
def add_attachment(attachment)
|
||||
@attachments << attachment
|
||||
end
|
||||
|
||||
def multipart?
|
||||
@attachments && @attachments.size > 0
|
||||
end
|
||||
|
||||
def delete_attachment(att_filename)
|
||||
@attachments.each { |att| att.delete_temp_data() if arr.filename == att_filename }
|
||||
@attachments.delete_if() { |att| att.filename == att_filename }
|
||||
end
|
||||
|
||||
def delete_attachments()
|
||||
@attachments.each { |att| att.delete_temp_data() }
|
||||
@attachments = Array.new
|
||||
end
|
||||
|
||||
def body() @body end
|
||||
|
||||
def body=(arg) @body = arg end
|
||||
|
||||
def content_type() @content_type end
|
||||
|
||||
def content_type=(arg) @content_type = arg end
|
||||
|
||||
def temp_location() @sender_temp_location end
|
||||
|
||||
def send_mail(db_msg_id = 0)
|
||||
m = TMail::Mail.new
|
||||
m.from, m.body = self.from, self.body
|
||||
m.date = Time.now
|
||||
m.subject, = quote_any_if_necessary("UTF-8", self.subject)
|
||||
m.to = decode_addresses(self.to)
|
||||
|
||||
m.cc, m.bcc = decode_addresses(self.cc), decode_addresses(self.bcc)
|
||||
|
||||
if multipart?
|
||||
m.set_content_type("multipart/mixed")
|
||||
p = TMail::Mail.new(TMail::StringPort.new(""))
|
||||
if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!!
|
||||
prepare_text(p, self.content_type, self.body)
|
||||
elsif self.content_type.include?("text/html")
|
||||
prepare_html(p, self.content_type, self.body)
|
||||
elsif self.content_type.include?("multipart")
|
||||
prepare_alternative(p, self.body)
|
||||
end
|
||||
m.parts << p
|
||||
else
|
||||
if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!!
|
||||
prepare_text(m, self.content_type, self.body)
|
||||
elsif self.content_type.include?("text/html")
|
||||
prepare_html(m, self.content_type, self.body)
|
||||
elsif self.content_type.include?("multipart")
|
||||
prepare_alternative(m, self.body)
|
||||
end
|
||||
end
|
||||
# attachments
|
||||
@attachments.each { |a|
|
||||
m.parts << a.encoded
|
||||
}
|
||||
encmail = m.encoded
|
||||
RAILS_DEFAULT_LOGGER.debug("Sending message \n #{encmail}")
|
||||
Net::SMTP.start(ActionMailer::Base.server_settings[:address], ActionMailer::Base.server_settings[:port],
|
||||
ActionMailer::Base.server_settings[:domain], ActionMailer::Base.server_settings[:user_name],
|
||||
ActionMailer::Base.server_settings[:password], ActionMailer::Base.server_settings[:authentication]) do |smtp|
|
||||
smtp.sendmail(encmail, m.from, m.destinations)
|
||||
end
|
||||
return encmail
|
||||
end
|
||||
|
||||
def forward(tmail, fb)
|
||||
decoded_subject = mime_encoded?(tmail.subject) ? mime_decode(tmail.subject) : tmail.subject
|
||||
self.subject = "[Fwd: #{decoded_subject}]"
|
||||
attachment = CDF::Attachment.new(self)
|
||||
attachment.body(tmail, fb)
|
||||
end
|
||||
|
||||
def reply(tmail, fb, type)
|
||||
decoded_subject = mime_encoded?(tmail.subject) ? mime_decode(tmail.subject) : tmail.subject
|
||||
self.subject = "[Re: #{decoded_subject}]"
|
||||
tm = tmail.setup_reply(tmail)
|
||||
self.to = tm.to
|
||||
footer = ""
|
||||
msg_id = ""
|
||||
mt = MailTransform.new
|
||||
self.body = mt.get_body(tmail, type)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delimeter
|
||||
if self.content_type == "text/plain"
|
||||
"\n"
|
||||
else
|
||||
"<br/>"
|
||||
end
|
||||
end
|
||||
|
||||
def text2html(str) CGI.escapeHTML(str).gsub("\n", "<br/>") end
|
||||
|
||||
def html2text(txt)
|
||||
clear_html(txt)
|
||||
end
|
||||
|
||||
def prepare_text(msg, ctype, bdy)
|
||||
msg.set_content_type(ctype, nil, {"charset"=>"utf-8"})
|
||||
msg.transfer_encoding = "8bit"
|
||||
msg.body = bdy
|
||||
end
|
||||
|
||||
def prepare_html(msg, ctype, bdy)
|
||||
msg.set_content_type(ctype, nil, {"charset"=>"utf8"})
|
||||
msg.transfer_encoding = "8bit"
|
||||
msg.body = bdy
|
||||
end
|
||||
|
||||
def prepare_alternative(msg, bdy)
|
||||
bound = ::TMail.new_boundary
|
||||
|
||||
msg.set_content_type("multipart/alternative", nil, {"charset"=>"utf8", "boundary"=>bound})
|
||||
msg.transfer_encoding = "8bit"
|
||||
|
||||
ptext = TMail::Mail.new(TMail::StringPort.new(""))
|
||||
phtml = TMail::Mail.new(TMail::StringPort.new(""))
|
||||
|
||||
prepare_text(ptext, "text/plain", html2text(bdy))
|
||||
prepare_html(phtml, "text/html", bdy)
|
||||
|
||||
msg.parts << ptext
|
||||
msg.parts << phtml
|
||||
end
|
||||
|
||||
def decode_addresses(str)
|
||||
ret = String.new
|
||||
str.split(",").each { |addr|
|
||||
if addr.slice(0,4) == "Grp+"
|
||||
grp_id = addr.scan(/Grp\+([0-9]*):(.*)/)[0][0]
|
||||
ContactGroup.find(:first, :conditions=>['customer_id = ? and id = ?', @customer_id, grp_id]).contacts.each { |contact|
|
||||
ret << "," if not(ret == "")
|
||||
@to_contacts << contact unless contact.nil?
|
||||
ret << contact.full_address
|
||||
ad, = quote_any_address_if_necessary(CDF::CONFIG[:mail_charset], contact.full_address)
|
||||
ret << ad
|
||||
}
|
||||
else
|
||||
ret << "," if not(ret == "")
|
||||
ad, = quote_any_address_if_necessary(CDF::CONFIG[:mail_charset], addr) if not(addr.nil? or addr == "")
|
||||
ret << ad if not(addr.nil? or addr == "")
|
||||
end
|
||||
} unless str.nil? or str.strip() == ""
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
class CDF::Attachment
|
||||
|
||||
def initialize(arg)
|
||||
@mail = arg
|
||||
@mail.add_attachment(self)
|
||||
@index = @mail.attachments.size - 1
|
||||
end
|
||||
|
||||
def filename=(arg)
|
||||
@filename = arg.tr('\\/:*?"\'<>|', '__________')
|
||||
end
|
||||
|
||||
def filename() @filename end
|
||||
|
||||
def temp_filename=(arg) @temp_filename = arg end
|
||||
|
||||
def temp_filename() @temp_filename end
|
||||
|
||||
def content_type=(arg) @content_type = arg end
|
||||
|
||||
def content_type() @content_type end
|
||||
|
||||
def delete_temp_data()
|
||||
File.delete(self.temp_filename)
|
||||
end
|
||||
|
||||
def file
|
||||
File.open(self.temp_filename, "rb") { |fp| fp.read }
|
||||
end
|
||||
|
||||
def file=(data)
|
||||
return if data.size == 0
|
||||
@content_type = data.content_type
|
||||
self.filename = data.original_filename.scan(/[^\\]*$/).first
|
||||
self.temp_filename = "#{@mail.temp_location}/#{@filename}"
|
||||
check_store_path
|
||||
data.rewind
|
||||
File.open(@temp_filename, "wb") { |f| f.write(data.read) }
|
||||
end
|
||||
|
||||
def body(data, fb)
|
||||
@content_type = "message/rfc822"
|
||||
filename = data.content_type['filename']
|
||||
self.filename = filename.nil? ? (mime_encoded?(data.subject) ? mime_decode(data.subject) : data.subject) : filename
|
||||
self.temp_filename = "#{@mail.temp_location}/#{@filename}"
|
||||
check_store_path
|
||||
File.open(@temp_filename, "wb") { |f| f.write(fb) }
|
||||
end
|
||||
|
||||
def check_store_path()
|
||||
path = ""
|
||||
"#{@mail.temp_location}".split(File::SEPARATOR).each { |p|
|
||||
path << p
|
||||
begin
|
||||
Dir.mkdir(path)
|
||||
rescue
|
||||
end
|
||||
path << File::SEPARATOR
|
||||
}
|
||||
end
|
||||
|
||||
def encoded
|
||||
p = TMail::Mail.new(TMail::StringPort.new(""))
|
||||
data = self.file
|
||||
p.body = data
|
||||
if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!!
|
||||
p.set_content_type(@content_type, nil, {"charset"=>"utf-8"})
|
||||
p.transfer_encoding = "8bit"
|
||||
elsif @content_type.include?("text/html")
|
||||
p.set_content_type(@content_type, nil, {"charset"=>"utf8"})
|
||||
p.transfer_encoding = "8bit"
|
||||
elsif @content_type.include?("rfc822")
|
||||
p.set_content_type(@content_type, nil, {"charset"=>"utf8"})
|
||||
p.set_disposition("inline;")
|
||||
p.transfer_encoding = "8bit"
|
||||
else
|
||||
p.set_content_type(@content_type, nil, {"name"=>@filename})
|
||||
p.set_disposition("inline; filename=#{@filename}") unless @filename.nil?
|
||||
p.set_disposition("inline;") if @filename.nil?
|
||||
p.transfer_encoding='Base64'
|
||||
p.body = TMail::Base64.folding_encode(data)
|
||||
end
|
||||
return p
|
||||
end
|
||||
end
|
5
components/webmail/environment.rb
Normal file
5
components/webmail/environment.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
require 'maildropserializator'
|
||||
Customer.class_eval do
|
||||
include MaildropSerializator
|
||||
has_many :filters, :order => "order_num", :dependent => true
|
||||
end
|
2
components/webmail/expression.rb
Normal file
2
components/webmail/expression.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Expression < ActiveRecord::Base
|
||||
end
|
3
components/webmail/filter.rb
Normal file
3
components/webmail/filter.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Filter < ActiveRecord::Base
|
||||
has_many :expressions
|
||||
end
|
38
components/webmail/imap_message.rb
Normal file
38
components/webmail/imap_message.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require 'mail2screen'
|
||||
class ImapMessage < ActiveRecord::Base
|
||||
include Mail2Screen
|
||||
|
||||
def set_folder(folder)
|
||||
@folder = folder
|
||||
end
|
||||
|
||||
def full_body
|
||||
@folder.mailbox.imap.uid_fetch(uid, "BODY[]").first.attr["BODY[]"]
|
||||
end
|
||||
|
||||
def from_addr=(fa)
|
||||
self.from = fa.to_yaml
|
||||
self.from_flat = short_address(fa)
|
||||
end
|
||||
|
||||
def from_addr
|
||||
begin
|
||||
YAML::load(from)
|
||||
rescue Object
|
||||
from
|
||||
end
|
||||
end
|
||||
|
||||
def to_addr=(ta)
|
||||
self.to = ta.to_yaml
|
||||
self.to_flat = short_address(ta)
|
||||
end
|
||||
|
||||
def to_addr
|
||||
begin
|
||||
YAML::load(to)
|
||||
rescue Object
|
||||
to
|
||||
end
|
||||
end
|
||||
end
|
497
components/webmail/imapmailbox.rb
Normal file
497
components/webmail/imapmailbox.rb
Normal file
|
@ -0,0 +1,497 @@
|
|||
# Copyright (c) 2005, Benjamin Stiglitz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Modifications (c) 2005 by littlegreen
|
||||
#
|
||||
require 'net/imap'
|
||||
|
||||
Net::IMAP.debug = true if CDF::CONFIG[:debug_imap]
|
||||
|
||||
class Net::IMAP
|
||||
class PlainAuthenticator
|
||||
def process(data)
|
||||
return "\0#{@user}\0#{@password}"
|
||||
end
|
||||
|
||||
private
|
||||
def initialize(user, password)
|
||||
@user = user
|
||||
@password = password
|
||||
end
|
||||
end
|
||||
add_authenticator('PLAIN', PlainAuthenticator)
|
||||
|
||||
class Address
|
||||
def to_s
|
||||
if(name)
|
||||
"#{name} #{mailbox}@#{host}"
|
||||
else
|
||||
"#{mailbox}@#{host}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class AuthenticationError < RuntimeError
|
||||
end
|
||||
|
||||
class IMAPMailbox
|
||||
attr_reader :connected
|
||||
attr_accessor :selected_mailbox
|
||||
cattr_accessor :logger
|
||||
|
||||
def initialize
|
||||
@selected_mailbox = ''
|
||||
@folders = {}
|
||||
@connected = false
|
||||
end
|
||||
|
||||
def connect(username, password)
|
||||
unless @connected
|
||||
use_ssl = CDF::CONFIG[:imap_use_ssl] ? true : false
|
||||
port = CDF::CONFIG[:imap_port] || (use_ssl ? 993 : 143)
|
||||
begin
|
||||
@imap = Net::IMAP.new(CDF::CONFIG[:imap_server], port, use_ssl)
|
||||
rescue Net::IMAP::ByeResponseError => bye
|
||||
# make a timeout and retry
|
||||
begin
|
||||
System.sleep(CDF::CONFIG[:imap_bye_timeout_retry_seconds])
|
||||
@imap = Net::IMAP.new(CDF::CONFIG[:imap_server], port, use_ssl)
|
||||
rescue Error => ex
|
||||
logger.error "Error on authentication!"
|
||||
logger.error bye.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
end
|
||||
rescue Net::IMAP::NoResponseError => noresp
|
||||
logger.error "Error on authentication!"
|
||||
logger.error noresp.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
rescue Net::IMAP::BadResponseError => bad
|
||||
logger.error "Error on authentication!"
|
||||
logger.error bad.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
rescue Net::IMAP::ResponseError => resp
|
||||
logger.error "Error on authentication!"
|
||||
logger.error resp.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
end
|
||||
@username = username
|
||||
begin
|
||||
logger.error "IMAP authentication - #{CDF::CONFIG[:imap_auth]}."
|
||||
if CDF::CONFIG[:imap_auth] == 'NOAUTH'
|
||||
@imap.login(username, password)
|
||||
else
|
||||
@imap.authenticate(CDF::CONFIG[:imap_auth], username, password)
|
||||
end
|
||||
@connected = true
|
||||
rescue Exception => ex
|
||||
logger.error "Error on authentication!"
|
||||
logger.error ex.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def imap
|
||||
@imap
|
||||
end
|
||||
|
||||
# Function chnage password works only if root has run imap_backend
|
||||
# and users courier-authlib utility authtest - from courier-imap version 4.0.1
|
||||
def change_password(username, password, new_password)
|
||||
ret = ""
|
||||
cin, cout, cerr = Open3.popen3("/usr/sbin/authtest #{username} #{password} #{new_password}")
|
||||
ret << cerr.gets
|
||||
if ret.include?("Password change succeeded.")
|
||||
return true
|
||||
else
|
||||
logger.error "[!] Error on change password! - #{ret}"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def disconnect
|
||||
if @connected
|
||||
@imap.logout
|
||||
@imap.disconnect
|
||||
@imap = nil
|
||||
@connected = false
|
||||
end
|
||||
end
|
||||
|
||||
def [](mailboxname)
|
||||
@last_folder = IMAPFolderList.new(self, @username)[mailboxname]
|
||||
end
|
||||
|
||||
def folders
|
||||
# reference just to stop GC
|
||||
@folder_list ||= IMAPFolderList.new(self, @username)
|
||||
@folder_list
|
||||
end
|
||||
|
||||
def reload
|
||||
@folder_list.reload if @folder_list
|
||||
end
|
||||
|
||||
def create_folder(name)
|
||||
begin
|
||||
@imap.create(name)
|
||||
reload
|
||||
rescue Exception=>e
|
||||
end
|
||||
end
|
||||
|
||||
def delete_folder(name)
|
||||
begin
|
||||
@imap.delete(name)
|
||||
reload
|
||||
rescue Exception=>e
|
||||
logger.error("Exception on delete #{name} folder #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def message_sent(message)
|
||||
# ensure we have sent folder
|
||||
begin
|
||||
@imap.create(CDF::CONFIG[:mail_sent])
|
||||
rescue Exception=>e
|
||||
end
|
||||
begin
|
||||
@imap.append(CDF::CONFIG[:mail_sent], message)
|
||||
folders[CDF::CONFIG[:mail_sent]].cached = false if folders[CDF::CONFIG[:mail_sent]]
|
||||
rescue Exception=>e
|
||||
logger.error("Error on append - #{e}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def message_bulk(message)
|
||||
# ensure we have sent folder
|
||||
begin
|
||||
@imap.create(CDF::CONFIG[:mail_bulk_sent])
|
||||
rescue Exception=>e
|
||||
end
|
||||
begin
|
||||
@imap.append(CDF::CONFIG[:mail_bulk_sent], message)
|
||||
folders[CDF::CONFIG[:mail_sent]].cached = false if folders[CDF::CONFIG[:mail_bulk_sent]]
|
||||
rescue Exception=>e
|
||||
logger.error("Error on bulk - #{e}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class IMAPFolderList
|
||||
include Enumerable
|
||||
cattr_accessor :logger
|
||||
|
||||
def initialize(mailbox, username)
|
||||
@mailbox = mailbox
|
||||
@folders = Hash.new
|
||||
@username = username
|
||||
end
|
||||
|
||||
def each
|
||||
refresh if @folders.empty?
|
||||
#@folders.each_value { |folder| yield folder }
|
||||
# We want to allow sorted access; for now only (FIXME)
|
||||
|
||||
@folders.sort.each { |pair| yield pair.last }
|
||||
end
|
||||
|
||||
def reload
|
||||
refresh
|
||||
end
|
||||
|
||||
def [](name)
|
||||
refresh if @folders.empty?
|
||||
@folders[name]
|
||||
end
|
||||
|
||||
private
|
||||
def refresh
|
||||
@folders = {}
|
||||
result = @mailbox.imap.list('', '*')
|
||||
if result
|
||||
result.each do |info|
|
||||
@folders[info.name] = IMAPFolder.new(@mailbox, info.name, @username, info.attr, info.delim)
|
||||
end
|
||||
else
|
||||
# if there are no folders subscribe to INBOX - this is on first use
|
||||
@mailbox.imap.subscribe(CDF::CONFIG[:mail_inbox])
|
||||
# try again to list them - we should find INBOX
|
||||
@mailbox.imap.list('', '*').each do |info|
|
||||
@folders[info.name] = IMAPFolder.new(@mailbox, info.name, @username, info.attr, info.delim)
|
||||
end
|
||||
end
|
||||
@folders
|
||||
end
|
||||
end
|
||||
|
||||
class IMAPFolder
|
||||
attr_reader :mailbox
|
||||
attr_reader :name
|
||||
attr_reader :username
|
||||
attr_reader :delim
|
||||
attr_reader :attribs
|
||||
|
||||
attr_writer :cached
|
||||
attr_writer :mcached
|
||||
|
||||
cattr_accessor :logger
|
||||
|
||||
@@fetch_attr = ['ENVELOPE','BODYSTRUCTURE', 'FLAGS', 'UID', 'RFC822.SIZE']
|
||||
|
||||
def initialize(mailbox, name, username, attribs, delim)
|
||||
@mailbox = mailbox
|
||||
@name = name
|
||||
@username = username
|
||||
@messages = Array.new
|
||||
@delim = delim
|
||||
@attribs = attribs
|
||||
@cached = false
|
||||
@mcached = false
|
||||
end
|
||||
|
||||
def activate
|
||||
if(@mailbox.selected_mailbox != @name)
|
||||
@mailbox.selected_mailbox = @name
|
||||
@mailbox.imap.select(@name)
|
||||
load_total_unseen if !@cached
|
||||
end
|
||||
end
|
||||
|
||||
# Just delete message without interaction with Trash folder
|
||||
def delete(message)
|
||||
uid = (message.kind_of?(Integer) ? message : message.uid)
|
||||
@mailbox.imap.uid_store(uid, "+FLAGS", :Deleted)
|
||||
@mailbox.imap.expunge
|
||||
# Sync with trash cannot be made - new uid generated - so just delete message from current folder
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid = ?", @username, @name, uid])
|
||||
@cached = false
|
||||
end
|
||||
|
||||
# Deleted messages - move to trash folder
|
||||
def delete_multiple(uids)
|
||||
# ensure we have trash folder
|
||||
begin
|
||||
@mailbox.imap.create(CDF::CONFIG[:mail_trash])
|
||||
rescue
|
||||
end
|
||||
move_multiple(uids, CDF::CONFIG[:mail_trash])
|
||||
end
|
||||
|
||||
def copy(message, dst_folder)
|
||||
uid = (message.kind_of?(Integer) ? message : message.uid)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(uid, dst_folder)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
end
|
||||
|
||||
def copy_multiple(message_uids, dst_folder)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(message_uids, dst_folder)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
end
|
||||
|
||||
def move(message, dst_folder)
|
||||
uid = (message.kind_of?(Integer) ? message : message.uid)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(uid, dst_folder)
|
||||
@mailbox.imap.uid_store(uid, "+FLAGS", :Deleted)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.imap.expunge
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid = ? ", @username, @name, uid])
|
||||
@cached = false
|
||||
@mcached = false
|
||||
end
|
||||
|
||||
def move_multiple(message_uids, dst_folder)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(message_uids, dst_folder)
|
||||
@mailbox.imap.uid_store(message_uids, "+FLAGS", :Deleted)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.imap.expunge
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid in ( ? )", @username, @name, message_uids])
|
||||
@cached = false
|
||||
@mcached = false
|
||||
end
|
||||
|
||||
def mark_read(message_uid)
|
||||
activate
|
||||
cached = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, message_uid])
|
||||
if cached.unread
|
||||
cached.unread = false
|
||||
cached.save
|
||||
@mailbox.imap.select(@name)
|
||||
@mailbox.imap.uid_store(message_uid, "+FLAGS", :Seen)
|
||||
@unseen_messages = @unseen_messages - 1
|
||||
end
|
||||
end
|
||||
|
||||
def mark_unread(message_uid)
|
||||
activate
|
||||
cached = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, message_uid])
|
||||
if !cached.unread
|
||||
cached.unread = true
|
||||
cached.save
|
||||
@mailbox.imap.select(@name)
|
||||
@mailbox.imap.uid_store(message_uid, "-FLAGS", :Seen)
|
||||
@unseen_messages = @unseen_messages + 1
|
||||
end
|
||||
end
|
||||
|
||||
def expunge
|
||||
activate
|
||||
@mailbox.imap.expunge
|
||||
end
|
||||
|
||||
def synchronize_cache
|
||||
startSync = Time.now
|
||||
activate
|
||||
startUidFetch = Time.now
|
||||
server_messages = @mailbox.imap.uid_fetch(1..-1, ['UID', 'FLAGS'])
|
||||
|
||||
startDbFetch = Time.now
|
||||
cached_messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name])
|
||||
|
||||
cached_unread_uids = Array.new
|
||||
cached_read_uids = Array.new
|
||||
uids_to_be_deleted = Array.new
|
||||
|
||||
cached_messages.each { |msg|
|
||||
cached_unread_uids << msg.uid if msg.unread
|
||||
cached_read_uids << msg.uid unless msg.unread
|
||||
uids_to_be_deleted << msg.uid
|
||||
}
|
||||
|
||||
uids_to_be_fetched = Array.new
|
||||
server_msg_uids = Array.new
|
||||
|
||||
uids_unread = Array.new
|
||||
uids_read = Array.new
|
||||
|
||||
server_messages.each { |server_msg|
|
||||
uid, flags = server_msg.attr['UID'], server_msg.attr['FLAGS']
|
||||
server_msg_uids << uid
|
||||
unless uids_to_be_deleted.include?(uid)
|
||||
uids_to_be_fetched << uid
|
||||
else
|
||||
if flags.member?(:Seen) && cached_unread_uids.include?(uid)
|
||||
uids_read << uid
|
||||
elsif !flags.member?(:Seen) && cached_read_uids.include?(uid)
|
||||
uids_unread << uid
|
||||
end
|
||||
end
|
||||
uids_to_be_deleted.delete(uid)
|
||||
} unless server_messages.nil?
|
||||
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_to_be_deleted]) unless uids_to_be_deleted.empty?
|
||||
ImapMessage.update_all('unread = 0', ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_read]) unless uids_read.empty?
|
||||
ImapMessage.update_all('unread = 1', ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_unread]) unless uids_unread.empty?
|
||||
|
||||
|
||||
# fetch and store not cached messages
|
||||
unless uids_to_be_fetched.empty?
|
||||
imapres = @mailbox.imap.uid_fetch(uids_to_be_fetched, @@fetch_attr)
|
||||
imapres.each { |cache|
|
||||
envelope = cache.attr['ENVELOPE'];
|
||||
message = ImapMessage.create( :folder_name => @name,
|
||||
:username => @username,
|
||||
:msg_id => envelope.message_id,
|
||||
:uid => cache.attr['UID'],
|
||||
:from_addr => envelope.from,
|
||||
:to_addr => envelope.to,
|
||||
:subject => envelope.subject,
|
||||
:content_type => cache.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text',
|
||||
:date => envelope.date,
|
||||
:unread => !(cache.attr['FLAGS'].member? :Seen),
|
||||
:size => cache.attr['RFC822.SIZE'])
|
||||
}
|
||||
end
|
||||
@mcached = true
|
||||
logger.debug("Synchonization done for folder #{@name} in #{Time.now - startSync} ms.")
|
||||
end
|
||||
|
||||
def messages(offset = 0, limit = 10, sort = 'date desc')
|
||||
# Synchronize first retrieval time
|
||||
synchronize_cache unless @mcached
|
||||
|
||||
if limit == -1
|
||||
@messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name], :order => sort)
|
||||
else
|
||||
@messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name], :order => sort, :limit => limit, :offset => offset )
|
||||
end
|
||||
end
|
||||
|
||||
def messages_search(query = ["ALL"], sort = 'date desc')
|
||||
activate
|
||||
uids = @mailbox.imap.uid_search(query)
|
||||
if uids.size > 1
|
||||
ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids], :order => sort )
|
||||
elsif uids.size == 1
|
||||
ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ? and uid = ? ", @username, @name, uids.first], :order => sort )
|
||||
else
|
||||
return Array.new
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def message(uid)
|
||||
activate
|
||||
message = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, uid])
|
||||
message.set_folder(self)
|
||||
message
|
||||
end
|
||||
|
||||
def unseen
|
||||
activate
|
||||
load_total_unseen if !@cached
|
||||
@unseen_messages
|
||||
end
|
||||
|
||||
def total
|
||||
activate
|
||||
load_total_unseen if !@cached
|
||||
@total_messages
|
||||
end
|
||||
|
||||
def load_total_unseen
|
||||
stat = @mailbox.imap.status(@name, ["MESSAGES", "UNSEEN"])
|
||||
@total_messages, @unseen_messages = stat["MESSAGES"], stat['UNSEEN']
|
||||
@cached = true
|
||||
end
|
||||
|
||||
def update_status
|
||||
@status ||= @mailbox.imap.status(@name, ["MESSAGES"])
|
||||
end
|
||||
|
||||
def subscribe
|
||||
@mailbox.imap.subscribe(@name)
|
||||
end
|
||||
end
|
167
components/webmail/mail2screen.rb
Normal file
167
components/webmail/mail2screen.rb
Normal file
|
@ -0,0 +1,167 @@
|
|||
require 'cdfutils'
|
||||
module Mail2Screen
|
||||
def mail2html(mail, msg_id)
|
||||
footer = ""
|
||||
parsed_body = create_body(mail, msg_id, footer)
|
||||
|
||||
ret = "<table class='messageheader' border='0' cellpadding='0' cellspacing='0' >\n"
|
||||
ret << "<tbody>\n"
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('From')}:</td><td>#{address(mail.from_addrs, @msg_id)}</td></tr>\n"
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('To')}:</td><td>#{address(mail.to_addrs, @msg_id)}</td></tr>\n"
|
||||
if @mail.cc_addrs
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('CC')}:</td><td>#{address(mail.cc_addrs, @msg_id)}</td></tr>\n"
|
||||
end
|
||||
if @mail.bcc_addrs
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('BCC')}:</td><td>#{address(mail.bcc_addrs, @msg_id)}</td></tr>\n"
|
||||
end
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('Subject')}:</td><td>#{h(mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject)}</dd>\n"
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('Date')}:</td><td>#{h message_date(mail.date)}</td></tr>\n"
|
||||
if footer != ''
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{image_tag('attachment.png')}</td><td>#{footer}</td></tr>\n"
|
||||
end
|
||||
ret << " </tbody>\n"
|
||||
ret << "</table>\n"
|
||||
|
||||
ret << "<div class='msgpart'>\n"
|
||||
ret << parsed_body
|
||||
ret << "</div>\n"
|
||||
end
|
||||
|
||||
def create_body(mail, msg_id, footer)
|
||||
charset = (mail.charset.nil? ? 'iso-8859-1' : mail.charset)
|
||||
if mail.multipart?
|
||||
ret = ""
|
||||
if mail.content_type == 'multipart/alternative'
|
||||
# take only HTML part
|
||||
mail.parts.each { |part|
|
||||
if part.content_type == "text/html" or part.multipart?
|
||||
ret << create_body(part, msg_id, footer)
|
||||
end
|
||||
}
|
||||
return ret
|
||||
else
|
||||
mail.parts.each { |part|
|
||||
if part.multipart?
|
||||
ret << create_body(part, msg_id, footer)
|
||||
else
|
||||
footer << ", " if footer != ''
|
||||
footer << add_attachment(part.header['content-type'], msg_id)
|
||||
if part.content_type == "text/plain" or part.content_type.nil?
|
||||
charset = (part.charset.nil? ? charset : mail.charset)
|
||||
ret << add_text(part, part.transfer_encoding, charset)
|
||||
elsif part.content_type == "text/html"
|
||||
charset = (part.charset.nil? ? charset : mail.charset)
|
||||
ret << add_html(part, part.transfer_encoding, charset)
|
||||
elsif part.content_type.include?("image/")
|
||||
ctype = part.header['content-type']
|
||||
ret << add_image(ctype, msg_id)
|
||||
elsif part.content_type.include?("message/rfc822")
|
||||
ret << "<br/>#{_('Follows attached message')}:<hr/>" << mail2html(TMail::Mail.parse(part.body), msg_id)
|
||||
end
|
||||
end
|
||||
}
|
||||
return ret
|
||||
end
|
||||
else
|
||||
ret = ""
|
||||
if mail.content_type == "text/plain" or mail.content_type.nil?
|
||||
ret << add_text(mail, mail.transfer_encoding, charset)
|
||||
elsif mail.content_type == "text/html"
|
||||
ret << add_html(mail, mail.transfer_encoding, charset)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
def add_text(part, encoding, charset)
|
||||
CGI.escapeHTML(decode_part_text("#{part}", encoding, charset)).gsub(/\r\n/,"<br/>").gsub(/\r/, "<br/>").gsub(/\n/,"<br/>")
|
||||
end
|
||||
|
||||
def add_html(part, encoding, charset)
|
||||
strip_html(decode_part_text("#{part}", encoding, charset))
|
||||
end
|
||||
|
||||
def decode_part_text(part_str, encoding, charset)
|
||||
# Parse mail
|
||||
header, text = "", ""
|
||||
|
||||
# Get header and body
|
||||
#Content-type: text/plain; charset="ISO-8859-1"
|
||||
#Content-transfer-encoding: quoted-printable
|
||||
isBody = false
|
||||
part_str.each_line { |line|
|
||||
if isBody
|
||||
text << line
|
||||
else
|
||||
if line.strip == ""
|
||||
isBody = true
|
||||
else
|
||||
header << line
|
||||
end
|
||||
end
|
||||
}
|
||||
# Manage encoding
|
||||
if not(encoding.nil?) and encoding.downcase == "quoted-printable"
|
||||
ret = from_qp(text)
|
||||
elsif not(encoding.nil?) and encoding.downcase == "base64"
|
||||
ret = "#{text.unpack("m")}"
|
||||
else
|
||||
ret = text
|
||||
end
|
||||
# manage charset
|
||||
if ret.nil? or charset.nil? or charset.downcase == "utf-8"
|
||||
return ret
|
||||
else
|
||||
begin
|
||||
return Iconv.conv("UTF-8",charset.downcase, ret)
|
||||
rescue Exception => ex
|
||||
RAILS_DEFAULT_LOGGER.debug("Exception occured #{ex}\n#{ex.backtrace.join('\n')}")
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_attachment(content_type, msg_id)
|
||||
filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name'])
|
||||
if filename == ""
|
||||
""
|
||||
else
|
||||
"<span class='attachment'> <a href='/webmail/webmail/download?msg_id=#{msg_id}&ctype=" << CGI.escape(filename) << "'>#{filename}</a></span>"
|
||||
end
|
||||
end
|
||||
|
||||
def add_image(content_type, msg_id)
|
||||
filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name'])
|
||||
"<hr/><span class='attachment'><br/><img src='/webmail/webmail/download?msg_id=#{msg_id}&ctype=" << CGI.escape(filename) << "' alt='#{filename}'/></span>"
|
||||
end
|
||||
|
||||
def friendly_address(addr)
|
||||
addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.strip == "") ? "#{addr.mailbox}@#{addr.host}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.mailbox}@#{addr.host}>") : ((addr.name.nil? or addr.name.strip == "") ? "#{addr.spec}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.spec}>")
|
||||
end
|
||||
|
||||
def friendly_address_or_name(addr)
|
||||
addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.mailbox}@#{addr.host}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s)) : ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.spec}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s))
|
||||
end
|
||||
|
||||
def add_to_contact(addr, msg_id)
|
||||
" <a href='/contacts/contact/add_from_mail?cstr=#{CGI.escape(friendly_address(addr))}&retmsg=#{msg_id}'>Add to contacts</a>"
|
||||
end
|
||||
|
||||
def short_address(addresses)
|
||||
ret = ""
|
||||
addresses.each { |addr| #split(/,\s*/)
|
||||
ret << "," unless ret == ""
|
||||
ret << CGI.escapeHTML(friendly_address_or_name(addr))
|
||||
} unless addresses.nil?
|
||||
ret
|
||||
end
|
||||
|
||||
def address(addresses, msg_id)
|
||||
ret = ""
|
||||
addresses.each { |addr| #split(/,\s*/)
|
||||
ret << "," unless ret == ""
|
||||
ret << CGI.escapeHTML(friendly_address_or_name(addr)) << add_to_contact(addr, msg_id)
|
||||
} unless addresses.nil?
|
||||
return ret
|
||||
end
|
||||
end
|
9
components/webmail/mail_pref.rb
Normal file
9
components/webmail/mail_pref.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require_association 'customer'
|
||||
|
||||
class MailPref < ActiveRecord::Base
|
||||
belongs_to :customer
|
||||
|
||||
def MailPref.find_by_customer(customer_id)
|
||||
find_first(["customer_id = #{customer_id}"])
|
||||
end
|
||||
end
|
75
components/webmail/mail_transform.rb
Normal file
75
components/webmail/mail_transform.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
require 'mail2screen'
|
||||
|
||||
class MailTransform
|
||||
include Mail2Screen
|
||||
|
||||
def get_body(tmail, type)
|
||||
@mail = tmail
|
||||
footer = ""
|
||||
msg_id = ""
|
||||
ret = mail2html(tmail, msg_id)
|
||||
ret = ret.gsub(/<br\/>/,"\n").gsub(/ /, " ").gsub(/</, "<").gsub(/>/, ">").gsub(/&/, "&").gsub(/<hr\/>/, "\n").gsub(/\n/, "\n> ") if type == 'text/plain'
|
||||
ret = ret.gsub(/\r\n/,"<br/>").gsub(/\r/, "<br/>").gsub(/\n/,"<br/>").gsub(/<br\/>/, "<br/>> ") unless type == 'text/plain'
|
||||
return ret
|
||||
end
|
||||
|
||||
def mail2html(mail, msg_id)
|
||||
footer = ""
|
||||
parsed_body = create_body(mail, msg_id, footer)
|
||||
|
||||
ret = "-----Original Message-----\n#{_('From')}:#{address(mail.from_addrs, @msg_id)}\n"
|
||||
ret << "#{_('To')}:#{address(mail.to_addrs, @msg_id)}\n"
|
||||
if @mail.cc_addrs
|
||||
ret << " #{_('CC')}:#{address(mail.cc_addrs, @msg_id)}\n"
|
||||
end
|
||||
if @mail.bcc_addrs
|
||||
ret << "#{_('BCC')}:#{address(mail.bcc_addrs, @msg_id)}\n"
|
||||
end
|
||||
ret << "#{_('Subject')}:#{mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject}\n"
|
||||
ret << "#{_('Date')}:#{message_date(mail.date)}\n"
|
||||
ret << "\n"
|
||||
ret << "\n"
|
||||
ret << parsed_body
|
||||
ret << "\n"
|
||||
end
|
||||
|
||||
def message_date(datestr)
|
||||
t = Time.now
|
||||
begin
|
||||
if datestr.kind_of?(String)
|
||||
d = (Time.rfc2822(datestr) rescue Time.parse(value)).localtime
|
||||
else
|
||||
d = datestr
|
||||
end
|
||||
if d.day == t.day and d.month == t.month and d.year == t.year
|
||||
d.strftime("%H:%M")
|
||||
else
|
||||
d.strftime("%Y-%m-%d")
|
||||
end
|
||||
rescue
|
||||
begin
|
||||
d = imap2time(datestr)
|
||||
if d.day == t.day and d.month == t.month and d.year == t.year
|
||||
d.strftime("%H:%M")
|
||||
else
|
||||
d.strftime("%Y-%m-%d")
|
||||
end
|
||||
rescue
|
||||
datestr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Overwrite some staff
|
||||
def add_to_contact(addr, msg_id)
|
||||
""
|
||||
end
|
||||
def add_attachment(content_type, msg_id)
|
||||
""
|
||||
end
|
||||
|
||||
def add_image(content_type, msg_id)
|
||||
""
|
||||
end
|
||||
|
||||
end
|
51
components/webmail/maildropserializator.rb
Normal file
51
components/webmail/maildropserializator.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
module MaildropSerializator
|
||||
def serialize_to_file
|
||||
mail_drop_filter = File.new(self.mail_filter_path, "w")
|
||||
for filter in filters
|
||||
mail_drop_filter << "# filter '#{filter.name}'\n"
|
||||
mail_drop_filter << "if (#{filter_expressions(filter)})\n"
|
||||
mail_drop_filter << "{\n"
|
||||
mail_drop_filter << " exception {\n"
|
||||
mail_drop_filter << " to #{dest_folder(filter)}\n"
|
||||
mail_drop_filter << " }\n"
|
||||
mail_drop_filter << "}\n"
|
||||
end
|
||||
mail_drop_filter.close()
|
||||
end
|
||||
|
||||
private
|
||||
def dest_folder(filter)
|
||||
'$DEFAULT/'<<filter.destination_folder.sub(Regexp.new("(#{CDF::CONFIG[:mail_inbox]})(.*)"), '\2')<<"/"
|
||||
end
|
||||
|
||||
def escape_expr_value(text)
|
||||
text.gsub(".", "\\.").gsub("*", "\\*").gsub("[", "\\[").gsub("]", "\\]").gsub("(", "\\(").gsub(")", "\\)").
|
||||
gsub("?", "\\?")
|
||||
end
|
||||
|
||||
def filter_expressions(filter)
|
||||
fe = ""
|
||||
for exp in filter.expressions
|
||||
post_flag = "h"
|
||||
fe << " && " unless fe == ""
|
||||
if exp.field_name == "^Body"
|
||||
fe << "/"
|
||||
post_flag = "b"
|
||||
else
|
||||
fe << "/#{exp.field_name}:"
|
||||
end
|
||||
if exp.operator == 'contains'
|
||||
fe << ".*(#{escape_expr_value(exp.expr_value)})/"
|
||||
else
|
||||
# starts with
|
||||
fe << "[ ]*(#{escape_expr_value(exp.expr_value)}).*/"
|
||||
end
|
||||
if exp.case_sensitive == 1
|
||||
fe << "D" << post_flag
|
||||
else
|
||||
fe << post_flag
|
||||
end
|
||||
end
|
||||
fe
|
||||
end
|
||||
end
|
4
components/webmail/routes.rb
Normal file
4
components/webmail/routes.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Webmail mapping
|
||||
map.connect 'webmail', :controller => 'webmail/webmail', :action => 'messages'
|
||||
|
||||
|
3
components/webmail/virtual_email.rb
Normal file
3
components/webmail/virtual_email.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class VirtualEmail < ActiveRecord::Base
|
||||
def self.table_name() "cdf.wm_virtual" end
|
||||
end
|
5
components/webmail/webmail/_contacts.rhtml
Normal file
5
components/webmail/webmail/_contacts.rhtml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<ul class="contacts">
|
||||
<% for contact in @contacts do -%>
|
||||
<li class="contact"><%=h contact.fname %> <%= h contact.lname %> <div class='email'><div class="notviscode">&lt;</div><%= h contact.email %><div class="notviscode">&gt;</div></div></li>
|
||||
<% end -%>
|
||||
</ul>
|
18
components/webmail/webmail/_expr.rhtml
Normal file
18
components/webmail/webmail/_expr.rhtml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<% @expression = @expressions[expr_counter] %>
|
||||
<tr>
|
||||
<td>
|
||||
<select name="expression[<%=expr_counter%>][field_name]">
|
||||
<%= options_for_select(CDF::CONFIG[:mail_filters_fields], @expressions[expr_counter].field_name)%>
|
||||
</select></td>
|
||||
<td>
|
||||
<select name="expression[<%=expr_counter%>][operator]">
|
||||
<%= options_for_select(CDF::CONFIG[:mail_filters_expressions], @expressions[expr_counter].operator)%>
|
||||
</select></td>
|
||||
<td>
|
||||
<%= text_field 'expression', 'expr_value', 'index'=>expr_counter %>
|
||||
</td>
|
||||
<td>
|
||||
<%= hidden_field "expression", 'case_sensitive', 'index'=>expr_counter %>
|
||||
<%= check_box "expression", 'case_sensitive', {'onclick'=>'toggleCheckbox(this)', "index"=>expr_counter } %> <%= _('case sensitive') %>
|
||||
</td>
|
||||
</tr>
|
19
components/webmail/webmail/_filter.rhtml
Normal file
19
components/webmail/webmail/_filter.rhtml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<tr>
|
||||
<td><%=h @user.filters[filter_counter].name%></th>
|
||||
<td>
|
||||
<% if filter_counter > 0 %>
|
||||
<%=link_filter_up(@user.filters[filter_counter].id)%>
|
||||
<% else %>
|
||||
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if filter_counter < @user.filters.size - 1 %>
|
||||
<%=link_filter_down(@user.filters[filter_counter].id)%>
|
||||
<% else %>
|
||||
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%=link_filter_edit(@user.filters[filter_counter].id)%></td>
|
||||
<td><%=link_filter_delete(@user.filters[filter_counter].id)%></td>
|
||||
</tr>
|
14
components/webmail/webmail/_message_row.rhtml
Normal file
14
components/webmail/webmail/_message_row.rhtml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<tr class="<%= message_row.unread ? 'notseen': 'seen' %>">
|
||||
<td class="mark"><input type="checkbox" name="messages[<%= message_row.uid %>]"/></td>
|
||||
<% if @folder_name == CDF::CONFIG[:mail_sent] %>
|
||||
<td class="to"><%= short_address(message_row.to_addr) %></td>
|
||||
<% else %>
|
||||
<td class="from"><%= short_address(message_row.from_addr) %></td>
|
||||
<% end %>
|
||||
<td class="subject"><div class='cutField'>
|
||||
<%= link_to(parse_subject(message_row.subject) << " " , :controller=>'webmail', :action=>'message', :msg_id=>message_row.uid)%>
|
||||
</td>
|
||||
<td class="date"><%= message_date(message_row.date) %></td>
|
||||
<td class="size"><%= message_size(message_row.size) %></td>
|
||||
<td class="attachind"><%= message_row.content_type == 'multipart' ? image_tag('attachment.png') : ' ' %></td>
|
||||
</tr>
|
13
components/webmail/webmail/_search.rhtml
Normal file
13
components/webmail/webmail/_search.rhtml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<a href='#' onclick='toggle_msg_search(true);'>
|
||||
<%=_('Search')%><img id='img_msg_search' alt='open' src='/images/list_<%=@srch_img_src%>.gif'/>
|
||||
</a>
|
||||
<div id="msg_search" class='<%=@srch_class%>'>
|
||||
<%=_('Search in message field')%>
|
||||
<select name="search_field">
|
||||
<%= options_for_select(CDF::CONFIG[:mail_search_fields], @search_field)%>
|
||||
</select>
|
||||
<label for="search_value"><%=_('for')%></label>
|
||||
<input type="text" name="search_value" value="<%=@search_value%>" size='16' id='search_value'/>
|
||||
<%= submit_tag(_('Search'), :name=>'op')%>
|
||||
<%= submit_tag(_('Show all'), :name=>'op')%>
|
||||
</div>
|
67
components/webmail/webmail/compose.rhtml
Normal file
67
components/webmail/webmail/compose.rhtml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<form name="composeMail" id='composeMail' action="/webmail/webmail/compose" enctype="multipart/form-data" method="post">
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><span><%= _('Compose') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_compose_new%></li>
|
||||
<li><a href='#' onclick="getFormField('composeMail').submit();"><%=_('Send')%></a></li>
|
||||
<li><a href="#" onclick="chooseContacts();"><%= _('Choose addresses from contacts') %></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<div id="msg-compose">
|
||||
<input type="hidden" id="mail_toc" name="mail[toc]" value="<%=@mail.toc%>"/>
|
||||
<input type="hidden" id="mail_op" name="op" value="<%=_('Send')%>"/>
|
||||
<div id="msghdr">
|
||||
<table>
|
||||
<tr><td><label for=''><%=_('To')%></label></td><td><%= text_field_with_auto_complete(:mail, :to, {"size"=>65}, :skip_style => true, :tokens=> ",") %></td></tr>
|
||||
<tr><td><label for=''><%=_('CC')%></label></td><td><%= text_field_with_auto_complete(:mail, :cc, {"size"=>65}, :skip_style => true, :tokens=> ",") %></td></tr>
|
||||
<tr><td><label for=''><%=_('BCC')%></label></td><td><%= text_field_with_auto_complete(:mail, :bcc, {"size"=>65}, :skip_style => true, :tokens=> ",") %></td></tr>
|
||||
<tr><td><label for=''><%=_('Subject')%></label></td><td><%= text_field('mail', 'subject', {"size"=>65}) %></td></tr>
|
||||
</table>
|
||||
<%= hidden_field('mail', 'from') %>
|
||||
<%= hidden_field('mail', 'content_type') %>
|
||||
</div>
|
||||
|
||||
<div class="msgpart ct-text-plain">
|
||||
<%= text_area "mail", "body", "rows"=>20, "cols"=>75 %>
|
||||
</div>
|
||||
|
||||
<div class="msgpart">
|
||||
<% if @mail.attachments and @mail.attachments.size > 0%>
|
||||
<table class="attachments">
|
||||
<% i = 0
|
||||
@mail.attachments.each { |att| %>
|
||||
<tr><td><%=attachment(att, i)%></td></tr>
|
||||
<% i = i + 1
|
||||
}%>
|
||||
</table>
|
||||
<% end %>
|
||||
<hr/>
|
||||
<label for="attachment"><%=_('Attachment')%>:</label><%=%><input type="file" name="attachment"/>
|
||||
<input type="button" name="mail_add_attachement" value="<%=_('Add')%>"
|
||||
onclick="getFormField('mail_op').value='<%=_('Add')%>';getFormField('composeMail').submit();">
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</form>
|
||||
|
||||
<% content_for("scripts") { %>
|
||||
<%= @additional_scripts %>
|
||||
<% if ['text/html', 'multipart'].include?(@mail.content_type) %>
|
||||
<%= include_tinymce %>
|
||||
<% end %>
|
||||
<%= javascript_include_tag "controls" %>
|
||||
<%= javascript_include_tag "dragdrop" %>
|
||||
<%= javascript_include_tag "effects" %>
|
||||
<% %>
|
||||
<% } %>
|
28
components/webmail/webmail/error_connection.rhtml
Normal file
28
components/webmail/webmail/error_connection.rhtml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><span><%= _('Folders') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_refresh%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<% content_for('sidebar') { %>
|
||||
<div id="folders">
|
||||
<h4><%=_('Folders')%><br/><%=link_manage_folders%></h4>
|
||||
<hr/>
|
||||
<%=_('Error occured obtaining connection to mail server. Please excuse us!')%>
|
||||
</div>
|
||||
<% } %>
|
||||
<div id="messages">
|
||||
</div>
|
||||
|
||||
</div></div>
|
41
components/webmail/webmail/filter.rhtml
Normal file
41
components/webmail/webmail/filter.rhtml
Normal file
|
@ -0,0 +1,41 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><span><%= _('Filters') %></span></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<div id="filters">
|
||||
<form action="/webmail/webmail/filter" method="post">
|
||||
<%=hidden_field 'filter', 'id' %>
|
||||
<table class="list" width='100%'>
|
||||
<tr>
|
||||
<td><label for="filter[name]"><%=_('Filter name')%></label></td>
|
||||
<td colspan='3'><%=text_field 'filter', 'name' %></td>
|
||||
</tr>
|
||||
<tr><td colspan="4"><%=_('Messages matching')%></td></tr>
|
||||
<%= render_partial_collection "expr", @expressions %>
|
||||
<tr><td colspan="4"><input type="submit" name="op" value="<%=_('Add')%>"/></td></tr>
|
||||
<tr>
|
||||
<td><label for="filter[destination_folder]"><%=_('Will be placed in')%></label></td>
|
||||
<td colspan='3'>
|
||||
<select name="filter[destination_folder]">
|
||||
<%= options_from_collection_for_select(@destfolders, 'name', 'name', @filter.destination_folder) %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="4">
|
||||
<input type="submit" name="op" value="<%=_('Save')%>"/>
|
||||
<input type="button" name="op" value="<%=_('Cancel')%>" onclick="changeLoc('/webmail/webmail/filters');"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div></div>
|
39
components/webmail/webmail/filters.rhtml
Normal file
39
components/webmail/webmail/filters.rhtml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><span><%= _('Filters') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_filter_add%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<div id="filters">
|
||||
<form action="/webmail/webmail/filters" method="post">
|
||||
<% if @user.filters and @user.filters.size > 0 %>
|
||||
<table class="list">
|
||||
<tr>
|
||||
<th><%=_('Filter name')%></th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
<%= render_partial_collection "filter", @user.filters %>
|
||||
</table>
|
||||
<% end %>
|
||||
</form>
|
||||
<% if @flash['error'] %>
|
||||
<div id="SystemError"><%= @flash['error'] %></div>
|
||||
<% elsif @flash['status'] %>
|
||||
<div id="SystemStatus"><%= @flash['status'] %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div></div>
|
35
components/webmail/webmail/folders.rhtml
Normal file
35
components/webmail/webmail/folders.rhtml
Normal file
|
@ -0,0 +1,35 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><span><%= _('Folders') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_refresh%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<% content_for('sidebar') { %>
|
||||
<div id="folders">
|
||||
<h4><%=_('Folders')%><br/><%=link_manage_folders%></h4>
|
||||
<hr/>
|
||||
<ul> <% for folder in @folders %>
|
||||
<li><%=folder_link(folder)%></li> <% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% } %>
|
||||
<div id="messages">
|
||||
<% if not(@request['msg_id'] == '') %>
|
||||
<%= render_component(:controller => "webmail/webmail", :action => "message", :params => { 'msg_id' => @request['msg_id']})%>
|
||||
<% else %>
|
||||
<%= render_component(:controller => "webmail/webmail", :action => "messages") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div></div>
|
31
components/webmail/webmail/mailsent.rhtml
Normal file
31
components/webmail/webmail/mailsent.rhtml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><span><%= _('Compose') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_compose_new%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<div class="msghdr">
|
||||
<dl>
|
||||
<dt><%=_('To')%></dt><dd><%= CGI.escapeHTML(@mail.to) %></dd>
|
||||
<% if @mail.cc %>
|
||||
<dt><%=_('CC')%></dt><dd><%= CGI.escapeHTML(@mail.cc) %></dd>
|
||||
<% end
|
||||
if @mail.bcc %>
|
||||
<dt><%=_('BCC')%></dt><dd><%= CGI.escapeHTML(@mail.bcc) %></dd>
|
||||
<% end %>
|
||||
<dt><%=_('Subject')%></dt><dd><%= CGI.escapeHTML(@mail.subject) %></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
48
components/webmail/webmail/manage_folders.rhtml
Normal file
48
components/webmail/webmail/manage_folders.rhtml
Normal file
|
@ -0,0 +1,48 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><span><%= _('Folders') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_back_to_messages%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<% content_for('sidebar') { %>
|
||||
<div id="folders">
|
||||
<h4><%=_('Add folder')%></h4>
|
||||
<hr/>
|
||||
<form action="/webmail/webmail/manage_folders" method="post">
|
||||
<ul>
|
||||
<li><label for='folder_name'><%=_('Name')%>:</label></li>
|
||||
<li><input type="text" name="folder_name" value="" size="18" id='folder_name'/></li>
|
||||
<li><input type="submit" name="op" value="<%=_('Add folder')%>"/></li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div id="messages">
|
||||
<div id='msg-fl-list'>
|
||||
<table>
|
||||
<thead><tr><th><%=_('Folder')%></th><th><%= _('Total messages') %></th><th><%= _('Unseen') %></th></tr></thead>
|
||||
<tbody>
|
||||
<% for folder in @folders %>
|
||||
<tr>
|
||||
<td><%=folder_manage_link(folder)%></td>
|
||||
<td><%= folder.total %></td>
|
||||
<td><%= folder.unseen > 0 ? "<b>#{folder.unseen}</b>" : "#{folder.unseen}" %></td></tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
48
components/webmail/webmail/message.rhtml
Normal file
48
components/webmail/webmail/message.rhtml
Normal file
|
@ -0,0 +1,48 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><span><%= _('Folders') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_refresh%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<% content_for('sidebar') { %>
|
||||
<div id="folders">
|
||||
<h4><%=_('Folders')%><br/><%=link_manage_folders%></h4>
|
||||
<hr/>
|
||||
<ul> <% for folder in @folders %>
|
||||
<li><%=folder_link(folder)%></li> <% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% } %>
|
||||
<div id="messages">
|
||||
|
||||
<div id="msgshow">
|
||||
<div id="topmenu">
|
||||
<ul class="actionmenu">
|
||||
<li>
|
||||
<%= link_to(_("« Back to list"), :controller=>"/webmail/webmail", :action=>"messages") %>
|
||||
</li>
|
||||
<li><%=link_reply_to_sender(@msg_id)%></li>
|
||||
<li><%=link_forward_message(@msg_id)%></li>
|
||||
<li><%=link_flag_for_deletion(@msg_id)%></li>
|
||||
<li><%=link_view_source(@msg_id)%></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<%= mail2html(@mail, @msg_id) %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div></div>
|
||||
|
89
components/webmail/webmail/messages.rhtml
Normal file
89
components/webmail/webmail/messages.rhtml
Normal file
|
@ -0,0 +1,89 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><span><%= _('Folders') %></span>
|
||||
<ul id="secondary">
|
||||
<li><%=link_refresh%></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><%=link_mail_prefs%></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
|
||||
<% content_for('sidebar') { %>
|
||||
<div id="folders">
|
||||
<h4><%=_('Folders')%><br/><%=link_manage_folders%></h4>
|
||||
<hr/>
|
||||
<ul> <% for folder in @folders %>
|
||||
<li><%=folder_link(folder)%></li> <% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 10px;">
|
||||
<input type="button" value="<%= _('Logout')%>" onclick="window.location='/login/logout'">
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div id="messages">
|
||||
<div id="msglist">
|
||||
<h2><%= @folder_name %></h2>
|
||||
<%= start_form_tag({:controller=>'/webmail/webmail', :action=>'messages'})%>
|
||||
<div class='notviscode'><input type="submit" name="op" value="<%=_('Search')%>" /></div>
|
||||
<input type="hidden" name="page" value="<%=@page%>"/>
|
||||
|
||||
<a href='#' onclick='toggle_msg_operations(true);'>
|
||||
<%=_('Operations')%><img id='img_msgops' alt='open' src='/images/list_<%=@ops_img_src%>.gif'/>
|
||||
</a>
|
||||
|
||||
<div id="msgops" class='<%=@ops_class%>'>
|
||||
<h4><%=_('Operations on marked messages')%></h4>
|
||||
<span id="opch">
|
||||
<%= submit_tag(_('delete'), :name=>'op')%>
|
||||
<%= submit_tag(_('copy'), :name=> 'op')%>
|
||||
<%= submit_tag(_('move'), :name=>'op')%>
|
||||
<%= submit_tag(_('mark read'), :name=>'op')%>
|
||||
<%= submit_tag(_('mark unread'), :name=>'op')%>
|
||||
</span><br/>
|
||||
<span id="destp">
|
||||
<%=_('Destination for move and copy operations')%>
|
||||
<select name="cpdest" size="1">
|
||||
<% for folder in @folders %>
|
||||
<option value="<%=folder.name%>"><%=folder.name%></option>
|
||||
<% end %>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
<%= render_partial "search" %>
|
||||
<%= page_navigation_webmail @pages if @pages.page_count > 1 %>
|
||||
<table width='98%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="1%"><input type="checkbox" name="allbox" onclick="checkAll(this.form)" style="margin: 0 0 0 4px" /></th>
|
||||
<% if @folder_name == CDF::CONFIG[:mail_sent] %>
|
||||
<th width="20%"><%= link_to(_('To'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'to_flat')%></th>
|
||||
<% else %>
|
||||
<th width="20%"><%= link_to(_('From'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'from_flat')%></th>
|
||||
<% end%>
|
||||
<th width='60%'><%= link_to(_('Subject'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'subject')%></th>
|
||||
<th><%= link_to(_('Date'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'date')%></th>
|
||||
<th><%= link_to(_('Size'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'size')%></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for message in @messages %>
|
||||
<%= render_partial 'webmail/webmail/message_row', message %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<%= page_navigation_webmail @pages if @pages.page_count > 1 %>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
1
components/webmail/webmail/noattachment.rhtml
Normal file
1
components/webmail/webmail/noattachment.rhtml
Normal file
|
@ -0,0 +1 @@
|
|||
No attachment found!
|
52
components/webmail/webmail/prefs.rhtml
Normal file
52
components/webmail/webmail/prefs.rhtml
Normal file
|
@ -0,0 +1,52 @@
|
|||
<h1><%=_('Mailbox')%></h1>
|
||||
<div id="header">
|
||||
<ul id="primary">
|
||||
<li><%=link_folders%></li>
|
||||
<li><%=link_send_mail%></li>
|
||||
<li><span><%= _('Preferences') %></span></li>
|
||||
<li><%=link_mail_filters%></li>
|
||||
<li><%=link_main%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tab_main">
|
||||
<div id="tab_content">
|
||||
<div id="prefs">
|
||||
<form action="/webmail/webmail/prefs" method="post">
|
||||
<%= hidden_field "mailpref", "id" %>
|
||||
<%= hidden_field "mailpref", "customer_id" %>
|
||||
<table class="edit">
|
||||
<%= form_input(:text_field, 'customer', 'fname', _('First name'), 'class'=>'two_columns') %>
|
||||
<%= form_input(:text_field, 'customer', 'lname', _('Last name'), 'class'=>'two_columns') %>
|
||||
<tr class="two_rows">
|
||||
<td><label><%=_('Send type message')%></label></td>
|
||||
<td><select name="mailpref[mail_type]">
|
||||
<%= options_for_select(CDF::CONFIG[:mail_send_types], @mailpref.mail_type)%>
|
||||
</select></td>
|
||||
</tr>
|
||||
|
||||
<tr class="two_rows">
|
||||
<td><label><%=_('Messages per page')%></label></td>
|
||||
<td><select name="mailpref[wm_rows]">
|
||||
<%= options_for_select(CDF::CONFIG[:mail_message_rows], @mailpref.wm_rows)%>
|
||||
</select></td>
|
||||
</tr>
|
||||
|
||||
<tr class="two_rows">
|
||||
<td><label for="mailpref_check_external_mail"><%=_('Check external mail?')%></label></td>
|
||||
<td>
|
||||
<%=check_box('mailpref', 'check_external_mail')%>
|
||||
<%=_('Note that by selecting this option webmail system will try to log you using your original email on a local server.')%>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="two_rows">
|
||||
<td colspan='2' class="buttonBar">
|
||||
<input type="submit" name="op" value="<%=_('Save')%>"/>
|
||||
<input type="button" value="<%=_('Cancel')%>" onclick="window.location='/webmail/webmail/folders'"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
13
components/webmail/webmail/view_source.rhtml
Normal file
13
components/webmail/webmail/view_source.rhtml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><%=_('Mailr')%></title>
|
||||
<link rel="stylesheet" href="/stylesheets/webmail/webmail.css" type="text/css" media="screen" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="msg_source">
|
||||
<%=@msg_source%>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
494
components/webmail/webmail_controller.rb
Normal file
494
components/webmail/webmail_controller.rb
Normal file
|
@ -0,0 +1,494 @@
|
|||
require 'cdfmail'
|
||||
require 'net/smtp'
|
||||
require 'net/imap'
|
||||
require 'mail2screen'
|
||||
require 'ezcrypto'
|
||||
|
||||
class Webmail::WebmailController < ApplicationController
|
||||
uses_component_template_root
|
||||
|
||||
# Administrative functions
|
||||
before_filter :login_required
|
||||
|
||||
before_filter :obtain_cookies_for_search_and_nav, :only=>[:messages]
|
||||
|
||||
layout "public", :except => [:view_source, :download]
|
||||
|
||||
before_filter :load_imap_session
|
||||
|
||||
after_filter :close_imap_session
|
||||
|
||||
model :filter, :expression, :mail_pref, :customer
|
||||
|
||||
BOOL_ON = "on"
|
||||
|
||||
def index
|
||||
redirect_to(:action=>"messages")
|
||||
end
|
||||
|
||||
def error_connection
|
||||
end
|
||||
|
||||
def refresh
|
||||
@mailbox.reload
|
||||
@folders = @mailbox.folders
|
||||
redirect_to(:action=>'messages')
|
||||
end
|
||||
|
||||
def manage_folders
|
||||
if operation_param == _('Add folder')
|
||||
@mailbox.create_folder(CDF::CONFIG[:mail_inbox]+"."+@params["folder_name"])
|
||||
elsif operation_param == _('(Delete)')
|
||||
@mailbox.delete_folder(@params["folder_name"])
|
||||
elsif operation_param == _('(Subscribe)')
|
||||
elsif operation_param == _('(Select)')
|
||||
end
|
||||
@folders = @mailbox.folders
|
||||
end
|
||||
|
||||
def messages
|
||||
@session["return_to"] = nil
|
||||
@search_field = @params['search_field']
|
||||
@search_value = @params['search_value']
|
||||
|
||||
# handle sorting - tsort session field contains last reverse or no for field
|
||||
# and lsort - last sort field
|
||||
if @session['tsort'].nil? or @session['lsort'].nil?
|
||||
@session['lsort'] = "DATE"
|
||||
@session['tsort'] = {"DATE" => true, "FROM" => true, "SUBJECT" => true, "TO" => false}
|
||||
end
|
||||
|
||||
case operation_param
|
||||
when _('copy') # copy
|
||||
msg_ids = []
|
||||
messages_param.each { |msg_id, bool|
|
||||
msg_ids << msg_id.to_i if bool == BOOL_ON and dst_folder != @folder_name } if messages_param
|
||||
folder.copy_multiple(msg_ids, dst_folder) if msg_ids.size > 0
|
||||
when _('move') # move
|
||||
msg_ids = []
|
||||
messages_param.each { |msg_id, bool|
|
||||
msg_ids << msg_id.to_i if bool == BOOL_ON and dst_folder != @folder_name } if messages_param
|
||||
folder.move_multiple(msg_ids, dst_folder) if msg_ids.size > 0
|
||||
when _('delete') # delete
|
||||
msg_ids = []
|
||||
messages_param.each { |msg_id, bool| msg_ids << msg_id.to_i if bool == BOOL_ON } if messages_param
|
||||
folder.delete_multiple(msg_ids) if msg_ids.size > 0
|
||||
when _('mark read') # mark as read
|
||||
messages_param.each { |msg_id, bool| msg = folder.mark_read(msg_id.to_i) if bool == BOOL_ON } if messages_param
|
||||
when _('mark unread') # mark as unread
|
||||
messages_param.each { |msg_id, bool| msg = folder.mark_unread(msg_id.to_i) if bool == BOOL_ON } if messages_param
|
||||
when "SORT"
|
||||
@session['lsort'] = sort_query = @params["scc"]
|
||||
@session['tsort'][sort_query] = (@session['tsort'][sort_query]? false : true)
|
||||
@search_field, @search_value = @session['search_field'], @session['search_value']
|
||||
when _('Search') # search
|
||||
@session['search_field'] = @search_field
|
||||
@session['search_value'] = @search_value
|
||||
when _('Show all') # search
|
||||
@session['search_field'] = @search_field = nil
|
||||
@session['search_value'] = @search_value = nil
|
||||
else
|
||||
# get search criteria from session
|
||||
@search_field = @session['search_field']
|
||||
@search_value = @session['search_value']
|
||||
end
|
||||
|
||||
sort_query = @session['lsort']
|
||||
reverse_sort = @session['tsort'][sort_query]
|
||||
query = ["ALL"]
|
||||
@page = @params["page"]
|
||||
@page ||= @session['page']
|
||||
@session['page'] = @page
|
||||
if @search_field and @search_value and not(@search_field.strip() == "") and not(@search_value.strip() == "")
|
||||
@pages = Paginator.new self, 0, get_mail_prefs.wm_rows, @page
|
||||
@messages = folder.messages_search([@search_field, @search_value], sort_query + (reverse_sort ? ' desc' : ' asc'))
|
||||
else
|
||||
@pages = Paginator.new self, folder.total, get_mail_prefs.wm_rows, @page
|
||||
@messages = folder.messages(@pages.current.first_item - 1, get_mail_prefs.wm_rows, sort_query + (reverse_sort ? ' desc' : ' asc'))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def delete
|
||||
@msg_id = msg_id_param.to_i
|
||||
folder.messages().delete(@msg_id)
|
||||
redirect_to(:action=>"messages")
|
||||
end
|
||||
|
||||
def reply # not ready at all
|
||||
@msg_id = msg_id_param.to_i
|
||||
@imapmail = folder.message(@msg_id)
|
||||
fb = @imapmail.full_body
|
||||
@tmail = TMail::Mail.parse(fb)
|
||||
|
||||
@mail = prepare_mail
|
||||
@mail.reply(@tmail, fb, get_mail_prefs.mail_type)
|
||||
|
||||
render_action("compose")
|
||||
end
|
||||
|
||||
def forward
|
||||
@msg_id = msg_id_param.to_i
|
||||
@imapmail = folder.message(@msg_id)
|
||||
fb = @imapmail.full_body
|
||||
@tmail = TMail::Mail.parse(fb)
|
||||
|
||||
@mail = prepare_mail
|
||||
@mail.forward(@tmail, fb)
|
||||
|
||||
render_action("compose")
|
||||
end
|
||||
|
||||
def compose
|
||||
if @mail.nil?
|
||||
operation = operation_param
|
||||
if operation == _('Send')
|
||||
@mail = create_mail
|
||||
encmail = @mail.send_mail
|
||||
get_imap_session
|
||||
@mailbox.message_sent(encmail)
|
||||
|
||||
# delete temporary files (attachments)
|
||||
@mail.delete_attachments()
|
||||
return render("webmail/webmail/mailsent")
|
||||
elsif operation == _('Add')
|
||||
@mail = create_mail
|
||||
attachment = CDF::Attachment.new(@mail)
|
||||
attachment.file = @params['attachment']
|
||||
else
|
||||
# default - new email create
|
||||
@mail = create_mail
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def empty # empty trash folder (works for any one else :-))
|
||||
folder.messages(0, -1).each{ |message|
|
||||
folder.delete(message)
|
||||
}
|
||||
folder.expunge
|
||||
redirect_to(:action=>"messages")
|
||||
end
|
||||
|
||||
def message
|
||||
@msg_id = msg_id_param
|
||||
@imapmail = folder.message(@msg_id)
|
||||
folder.mark_read(@imapmail.uid) if @imapmail.unread
|
||||
@mail = TMail::Mail.parse(@imapmail.full_body)
|
||||
end
|
||||
|
||||
def download
|
||||
msg_id = msg_id_param
|
||||
imapmail = folder.message(msg_id)
|
||||
mail = TMail::Mail.parse(imapmail.full_body)
|
||||
|
||||
if mail.multipart?
|
||||
get_parts(mail).each { |part|
|
||||
return send_part(part) if part.header and part.header['content-type']['name'] == @params['ctype']
|
||||
}
|
||||
render("webmail/webmail/noattachment")
|
||||
else
|
||||
render("webmail/webmail/noattachment")
|
||||
end
|
||||
end
|
||||
|
||||
def prefs
|
||||
@customer = Customer.find(logged_customer)
|
||||
if not(@mailpref = MailPref.find_by_customer(logged_customer))
|
||||
@mailpref = MailPref.create("customer_id"=>logged_customer)
|
||||
end
|
||||
|
||||
if @params['op'] == _('Save')
|
||||
if @params['customer']
|
||||
@customer.fname = @params['customer']['fname']
|
||||
@customer.lname = @params['customer']['lname']
|
||||
@customer.save
|
||||
end
|
||||
@mailpref.attributes = @params["mailpref"]
|
||||
@mailpref.save
|
||||
@session["wmimapseskey"] = nil
|
||||
redirect_to(:action=>"messages")
|
||||
end
|
||||
end
|
||||
|
||||
# Message filters management
|
||||
def filters
|
||||
end
|
||||
|
||||
def filter
|
||||
if @params['op']
|
||||
@filter = Filter.new(@params['filter'])
|
||||
@filter.customer_id = logged_customer
|
||||
@params['expression'].each { |index, expr| @filter.expressions << Expression.new(expr) unless expr["expr_value"].nil? or expr["expr_value"].strip == "" }
|
||||
case @params['op']
|
||||
when _('Add')
|
||||
@filter.expressions << Expression.new
|
||||
when _('Save')
|
||||
if @params['filter']['id'] and @params['filter']['id'] != ""
|
||||
@sf = Filter.find(@params['filter']['id'])
|
||||
@sf.name, @sf.destination_folder = @filter.name, @filter.destination_folder
|
||||
@sf.expressions.each{|expr| Expression.delete(expr.id) }
|
||||
@filter.expressions.each {|expr| @sf.expressions << Expression.create(expr.attributes) }
|
||||
else
|
||||
@sf = Filter.create(@filter.attributes)
|
||||
@sf.order_num = @user.filters.size
|
||||
@filter.expressions.each {|expr| @sf.expressions << Expression.create(expr.attributes) }
|
||||
end
|
||||
# may be some validation will be needed
|
||||
@sf.save
|
||||
@user.serialize_to_file
|
||||
return redirect_to(:action=>"filters")
|
||||
end
|
||||
@expressions = @filter.expressions
|
||||
else
|
||||
@filter = Filter.find(@params["id"]) if @params["id"]
|
||||
@expressions = @filter.expressions
|
||||
end
|
||||
@destfolders = get_to_folders
|
||||
end
|
||||
|
||||
def filter_delete
|
||||
Filter.delete(@params["id"])
|
||||
# reindex other filters
|
||||
@user = Customer.find(logged_customer)
|
||||
findex = 0
|
||||
@user.filters.each { |filter|
|
||||
findex = findex + 1
|
||||
filter.order_num = findex
|
||||
filter.save
|
||||
}
|
||||
@user.serialize_to_file
|
||||
redirect_to :action=>"filters"
|
||||
end
|
||||
|
||||
def filter_up
|
||||
filt = @user.filters.find(@params['id'])
|
||||
ufilt = @user.filters.find_all("order_num = #{filt.order_num - 1}").first
|
||||
ufilt.order_num = ufilt.order_num + 1
|
||||
filt.order_num = filt.order_num - 1
|
||||
ufilt.save
|
||||
filt.save
|
||||
@user.serialize_to_file
|
||||
redirect_to :action=>"filters"
|
||||
end
|
||||
|
||||
def filter_down
|
||||
filt = Filter.find(@params["id"])
|
||||
dfilt = @user.filters[filt.order_num]
|
||||
dfilt.order_num = dfilt.order_num - 1
|
||||
filt.order_num = filt.order_num + 1
|
||||
dfilt.save
|
||||
filt.save
|
||||
@user.serialize_to_file
|
||||
redirect_to :action=>"filters"
|
||||
end
|
||||
|
||||
def filter_add
|
||||
@filter = Filter.new
|
||||
@filter.expressions << Expression.new
|
||||
@expressions = @filter.expressions
|
||||
@destfolders = get_to_folders
|
||||
render_action("filter")
|
||||
end
|
||||
# end of filters
|
||||
|
||||
def view_source
|
||||
@msg_id = msg_id_param.to_i
|
||||
@imapmail = folder.message(@msg_id)
|
||||
@msg_source = CGI.escapeHTML(@imapmail.full_body).gsub("\n", "<br/>")
|
||||
end
|
||||
|
||||
def auto_complete_for_mail_to
|
||||
auto_complete_responder_for_contacts params[:mail][:to]
|
||||
end
|
||||
|
||||
def auto_complete_for_mail_cc
|
||||
auto_complete_responder_for_contacts params[:mail][:cc]
|
||||
end
|
||||
|
||||
def auto_complete_for_mail_bcc
|
||||
auto_complete_responder_for_contacts params[:mail][:bcc]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def auto_complete_responder_for_contacts(value)
|
||||
# first split by "," and take last name
|
||||
searchName = value.split(',').last.strip
|
||||
|
||||
# if there are 2 names search by them
|
||||
if searchName.split.size > 1
|
||||
fname, lname = searchName.split.first, searchName.split.last
|
||||
conditions = ['customer_id = ? and LOWER(fname) LIKE ? and LOWER(lname) like ?', logged_customer, fname.downcase + '%', lname.downcase + '%']
|
||||
else
|
||||
conditions = ['customer_id = ? and LOWER(fname) LIKE ?', logged_customer, searchName.downcase + '%']
|
||||
end
|
||||
@contacts = Contact.find(:all, :conditions => conditions, :order => 'fname ASC',:limit => 8)
|
||||
render :partial => 'contacts'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def additional_scripts()
|
||||
'<link rel="stylesheet" href="/stylesheets/webmail/webmail.css" type="text/css" media="screen" />'<<
|
||||
'<script type="text/javascript" src="/javascripts/webmail.js"></script>'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_upass
|
||||
if CDF::CONFIG[:crypt_session_pass]
|
||||
EzCrypto::Key.decrypt_with_password(CDF::CONFIG[:encryption_password], CDF::CONFIG[:encryption_salt], @session["wmp"])
|
||||
else
|
||||
# retrun it plain
|
||||
@session["wmp"]
|
||||
end
|
||||
end
|
||||
|
||||
def get_to_folders
|
||||
res = Array.new
|
||||
@folders.each{|f| res << f unless f.name == CDF::CONFIG[:mail_sent] or f.name == CDF::CONFIG[:mail_inbox] }
|
||||
res
|
||||
end
|
||||
|
||||
def load_imap_session
|
||||
return if ['compose', 'prefs', 'error_connection'].include?(action_name)
|
||||
get_imap_session
|
||||
end
|
||||
|
||||
def get_imap_session
|
||||
begin
|
||||
@mailbox = IMAPMailbox.new
|
||||
uname = (get_mail_prefs.check_external_mail == 1 ? user.email : user.local_email)
|
||||
upass = get_upass
|
||||
@mailbox.connect(uname, upass)
|
||||
load_folders
|
||||
rescue Exception => ex
|
||||
logger.error("Exception on loggin webmail session - #{ex} - #{ex.backtrace.join("\t\n")}")
|
||||
render_action "error_connection"
|
||||
end
|
||||
end
|
||||
|
||||
def close_imap_session
|
||||
return if @mailbox.nil? or not(@mailbox.connected)
|
||||
@mailbox.disconnect
|
||||
@mailbox = nil
|
||||
end
|
||||
|
||||
def have_to_load_folders?
|
||||
return true if ['messages', 'delete', 'reply', 'forward', 'empty', 'message', 'download',
|
||||
'filter', 'filter_add', 'view_source'].include?(action_name)
|
||||
return false
|
||||
end
|
||||
|
||||
def load_folders
|
||||
if have_to_load_folders?()
|
||||
if @params["folder_name"]
|
||||
@folder_name = @params["folder_name"]
|
||||
else
|
||||
@folder_name = @session["folder_name"] ? @session["folder_name"] : CDF::CONFIG[:mail_inbox]
|
||||
end
|
||||
@session["folder_name"] = @folder_name
|
||||
@folders = @mailbox.folders if @folders.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def create_mail
|
||||
m = CDF::Mail.new(user.mail_temporary_path)
|
||||
if @params["mail"]
|
||||
ma = @params["mail"]
|
||||
m.body, m.content_type, m.from, m.to, m.cc, m.bcc, m.subject = ma["body"], ma["content_type"], ma["from"], ma["to"], ma["cc"], ma["bcc"], ma["subject"]
|
||||
if @params["att_files"]
|
||||
att_files, att_tfiles, att_ctypes = @params["att_files"], @params["att_tfiles"], @params["att_ctypes"]
|
||||
att_files.each {|i, value|
|
||||
att = CDF::Attachment.new(m)
|
||||
att.filename, att.temp_filename, att.content_type = value, att_tfiles[i], att_ctypes[i]
|
||||
}
|
||||
end
|
||||
else
|
||||
m.from, m.content_type = user.friendlly_local_email, get_mail_prefs.mail_type
|
||||
end
|
||||
m.customer_id = logged_customer
|
||||
m
|
||||
end
|
||||
|
||||
def prepare_mail
|
||||
m = CDF::Mail.new(user.mail_temporary_path)
|
||||
m.from, m.content_type = user.friendlly_local_email, get_mail_prefs.mail_type
|
||||
m
|
||||
end
|
||||
|
||||
def user
|
||||
@user = Customer.find(logged_customer) if @user.nil?
|
||||
@user
|
||||
end
|
||||
|
||||
def get_mail_prefs
|
||||
if not(@mailprefs)
|
||||
if not(@mailprefs = MailPref.find_by_customer(logged_customer))
|
||||
@mailprefs = MailPref.create("customer_id"=>logged_customer)
|
||||
end
|
||||
end
|
||||
@mailprefs
|
||||
end
|
||||
|
||||
def send_part(part)
|
||||
if part.content_type == "text/html"
|
||||
disposition = "inline"
|
||||
elsif part.content_type.include?("image/")
|
||||
disposition = "inline"
|
||||
else
|
||||
disposition = "attachment"
|
||||
end
|
||||
@headers['Content-Length'] = part.body.size
|
||||
@response.headers['Accept-Ranges'] = 'bytes'
|
||||
@headers['Content-type'] = part.content_type.strip
|
||||
@headers['Content-Disposition'] = disposition << %(; filename="#{part.header['content-type']['name']}")
|
||||
render_text part.body
|
||||
end
|
||||
|
||||
def get_parts(mail)
|
||||
parts = Array.new
|
||||
parts << mail
|
||||
mail.parts.each { |part|
|
||||
if part.multipart?
|
||||
parts = parts.concat(get_parts(part))
|
||||
elsif part.content_type and part.content_type.include?("rfc822")
|
||||
parts = parts.concat(get_parts(TMail::Mail.parse(part.body))) << part
|
||||
else
|
||||
parts << part
|
||||
end
|
||||
}
|
||||
parts
|
||||
end
|
||||
|
||||
def obtain_cookies_for_search_and_nav
|
||||
@srch_class = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'open')
|
||||
@srch_img_src = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'opened')
|
||||
@ops_class = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'open')
|
||||
@ops_img_src = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'opened')
|
||||
end
|
||||
|
||||
###################################################################
|
||||
### Some fixed parameters and session variables
|
||||
###################################################################
|
||||
def folder
|
||||
@folders[@folder_name]
|
||||
end
|
||||
|
||||
def msg_id_param
|
||||
@params["msg_id"]
|
||||
end
|
||||
|
||||
def messages_param
|
||||
@params["messages"]
|
||||
end
|
||||
|
||||
def dst_folder
|
||||
@params["cpdest"]
|
||||
end
|
||||
|
||||
def operation_param
|
||||
@params["op"]
|
||||
end
|
||||
end
|
211
components/webmail/webmail_helper.rb
Normal file
211
components/webmail/webmail_helper.rb
Normal file
|
@ -0,0 +1,211 @@
|
|||
require 'cdfutils'
|
||||
require 'mail2screen'
|
||||
|
||||
module Webmail::WebmailHelper
|
||||
include Mail2Screen
|
||||
def link_folders
|
||||
link_to(_('Folders'), :controller=>"/webmail/webmail", :action=>"messages")
|
||||
end
|
||||
|
||||
def link_send_mail
|
||||
link_to(_('Compose'), :controller=>"/webmail/webmail", :action=>"compose")
|
||||
end
|
||||
|
||||
def link_compose_new
|
||||
link_to(_('Compose new mail'), :controller=>"/webmail/webmail", :action=>"compose")
|
||||
end
|
||||
|
||||
def link_refresh
|
||||
link_to(_('Refresh'), :controller=>"/webmail/webmail", :action=>"refresh")
|
||||
end
|
||||
|
||||
def link_message_list
|
||||
link_to(_('Message list'), :controller=>"/webmail/webmail", :action=>"messages")
|
||||
end
|
||||
|
||||
def link_reply_to_sender(msg_id)
|
||||
link_to(_('Reply'), :controller=>"/webmail/webmail", :action=>"reply", :params=>{"msg_id"=>msg_id})
|
||||
end
|
||||
|
||||
def link_forward_message(msg_id)
|
||||
link_to(_('Forward'), :controller=>"/webmail/webmail", :action=>"forward", :params=>{"msg_id"=>msg_id})
|
||||
end
|
||||
|
||||
def link_flag_for_deletion(msg_id)
|
||||
link_to(_('Delete'), :controller=>"/webmail/webmail", :action=>"delete", :params=>{"msg_id"=>msg_id})
|
||||
end
|
||||
|
||||
def link_view_source(msg_id)
|
||||
link_to(_('View source'), {:controller=>"/webmail/webmail", :action=>"view_source", :params=>{"msg_id"=>msg_id}}, {'target'=>"_blank"})
|
||||
end
|
||||
|
||||
def link_manage_folders
|
||||
link_to(_('add/edit'), :controller=>"/webmail/webmail", :action=>"manage_folders")
|
||||
end
|
||||
|
||||
def link_back_to_messages
|
||||
link_to("«" << _('Back to messages'), :controller=>"/webmail/webmail", :action=>"messages")
|
||||
end
|
||||
|
||||
def link_mail_prefs
|
||||
link_to(_('Preferences'), :controller=>"/webmail/webmail", :action=>"prefs")
|
||||
end
|
||||
|
||||
def link_mail_filters
|
||||
link_to(_('Filters'), :controller=>"/webmail/webmail", :action=>"filters")
|
||||
end
|
||||
|
||||
def link_filter_add
|
||||
link_to(_('Add filter'), :controller=>'/webmail/webmail', :action=>'filter_add')
|
||||
end
|
||||
|
||||
def folder_link(folder)
|
||||
if folder.attribs.include? :Noselect
|
||||
return folder.name
|
||||
end
|
||||
unseen_messages = folder.unseen
|
||||
if unseen_messages > 0
|
||||
fn = "#{short_fn(folder)} (#{folder.unseen})"
|
||||
else
|
||||
fn = "#{short_fn(folder)}"
|
||||
end
|
||||
if folder.name == CDF::CONFIG[:mail_trash]
|
||||
(unseen_messages > 0 ? "<b>" : "" ) <<
|
||||
link_to( fn, :controller=>"/webmail/webmail", :action=>"messages", :params=>{"folder_name"=>folder.name}) <<
|
||||
" " << link_to(_('(Empty)'), {:controller=>"/webmail/webmail", :action=>"empty", :params=>{"folder_name"=>folder.name}}, :confirm => _('Do you really want to empty trash?')) <<
|
||||
(unseen_messages > 0 ? "</b>" : "" )
|
||||
else
|
||||
(unseen_messages > 0 ? "<b>" : "" ) <<
|
||||
link_to( fn, :controller=>"/webmail/webmail", :action=>"messages", :params=>{"folder_name"=>folder.name}) <<
|
||||
(unseen_messages > 0 ? "</b>" : "" )
|
||||
end
|
||||
end
|
||||
|
||||
def short_fn(folder)
|
||||
if folder.name.include? folder.delim
|
||||
" " + folder.name.split(folder.delim).last
|
||||
else
|
||||
folder.name
|
||||
end
|
||||
end
|
||||
|
||||
def folder_manage_link(folder)
|
||||
if folder.name == CDF::CONFIG[:mail_trash] or folder.name == CDF::CONFIG[:mail_inbox] or folder.name == CDF::CONFIG[:mail_sent]
|
||||
short_fn(folder)
|
||||
else
|
||||
return short_fn(folder) +
|
||||
(" " + link_to(_('(Delete)'), :controller=>"/webmail/webmail", :action=>"manage_folders", :params=>{"op"=>_('(Delete)'), "folder_name"=>folder.name}))
|
||||
end
|
||||
end
|
||||
|
||||
def message_date(datestr)
|
||||
t = Time.now
|
||||
begin
|
||||
if datestr.kind_of?(String)
|
||||
d = (Time.rfc2822(datestr) rescue Time.parse(value)).localtime
|
||||
else
|
||||
d = datestr
|
||||
end
|
||||
if d.day == t.day and d.month == t.month and d.year == t.year
|
||||
d.strftime("%H:%M")
|
||||
else
|
||||
d.strftime("%Y-%m-%d")
|
||||
end
|
||||
rescue
|
||||
begin
|
||||
d = imap2time(datestr)
|
||||
if d.day == t.day and d.month == t.month and d.year == t.year
|
||||
d.strftime("%H:%M")
|
||||
else
|
||||
d.strftime("%Y-%m-%d")
|
||||
end
|
||||
rescue
|
||||
datestr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def attachment(att, index)
|
||||
ret = "#{att.filename}"
|
||||
# todo: add link to delete attachment
|
||||
#ret <<
|
||||
ret << "<input type='hidden' name='att_files[#{index}]' value='#{att.filename}'/>"
|
||||
ret << "<input type='hidden' name='att_tfiles[#{index}]' value='#{att.temp_filename}'/>"
|
||||
ret << "<input type='hidden' name='att_ctypes[#{index}]' value='#{att.content_type}'/>"
|
||||
end
|
||||
|
||||
def link_filter_up(filter_id)
|
||||
link_to(_('Up'), :controller=>"/webmail/webmail", :action=>"filter_up", :id=>filter_id)
|
||||
end
|
||||
|
||||
def link_filter_down(filter_id)
|
||||
link_to(_('Down'), :controller=>"/webmail/webmail", :action=>"filter_down", :id=>filter_id)
|
||||
end
|
||||
|
||||
def link_filter_edit(filter_id)
|
||||
link_to(_('Edit'), :controller=>"/webmail/webmail", :action=>"filter", :id=>filter_id)
|
||||
end
|
||||
|
||||
def link_filter_delete(filter_id)
|
||||
link_to(_('Delete'), :controller=>"/webmail/webmail", :action=>"filter_delete", :id=>filter_id)
|
||||
end
|
||||
|
||||
def page_navigation_webmail(pages)
|
||||
nav = "<p class='paginator'><small>"
|
||||
|
||||
nav << "(#{pages.length} #{_('Pages')}) "
|
||||
|
||||
window_pages = pages.current.window.pages
|
||||
nav << "..." unless window_pages[0].first?
|
||||
for page in window_pages
|
||||
if pages.current == page
|
||||
nav << page.number.to_s << " "
|
||||
else
|
||||
nav << link_to(page.number, :controller=>"/webmail/webmail", :action=>'messages', :page=>page.number) << " "
|
||||
end
|
||||
end
|
||||
nav << "..." unless window_pages[-1].last?
|
||||
nav << " "
|
||||
|
||||
nav << link_to(_('First'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.first.number) << " | " unless @pages.current.first?
|
||||
nav << link_to(_('Prev'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.current.previous.number) << " | " if @pages.current.previous
|
||||
nav << link_to(_('Next'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.current.next.number) << " | " if @pages.current.next
|
||||
nav << link_to(_('Last'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.last.number) << " | " unless @pages.current.last?
|
||||
|
||||
nav << "</small></p>"
|
||||
|
||||
return nav
|
||||
end
|
||||
|
||||
def parse_subject(subject)
|
||||
begin
|
||||
if mime_encoded?(subject)
|
||||
if mime_decode(subject) == ''
|
||||
_('(No subject)')
|
||||
else
|
||||
mime_decode(subject)
|
||||
end
|
||||
else
|
||||
if from_qp(subject) == ''
|
||||
_('(No subject)')
|
||||
else
|
||||
from_qp(subject)
|
||||
end
|
||||
end
|
||||
rescue Exception => ex
|
||||
RAILS_DEFAULT_LOGGER.debug('Exception occured - #{ex}')
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
def message_size(size)
|
||||
if size / (1024*1024) > 0
|
||||
return "#{(size / (1024*1024)).round} MB"
|
||||
elsif size / 1024 > 0
|
||||
return "#{(size / (1024)).round} KB"
|
||||
else
|
||||
return "#{size} B"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue