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/23 21:38:06 UTC
[whimsy.git] [1/1] Commit 99c663a: burst support
Commit 99c663ae20a80c41b94e436bede5ee08ad9206f6:
burst support
Branch: refs/heads/secmail
Author: Sam Ruby <ru...@intertwingly.net>
Committer: Sam Ruby <ru...@intertwingly.net>
Pusher: rubys <ru...@apache.org>
------------------------------------------------------------
www/secmail/models/attachment.rb | +++++++ ---
www/secmail/models/message.rb | +++++++++
www/secmail/views/actions/burst.json.rb | +++++++++++
www/secmail/views/app.js.rb | -
www/secmail/views/parts.js.rb | ++++++++++ -
------------------------------------------------------------
83 changes: 78 additions, 5 deletions.
------------------------------------------------------------
diff --git a/www/secmail/models/attachment.rb b/www/secmail/models/attachment.rb
index e1fb6f4..83f98ff 100644
--- a/www/secmail/models/attachment.rb
+++ b/www/secmail/models/attachment.rb
@@ -8,6 +8,10 @@ def initialize(message, headers, part)
@part = part
end
+ def name
+ headers[:name] || @part.filename
+ end
+
def content_type
headers[:mime] || @part.content_type
end
@@ -17,7 +21,7 @@ def body
end
def safe_name
- name = @part.filename
+ name = self.name.dup
name.gsub! /^\W/, ''
name.gsub! /[^\w.]/, '_'
name.untaint
@@ -29,9 +33,9 @@ def as_pdf
file.rewind
return file if content_type.end_with? '/pdf'
- return file if @part.filename.end_with? '.pdf'
+ return file if name.end_with? '.pdf'
- ext = File.extname(@part.filename).downcase
+ ext = File.extname(name).downcase
if IMAGE_TYPES.include? ext or content_type.start_with? 'image/'
pdf = Tempfile.new([safe_name, '.pdf'], encoding: Encoding::BINARY)
diff --git a/www/secmail/models/message.rb b/www/secmail/models/message.rb
index af66139..e56e44e 100644
--- a/www/secmail/models/message.rb
+++ b/www/secmail/models/message.rb
@@ -61,6 +61,15 @@ def update_attachment name, values
end
end
+ def replace_attachment name, values
+ attachment = find(name)
+ if attachment
+ index = @headers[:attachments].find_index(attachment.headers)
+ @headers[:attachments][index, 1] = Array(values)
+ write
+ end
+ end
+
def delete_attachment name
attachment = find(name)
if attachment
diff --git a/www/secmail/views/actions/burst.json.rb b/www/secmail/views/actions/burst.json.rb
new file mode 100644
index 0000000..83933f1
--- /dev/null
+++ b/www/secmail/views/actions/burst.json.rb
@@ -0,0 +1,42 @@
+#
+# burst a document into separate pages
+#
+
+month, hash = @message.match(%r{/(\d+)/(\w+)}).captures
+
+mbox = Mailbox.new(month)
+message = mbox.find(hash)
+
+attachments = []
+
+begin
+ source = message.find(@selected).as_pdf
+
+ Dir.mktmpdir do |dir|
+ Kernel.system 'pdftk', source.path, 'burst', 'output',
+ "#{dir}/page_%06d.pdf"
+
+ pages = Dir["#{dir}/*.pdf"].sort.map {|name| name.untaint}
+
+ format = @selected.sub(/\.\w+$/, '') +
+ "-%0#{pages.length.to_s.length}d.pdf"
+
+ pages.each_with_index do |page, index|
+ attachments << {
+ name: format % (index+1),
+ content: File.read(page),
+ mime: 'application/pdf'
+ }
+ end
+ end
+
+ message.replace_attachment @selected, attachments
+
+ensure
+ source.unlink if source
+end
+
+{
+ attachments: message.attachments,
+ selected: (attachments.empty? ? nil : attachments.first[:name])
+}
diff --git a/www/secmail/views/app.js.rb b/www/secmail/views/app.js.rb
index 2d7fb10..17bf47e 100644
--- a/www/secmail/views/app.js.rb
+++ b/www/secmail/views/app.js.rb
@@ -3,4 +3,3 @@
require_relative 'index'
require_relative 'parts'
-require_relative 'context-menu'
diff --git a/www/secmail/views/parts.js.rb b/www/secmail/views/parts.js.rb
index 21fa5ad..c428de3 100644
--- a/www/secmail/views/parts.js.rb
+++ b/www/secmail/views/parts.js.rb
@@ -34,7 +34,10 @@ def render
end
end
- _ContextMenu
+ _ul.contextMenu do
+ _li 'burst', onMouseDown: self.burst
+ _li 'delete'
+ end
_img.spinner src: '../../rotatingclock-slow2.gif' if @busy
end
@@ -97,6 +100,22 @@ def keydown(event)
end
end
+ # burst a PDF into individual pages
+ def burst(event)
+ data = {
+ selected: @selected,
+ message: window.parent.location.pathname
+ }
+
+ @busy = true
+ HTTP.post '../../actions/burst', data do |response|
+ @attachments = response.attachments
+ @selected = response.selected
+ @busy = false
+ window.parent.frames.content.location.href=response.selected
+ end
+ end
+
#
# drag/drop support. Note: support varies by browser (in particular,
# when events are called and whether or not a particular event has