You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by Sam Ruby <ru...@apache.org> on 2015/12/13 16:14:51 UTC
[whimsy.git] [5/37] Commit 053f75f: rough in a body view
Commit 053f75f64a62f2d81dbf3f9eb01b47a8ac9dd088:
rough in a body view
Branch: refs/heads/secmail
Author: Sam Ruby <ru...@intertwingly.net>
Committer: Sam Ruby <ru...@intertwingly.net>
Pusher: rubys <ru...@apache.org>
------------------------------------------------------------
common.rb | ++++++++++
mailbox.rb | +++++++++++++++
parsemail.rb | +++ -----------
server.rb | ++++++++ -
views/body.html.rb | ++++++++++
views/index.html.rb | +++ -
views/message.html.rb | ++++++++
views/parts.html.rb | ++++++++++
------------------------------------------------------------
211 changes: 188 additions, 23 deletions.
------------------------------------------------------------
diff --git a/common.rb b/common.rb
new file mode 100644
index 0000000..658126c
--- /dev/null
+++ b/common.rb
@@ -0,0 +1,37 @@
+require 'digest'
+require 'zlib'
+require 'zip'
+require 'stringio'
+
+require_relative 'config.rb'
+
+#
+# What to use as a hash for mail
+#
+def hashmail(message)
+ Digest::SHA1.hexdigest(mail[/^Message-ID:.*/i] || mail)[0..9]
+end
+
+#
+# Read a mailbox and split it into messages
+#
+def readmbox(filename)
+ mails = File.read(filename)
+
+ if filename.end_with? '.gz'
+ stream = StringIO.new(mails)
+ reader = Zlib::GzipReader.new(stream)
+ mails = reader.read
+ reader.close
+ stream.close rescue nil
+ end
+
+ mails.force_encoding Encoding::ASCII_8BIT
+
+ # split into individual messages
+ mails = mails.split(/^From .*/)
+ mails.shift
+
+ mails
+end
+
diff --git a/mailbox.rb b/mailbox.rb
new file mode 100644
index 0000000..9f123a9
--- /dev/null
+++ b/mailbox.rb
@@ -0,0 +1,57 @@
+require 'digest'
+require 'zlib'
+require 'zip'
+require 'stringio'
+require 'mail'
+
+require_relative 'config.rb'
+
+class Mailbox
+ #
+ # What to use as a hash for mail
+ #
+ def self.hash(message)
+ Digest::SHA1.hexdigest(message[/^Message-ID:.*/i] || message)[0..9]
+ end
+
+ #
+ # Read a mailbox and split it into messages
+ #
+ def initialize(filename)
+ mails = File.read(filename)
+
+ if filename.end_with? '.gz'
+ stream = StringIO.new(mails)
+ reader = Zlib::GzipReader.new(stream)
+ mails = reader.read
+ reader.close
+ stream.close rescue nil
+ end
+
+ mails.force_encoding Encoding::ASCII_8BIT
+
+ # split into individual messages
+ mails = mails.split(/^From .*/)
+ mails.shift
+
+ @mails = mails
+ end
+
+
+ #
+ # Find a message
+ #
+ def find(hash)
+ message = @mails.find {|mail| Mailbox.hash(mail) == hash}
+ Mail.new(message) if message
+ end
+
+ #
+ # iterate through messages
+ #
+ def each(&block)
+ @mails.each(&block)
+ end
+end
+
+
diff --git a/parsemail.rb b/parsemail.rb
index 22581cb..d4e8422 100644
--- a/parsemail.rb
+++ b/parsemail.rb
@@ -10,14 +10,10 @@
# * Invalid from addresses
#
-require 'mail'
-require 'zlib'
-require 'zip'
require 'yaml'
-require 'stringio'
require 'time'
-require_relative 'config'
+require_relative 'mailbox'
database = File.basename(SOURCE)
@@ -76,26 +72,14 @@ def headers(part)
mbox[:mtime] = File.mtime(name)
# read (and unzip) the mailbox
- mails = File.read(name)
- if name.end_with? '.gz'
- stream = StringIO.new(mails)
- reader = Zlib::GzipReader.new(stream)
- mails = reader.read
- reader.close
- stream.close rescue nil
- end
- mails.force_encoding Encoding::ASCII_8BIT
-
- # split into individual messages
- mails = mails.split(/^From .*/)
- mails.shift
+ messages = Mailbox.new(name)
# process each
- mails.each do |mail|
+ messages.each do |message|
# compute id, skip if already processed
- id = hashmail(mail)
+ id = Mailbox.hash(message)
next if mbox[id]
- mail = Mail.read_from_string(mail)
+ mail = Mail.read_from_string(message)
# parse from address
begin
diff --git a/server.rb b/server.rb
index b04a976..94e9d5c 100644
--- a/server.rb
+++ b/server.rb
@@ -1,7 +1,8 @@
require 'whimsy/asf'
require 'wunderbar/sinatra'
+require 'mail'
-require_relative 'config'
+require_relative 'mailbox'
def load_mbox(file)
messages = YAML.load_file(file)
@@ -12,6 +13,18 @@ def load_mbox(file)
end
end
+def load_message(month, hash)
+ mbox = Dir["#{ARCHIVE}/#{month}", "#{ARCHIVE}/#{month}.gz"].first
+ return unless mbox
+
+ mbox = Mailbox.new(mbox)
+ mbox.each do |message|
+ if Mailbox.hash(message) == hash
+ return Mail.read_from_string(message)
+ end
+ end
+end
+
get '/' do
@messages = load_mbox(Dir["#{ARCHIVE}/*.yml"].sort.last)
@messages.merge! load_mbox(Dir["#{ARCHIVE}/*.yml"].sort[-2])
@@ -20,3 +33,20 @@ def load_mbox(file)
_html :index
end
+
+get %r{^/(\d+)/(\w+)/$} do |month, hash|
+ @message = load_mbox("#{ARCHIVE}/#{month}.yml")[hash] rescue pass
+ _html :message
+end
+
+get %r{^/(\d+)/(\w+)/_index_$} do |month, hash|
+ @message = load_mbox("#{ARCHIVE}/#{month}.yml")[hash] rescue pass
+ _html :parts
+end
+
+get %r{^/(\d+)/(\w+)/_body_$} do |month, hash|
+ @message = load_message(month, hash)
+ pass unless @message
+ _html :body
+end
+
diff --git a/views/body.html.rb b/views/body.html.rb
new file mode 100644
index 0000000..2e938aa
--- /dev/null
+++ b/views/body.html.rb
@@ -0,0 +1,37 @@
+_html do
+ _table do
+ _tr do
+ _td 'From:'
+ _td @message[:from]
+ end
+
+ _tr do
+ _td 'To:'
+ _td @message[:to]
+ end
+
+ if @message[:cc]
+ _tr do
+ _td 'Cc:'
+ _td @message[:cc]
+ end
+ end
+
+ _tr do
+ _td 'Subject:'
+ _td @message.subject
+ end
+ end
+
+ _p
+ _hr
+ _p
+
+ if @message.html_part
+ _div do
+ _{@message.html_part.body.to_s.untaint}
+ end
+ else
+ _pre @message.text_part.body.to_s
+ end
+end
diff --git a/views/index.html.rb b/views/index.html.rb
index e2ca141..73dbe8d 100644
--- a/views/index.html.rb
+++ b/views/index.html.rb
@@ -1,11 +1,13 @@
_html do
_table do
@messages.each do |id, description|
+
+ # skip if there are no attachments at all
next unless description[:attachments]
_tr_ do
_td! do
- _a description[:time], href: "msg/#{description[:source]}/#{id}"
+ _a description[:time], href: "#{description[:source]}/#{id}/"
end
_td description[:name]
_td description['Subject']
diff --git a/views/message.html.rb b/views/message.html.rb
new file mode 100644
index 0000000..13d6f2f
--- /dev/null
+++ b/views/message.html.rb
@@ -0,0 +1,8 @@
+_html do
+ _title 'ASF Secretary Workbench'
+
+ _frameset cols: '20%, 60%' do
+ _frame src: '_index_'
+ _frame src: '_body_'
+ end
+end
diff --git a/views/parts.html.rb b/views/parts.html.rb
new file mode 100644
index 0000000..3bb699d
--- /dev/null
+++ b/views/parts.html.rb
@@ -0,0 +1,10 @@
+_html do
+ _ul do
+ _li 'text'
+ _li 'headers'
+
+ @message[:attachments].each do |attachment|
+ _li attachment[:name]
+ end
+ end
+end