devel
This commit is contained in:
parent
649dc660df
commit
52b4c63ddb
13 changed files with 287 additions and 107 deletions
|
@ -39,8 +39,7 @@ class MessagesController < ApplicationController
|
|||
(uids_remote-uids_local).each_slice($defaults["imap_fetch_slice"].to_i) do |slice|
|
||||
messages = @mailbox.uid_fetch(slice, ImapMessageModule::IMAPMessage.fetch_attr)
|
||||
messages.each do |m|
|
||||
mess = ImapMessageModule::IMAPMessage.fromImap(m)
|
||||
Message.createForUser(@current_user,@current_folder,mess)
|
||||
Message.createForUser(@current_user,@current_folder,m)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -141,41 +140,50 @@ class MessagesController < ApplicationController
|
|||
@attachments = []
|
||||
@render_as_text = []
|
||||
|
||||
@message = @current_user.messages.find(params[:id])
|
||||
@message = @current_user.messages.find_by_uid(params[:id])
|
||||
@message.update_attributes(:unseen => false)
|
||||
imap_message = @mailbox.fetch_body(@message.uid)
|
||||
parts = imap_message.split(/\r\n\r\n/)
|
||||
@message_header = parts[0]
|
||||
mail = Mail.new(imap_message)
|
||||
@title = mail.subject
|
||||
if mail.multipart?
|
||||
idx = 0
|
||||
mail.parts.each do |part|
|
||||
case part.content_type
|
||||
when /^text\/plain/ then
|
||||
@render_as_text << part.body.raw_source
|
||||
else
|
||||
a = Attachment.new( :message_id => @message.id,
|
||||
:description => part.content_description,
|
||||
:type => part.content_type,
|
||||
:content => part.body.raw_source,
|
||||
:idx => idx
|
||||
)
|
||||
@attachments << a
|
||||
end
|
||||
idx += 1
|
||||
@mail = Mail.new(imap_message)
|
||||
if @mail.multipart?
|
||||
# idx = 0
|
||||
# @mail.parts.each do |part|
|
||||
# a = Attachment.new( :message_id => @message.id,
|
||||
# :description => part.content_description,
|
||||
# :type => part.content_type,
|
||||
# :content => part.body.raw_source,
|
||||
# :encoding => part.content_transfer_encoding,
|
||||
# :idx => idx,
|
||||
# :multipart => part.multipart?
|
||||
# )
|
||||
# logger.custom('a',a.to_s)
|
||||
# if a.isText?
|
||||
# @render_as_text << a.content_normalized
|
||||
# else
|
||||
# @attachments << a
|
||||
# end
|
||||
#
|
||||
# idx += 1
|
||||
# end
|
||||
Attachment.fromPart(@attachments,@message.id,@mail.parts,0)
|
||||
@attachments.each do |a|
|
||||
a.isText? ? @render_as_text << a.content_normalized : @render_as_text
|
||||
end
|
||||
|
||||
else
|
||||
if mail.content_type.nil?
|
||||
@render_as_text << mail.body.raw_source
|
||||
else
|
||||
a = Attachment.new( :message_id => @message.id,
|
||||
:type => mail.content_type,
|
||||
:encoding => mail.body.encoding,
|
||||
:charset => mail.body.charset,
|
||||
:content => mail.body.raw_source,
|
||||
a = Attachment.new( :message_id => @message.id,
|
||||
:description => @mail.content_description,
|
||||
:type => @mail.content_type,
|
||||
:encoding => @mail.body.encoding,
|
||||
:charset => @mail.body.charset,
|
||||
:content => @mail.body.raw_source,
|
||||
:idx => 0
|
||||
)
|
||||
logger.custom('a',a.to_s)
|
||||
if a.isText?
|
||||
@render_as_text << a.content_normalized
|
||||
else
|
||||
@attachments << a
|
||||
end
|
||||
end
|
||||
|
@ -203,6 +211,7 @@ class MessagesController < ApplicationController
|
|||
:description => part.content_description,
|
||||
:type => part.content_type,
|
||||
:content => part.body.raw_source,
|
||||
:encoding => part.content_transfer_encoding,
|
||||
:idx => params[:idx]
|
||||
)
|
||||
else
|
||||
|
@ -216,7 +225,7 @@ class MessagesController < ApplicationController
|
|||
end
|
||||
headers['Content-type'] = a.type
|
||||
headers['Content-Disposition'] = %(attachment; filename="#{a.name}")
|
||||
render :text => a.content_decoded
|
||||
render :text => a.decode
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -13,10 +13,14 @@ class UserController < ApplicationController
|
|||
end
|
||||
|
||||
def authenticate
|
||||
if !$defaults["only_can_logins"].include?(params[:user][:email])
|
||||
redirect_to :controller => 'internal', :action => 'onlycanlogins'
|
||||
return false
|
||||
|
||||
if not $defaults["only_can_logins"].nil?
|
||||
if not $defaults["only_can_logins"].include?(params[:user][:email])
|
||||
redirect_to :controller => 'internal', :action => 'onlycanlogins'
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
user = User.find_by_email(params[:user][:email])
|
||||
if user.nil?
|
||||
redirect_to :action => 'unknown' ,:email=> params[:user][:email]
|
||||
|
|
|
@ -14,15 +14,24 @@ module MessagesHelper
|
|||
date.nil? ? t(:no_data) : date.strftime("%Y-%m-%d %H:%M")
|
||||
end
|
||||
|
||||
def address_formatter(addr)
|
||||
ImapMessageModule::IMAPAddress.parse(addr).friendly
|
||||
end
|
||||
# def address_formatter(addr)
|
||||
# ImapMessageModule::IMAPAddress.parse(addr).friendly
|
||||
# end
|
||||
|
||||
def address_formatter(addr,mode)
|
||||
s = ""
|
||||
length = $defaults["msg_address_length"].to_i
|
||||
fs = addr.split(/</)
|
||||
|
||||
if mode == :index
|
||||
fs[0].size.zero? ? s = fs[1] : s = fs[0]
|
||||
s.length >= length ? s = s[0,length]+"..." : s
|
||||
else
|
||||
fs[0].size.zero? ? s = "<" + fs[1] + ">" : s << fs[0] + " <" + fs[1] + ">"
|
||||
end
|
||||
|
||||
return h(s)
|
||||
|
||||
def show_address_formatter(addr)
|
||||
html = ""
|
||||
fs = addr.split(/#/)
|
||||
fs[0].size.zero? ? html << h("<")+fs[1]+h("@")+fs[2]+h(">") : html << fs[0]+h(" <")+fs[1]+h("@")+fs[2]+h(">")
|
||||
html
|
||||
end
|
||||
|
||||
def subject_formatter(message)
|
||||
|
@ -32,7 +41,7 @@ module MessagesHelper
|
|||
length = $defaults["msg_subject_length"].to_i
|
||||
message.subject.length >= length ? s = message.subject[0,length]+"..." : s = message.subject
|
||||
end
|
||||
link_to s,{:controller => 'messages', :action => 'show', :id => message.id} , :title => message.subject
|
||||
link_to s,{:controller => 'messages', :action => 'show', :id => message.uid} , :title => message.subject
|
||||
end
|
||||
|
||||
def attachment_formatter(message)
|
||||
|
@ -61,8 +70,9 @@ module MessagesHelper
|
|||
end
|
||||
|
||||
def content_text_plain_for_render(text)
|
||||
html = h(text)
|
||||
html.gsub!(/\r\n/,"<br/>")
|
||||
html = "<pre>"
|
||||
html << h(text)
|
||||
html << "</pre>"
|
||||
html
|
||||
end
|
||||
|
||||
|
|
|
@ -3,20 +3,51 @@ class Attachment
|
|||
include ActiveModel::Conversion
|
||||
extend ActiveModel::Naming
|
||||
|
||||
attr_accessor :type, :charset, :encoding, :name, :description, :content, :message_id, :idx
|
||||
attr_accessor :type, :charset, :encoding, :name, :description, :content, :message_id, :idx, :boundary, :format, :multipart
|
||||
attr_reader :link
|
||||
|
||||
def initialize(attributes = {})
|
||||
|
||||
attributes.each do |name, value|
|
||||
send("#{name}=", value)
|
||||
end
|
||||
|
||||
if @type =~ /name=(\S+)/
|
||||
@name = $1
|
||||
@type =~ /^(\S+);/
|
||||
@type = $1
|
||||
else
|
||||
@name = "no_name.dat"
|
||||
if not @type.nil?
|
||||
params = @type.split(/;\s*/)
|
||||
@type = params[0]
|
||||
params.each do |p|
|
||||
if p =~ /=/
|
||||
fields = p.split(/=/)
|
||||
key = fields[0]
|
||||
value = fields[1]
|
||||
if Attachment.attribute_method?(key) == true
|
||||
send("#{key}=", value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def multipart?
|
||||
multipart
|
||||
end
|
||||
|
||||
def self.fromPart(attachments,id,parts,idx)
|
||||
parts.each do |part|
|
||||
a = Attachment.new( :message_id => id,
|
||||
:description => part.content_description,
|
||||
:type => part.content_type,
|
||||
:content => part.body.raw_source,
|
||||
:encoding => part.content_transfer_encoding,
|
||||
:idx => idx,
|
||||
:multipart => part.multipart?
|
||||
)
|
||||
if a.multipart?
|
||||
fromPart(attachments,id,part.parts,idx)
|
||||
else
|
||||
attachments << a
|
||||
end
|
||||
idx += 1
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,6 +55,25 @@ class Attachment
|
|||
false
|
||||
end
|
||||
|
||||
|
||||
|
||||
def name
|
||||
if @name.nil?
|
||||
case type
|
||||
when /^text\/html/
|
||||
"index#{idx}.html"
|
||||
when /^multipart/
|
||||
"multipart#{idx}.part"
|
||||
when /^text\/plain/
|
||||
"file#{idx}.txt"
|
||||
else
|
||||
"filaname.dat"
|
||||
end
|
||||
else
|
||||
@name
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
s = "Attachment:\n"
|
||||
instance_variables.sort.each do |name|
|
||||
|
@ -36,8 +86,12 @@ class Attachment
|
|||
s
|
||||
end
|
||||
|
||||
def isText?
|
||||
@type.nil? or @type =~ /^text\/plain/
|
||||
end
|
||||
|
||||
def title
|
||||
@description.nil? ? @name : @description
|
||||
@description.nil? ? name : @description
|
||||
end
|
||||
|
||||
def type
|
||||
|
@ -52,6 +106,51 @@ class Attachment
|
|||
@encoding.nil? ? '' : @encoding
|
||||
end
|
||||
|
||||
def format
|
||||
@format.nil? ? '' : @format
|
||||
end
|
||||
|
||||
def boundary
|
||||
@boundary.nil? ? '' : @boundary
|
||||
end
|
||||
|
||||
def decode
|
||||
case @encoding
|
||||
when /quoted-printable/
|
||||
decoded = @content.gsub(/_/," ").unpack("M").first
|
||||
when /base64/
|
||||
decoded = @content.unpack("m").first
|
||||
when /uuencode/
|
||||
array = @content.split(/\n/)
|
||||
if array[0] =~ /^begin/
|
||||
size = array.size
|
||||
array.delete_at(size-1)
|
||||
array.delete_at(size-2)
|
||||
array.delete_at(0)
|
||||
end
|
||||
string = array.join
|
||||
decoded = string.unpack("u").first
|
||||
else
|
||||
decoded = @content
|
||||
end
|
||||
end
|
||||
|
||||
def content_normalized
|
||||
|
||||
decoded = decode
|
||||
|
||||
if not @charset == 'UTF-8'
|
||||
@charset.nil? ? charset = $defaults["msg_unknown_encoding"] : charset = @charset
|
||||
charseted = Iconv.iconv("UTF-8",charset,decoded)
|
||||
else
|
||||
charseted = decoded
|
||||
end
|
||||
|
||||
charseted
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
# def to_html
|
||||
# html = "<span class=\"attachment\">"
|
||||
# html << "<span class=\"title\">"
|
||||
|
@ -81,9 +180,4 @@ class Attachment
|
|||
# html
|
||||
# end
|
||||
|
||||
def content_decoded
|
||||
# TODO attachments decoding
|
||||
@content
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,8 +1,47 @@
|
|||
require 'iconv'
|
||||
|
||||
class Message < ActiveRecord::Base
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :folder
|
||||
|
||||
attr_accessor :body
|
||||
set_primary_key :uid
|
||||
attr_accessible :unseen, :to_addr, :size, :content_type, :folder_id, :subject, :date, :uid, :from_addr, :user_id, :msg_id
|
||||
|
||||
def self.decode(text,unknown_encoding = $defaults["msg_unknown_encoding"])
|
||||
begin
|
||||
if text.=~(/^=\?/).nil?
|
||||
after = Iconv.conv('UTF-8',unknown_encoding,text)
|
||||
else
|
||||
f = text.split(/\?/)
|
||||
case f[2].downcase
|
||||
when 'q':
|
||||
after = f[3].gsub(/_/," ").unpack("M").first
|
||||
when 'b':
|
||||
after = f[3].gsub(/_/," ").unpack("m").first
|
||||
else
|
||||
return text
|
||||
end
|
||||
|
||||
if f[1].downcase != 'utf-8'
|
||||
after = Iconv.conv('UTF-8',f[1],after)
|
||||
end
|
||||
|
||||
end
|
||||
return after
|
||||
rescue
|
||||
logger.error("Class Message: String decode error: #{text}")
|
||||
return text
|
||||
end
|
||||
end
|
||||
|
||||
def self.addr_to_db(addr)
|
||||
ret = ""
|
||||
name = addr.name
|
||||
name.nil? ? ret : ret << decode(name)
|
||||
ret << "<" + addr.mailbox + "@" + addr.host
|
||||
ret
|
||||
end
|
||||
|
||||
def self.getPageForUser(user,folder,page,sort_field,sort_dir)
|
||||
|
||||
|
@ -17,23 +56,33 @@ class Message < ActiveRecord::Base
|
|||
Message.paginate :page => page , :per_page => user.prefs.msgs_per_page.to_i, :conditions=> ['user_id = ? and folder_id = ?', user.id,folder.id],:order => order
|
||||
end
|
||||
|
||||
def self.createForUser(user,folder,mess)
|
||||
def self.createForUser(user,folder,imap_message)
|
||||
|
||||
envelope = imap_message.attr['ENVELOPE']
|
||||
|
||||
from = addr_to_db(envelope.from[0])
|
||||
to = addr_to_db(envelope.to[0])
|
||||
|
||||
envelope.subject.nil? ? subject = "" : subject = decode(envelope.subject)
|
||||
|
||||
create(
|
||||
:user_id => user.id,
|
||||
:folder_id => folder.id,
|
||||
:msg_id => mess.message_id,
|
||||
:uid => mess.uid,
|
||||
:from_addr => mess.from_to_db,
|
||||
:to_addr => mess.to_to_db,
|
||||
:subject => mess.subject,
|
||||
:content_type => mess.content_type,
|
||||
:date => mess.date,
|
||||
:unseen => mess.unseen,
|
||||
:size => mess.size)
|
||||
end
|
||||
:msg_id => envelope.message_id,
|
||||
:uid => imap_message.attr['UID'].to_i,
|
||||
:from_addr => from,
|
||||
:to_addr => to,
|
||||
:subject => subject,
|
||||
:content_type => imap_message.attr['BODYSTRUCTURE'].media_type.downcase,
|
||||
:date => envelope.date,
|
||||
:unseen => !(imap_message.attr['FLAGS'].member? :Seen),
|
||||
:size => imap_message.attr['RFC822.SIZE']
|
||||
)
|
||||
end
|
||||
|
||||
def change_folder(folder)
|
||||
update_attributes(:folder_id => folder.id)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -17,8 +17,12 @@ msgs_inbox_view_fields: [from_addr, subject, date, size]
|
|||
msgs_sent_view_fields: [to_addr, subject, date, size]
|
||||
|
||||
msg_subject_length: 45
|
||||
msg_address_length: 35
|
||||
msg_search_fields: [subject, from, to]
|
||||
|
||||
# if encoding can not be get from data
|
||||
msg_unknown_encoding: ISO-8859-2
|
||||
|
||||
imap_debug: false
|
||||
imap_use_ssl: 'false'
|
||||
imap_port: 143
|
||||
|
@ -35,4 +39,5 @@ mailbox_trash: INBOX.Trash
|
|||
mailbox_sent: INBOX.sent
|
||||
mailbox_drafts: INBOX.drafts
|
||||
|
||||
# array of logins which only can login to application, comment it to allow everyone to login
|
||||
only_can_logins: [wtodryk]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class CreateMessages < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :messages do |t|
|
||||
create_table :messages ,:id => false do |t|
|
||||
t.integer :folder_id
|
||||
t.integer :user_id
|
||||
t.string :msg_id
|
||||
|
|
|
@ -37,7 +37,7 @@ ActiveRecord::Schema.define(:version => 20110816120258) do
|
|||
t.string "alter_name"
|
||||
end
|
||||
|
||||
create_table "messages", :force => true do |t|
|
||||
create_table "messages", :id => false, :force => true do |t|
|
||||
t.integer "folder_id"
|
||||
t.integer "user_id"
|
||||
t.string "msg_id"
|
||||
|
|
|
@ -46,40 +46,41 @@ end
|
|||
class IMAPMessage
|
||||
|
||||
@@fetch_attr = ['ENVELOPE','BODYSTRUCTURE', 'FLAGS', 'UID', 'RFC822.SIZE']
|
||||
#@@fetch_attr = ['RFC822','FLAGS', 'UID', 'RFC822.SIZE']
|
||||
|
||||
attr_accessor :envelope,:uid,:content_type,:size,:unseen,:from,:message_id,:to,:from,:subject,:date
|
||||
|
||||
def initialize
|
||||
end
|
||||
|
||||
def self.fromImap(message)
|
||||
m = IMAPMessage.new
|
||||
envelope = message.attr['ENVELOPE']
|
||||
m.envelope = envelope
|
||||
m.message_id = envelope.message_id
|
||||
m.date = envelope.date
|
||||
m.subject = envelope.subject
|
||||
m.uid = message.attr['UID']
|
||||
#content_type = m.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text'
|
||||
m.content_type = message.attr['BODYSTRUCTURE'].media_type.downcase
|
||||
m.size = message.attr['RFC822.SIZE']
|
||||
m.unseen = !(message.attr['FLAGS'].member? :Seen)
|
||||
m.from = IMAPAddress.from_address(envelope.from[0])
|
||||
m.to = IMAPAddress.from_address(envelope.to[0])
|
||||
m
|
||||
end
|
||||
|
||||
# attr_accessor :envelope,:uid,:content_type,:size,:unseen,:from,:message_id,:to,:from,:subject,:date
|
||||
#
|
||||
# def initialize
|
||||
# end
|
||||
#
|
||||
# def self.fromImap(message)
|
||||
# m = IMAPMessage.new
|
||||
# envelope = message.attr['ENVELOPE']
|
||||
# m.envelope = envelope
|
||||
# m.message_id = envelope.message_id
|
||||
# m.date = envelope.date
|
||||
# m.subject = envelope.subject
|
||||
# m.uid = message.attr['UID']
|
||||
# #content_type = m.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text'
|
||||
# m.content_type = message.attr['BODYSTRUCTURE'].media_type.downcase
|
||||
# m.size = message.attr['RFC822.SIZE']
|
||||
# m.unseen = !(message.attr['FLAGS'].member? :Seen)
|
||||
# m.from = IMAPAddress.from_address(envelope.from[0])
|
||||
# m.to = IMAPAddress.from_address(envelope.to[0])
|
||||
# m
|
||||
# end
|
||||
#
|
||||
def self.fetch_attr
|
||||
@@fetch_attr
|
||||
end
|
||||
|
||||
def from_to_db
|
||||
from.to_db
|
||||
end
|
||||
|
||||
def to_to_db
|
||||
to.to_db
|
||||
end
|
||||
#
|
||||
# def from_to_db
|
||||
# from.to_db
|
||||
# end
|
||||
#
|
||||
# def to_to_db
|
||||
# to.to_db
|
||||
# end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -499,6 +499,11 @@ div.render_text pre {
|
|||
padding: 5px;
|
||||
border: 1px solid #5E634E;
|
||||
margin: 10px 0 0 0;
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
}
|
||||
|
||||
span.attachment {
|
||||
|
@ -512,4 +517,3 @@ span.attachment pre {
|
|||
span.attachment span.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="msg_header">
|
||||
<%= raw mail_param_view(@message,"from_addr",show_address_formatter(@message.from_addr)) %>
|
||||
<%= raw mail_param_view(@message,"to_addr",show_address_formatter(@message.to_addr)) %>
|
||||
<%= raw mail_param_view(@message,"from_addr",address_formatter(@message.from_addr,:message)) %>
|
||||
<%= raw mail_param_view(@message,"to_addr",address_formatter(@message.to_addr,:message)) %>
|
||||
<%= raw mail_param_view(@message,"subject",@message.subject) %>
|
||||
<%= raw mail_param_view(@message,"date",date_formatter(@message.date)) %>
|
||||
<%= hidden_field_tag 'uids[]', @message.uid %>
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<td><%= check_box_tag "uids[]", row.uid %></td>
|
||||
<td><%= attachment_formatter(row) %></td>
|
||||
<td nowrap="nowrap"><%= address_formatter(row.from_addr) %></td>
|
||||
|
||||
<% if @current_folder.hasFullName?($defaults["mailbox_sent"]) %>
|
||||
<td nowrap="nowrap"><%= address_formatter(row.to_addr,:index) %></td>
|
||||
<% else %>
|
||||
<td nowrap="nowrap"><%= address_formatter(row.from_addr,:index) %></td>
|
||||
<% end %>
|
||||
|
||||
<td nowrap="nowrap"><%= subject_formatter(row) %></td>
|
||||
<td nowrap="nowrap"><%= date_formatter(row.date) %></td>
|
||||
</td><td nowrap="nowrap"><%= size_formatter(row.size) %></td><td><%= raw(' ') %>
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
</p>
|
||||
<% else %>
|
||||
<% @render_as_text.each do |r| %>
|
||||
<pre>
|
||||
<%= raw content_text_plain_for_render(r) %>
|
||||
</pre>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue