diff --git a/app/controllers/wiki_external_filter_controller.rb b/app/controllers/wiki_external_filter_controller.rb
index 23c03dc..94a25bd 100644
--- a/app/controllers/wiki_external_filter_controller.rb
+++ b/app/controllers/wiki_external_filter_controller.rb
@@ -6,12 +6,14 @@ class WikiExternalFilterController < ApplicationController
def filter
name = params[:name]
macro = params[:macro]
+ index = params[:index].to_i
+ filename = params[:filename] ? params[:filename] : name
config = load_config
cache_key = self.construct_cache_key(macro, name)
content = read_fragment cache_key
if (content)
- send_data content, :type => config[macro]['content_type'], :disposition => 'inline'
+ send_data content[index], :type => config[macro]['content_type'], :disposition => 'inline', :filename => filename
else
render_404
end
diff --git a/app/helpers/wiki_external_filter_helper.rb b/app/helpers/wiki_external_filter_helper.rb
index 931b77a..431a93f 100644
--- a/app/helpers/wiki_external_filter_helper.rb
+++ b/app/helpers/wiki_external_filter_helper.rb
@@ -1,4 +1,5 @@
require 'digest/sha2'
+require 'open4'
module WikiExternalFilterHelper
@@ -24,7 +25,7 @@ module WikiExternalFilterHelper
['wiki_external_filter', macro, name].join("/")
end
- def build(text, macro, info)
+ def build(text, attachments, macro, info)
name = Digest::SHA256.hexdigest(text)
result = {}
@@ -49,14 +50,14 @@ module WikiExternalFilterHelper
result[:content_type] = info['content_type']
RAILS_DEFAULT_LOGGER.debug "from cache: #{name}"
else
- result = self.build_forced(text, info)
+ result = self.build_forced(text, attachments, info)
if result[:status]
if expires > 0
write_fragment cache_key, result[:content], :expires_in => expires.seconds
RAILS_DEFAULT_LOGGER.debug "cache saved: #{name}"
end
else
- raise "Error applying external filter: #{result[:content]}"
+ raise "Error applying external filter: stdout is #{result[:content]}, stderr is #{result[:errors]}"
end
end
@@ -66,23 +67,42 @@ module WikiExternalFilterHelper
return result
end
- def build_forced(text, info)
+ def build_forced(text, attachments, info)
+
+ if info['replace_attachments'] and attachments
+ attachments.each do |att|
+ text.gsub!(/#{att.filename.downcase}/i, att.diskfile)
+ end
+ end
result = {}
+ content = []
+ errors = ""
- RAILS_DEFAULT_LOGGER.debug "executing command: #{info['command']}"
+ commands = info['commands']? info['commands'] : [info['command']]
- content = IO.popen(info['command'], 'r+b') { |f|
- f.write info[:prolog] if info.key?(:prolog)
- f.write CGI.unescapeHTML(text)
- f.write info[:epilog] if info.key?(:epilog)
- f.close_write
- f.read
- }
+ commands.each do |command|
+ RAILS_DEFAULT_LOGGER.info "executing command: #{command}"
- RAILS_DEFAULT_LOGGER.info("child status: sig=#{$?.termsig}, exit=#{$?.exitstatus}")
+ c = nil
+ e = nil
+
+ Open4::popen4(command) { |pid, fin, fout, ferr|
+ fin.write info[:prolog] if info.key?(:prolog)
+ fin.write CGI.unescapeHTML(text)
+ fin.write info[:epilog] if info.key?(:epilog)
+ fin.close
+ c, e = [fout.read, ferr.read]
+ }
+
+ RAILS_DEFAULT_LOGGER.debug("child status: sig=#{$?.termsig}, exit=#{$?.exitstatus}")
+
+ content << c
+ errors += e if e
+ end
result[:content] = content
+ result[:errors] = errors
result[:content_type] = info['content_type']
result[:source] = text
result[:status] = $?.exitstatus == 0
@@ -101,12 +121,12 @@ module WikiExternalFilterHelper
end
class Macro
- def initialize(view, source, macro, info)
+ def initialize(view, source, attachments, macro, info)
@view = view
@view.controller.extend(WikiExternalFilterHelper)
source.gsub!(/
/, "")
source.gsub!(/<\/?p>/, "")
- @result = @view.controller.build(source, macro, info)
+ @result = @view.controller.build(source, attachments, macro, info)
end
def render()
diff --git a/app/views/wiki_external_filter/macro_block.html.erb b/app/views/wiki_external_filter/macro_block.html.erb
index a72ab02..03f3949 100644
--- a/app/views/wiki_external_filter/macro_block.html.erb
+++ b/app/views/wiki_external_filter/macro_block.html.erb
@@ -12,6 +12,15 @@
when /\/.*(x|ht)ml/ then
%>
<%= h content %>+
<%= h content[0] %><% when /\/.*(x|ht)ml/ then %> -
Click here to download latest version
":"Download latest version from here
");if(m.tagName=="A"){m.onclick=function(){location.href="http://www.adobe.com/go/getflashplayer"}}}}}if(!o&&p.onFail){var n=p.onFail.call(this);if(typeof n=="string"){m.innerHTML=n}}if(document.all){window[p.id]=document.getElementById(p.id)}}window.flashembed=function(l,m,k){if(typeof l=="string"){var n=document.getElementById(l);if(n){l=n}else{c(function(){flashembed(l,m,k)});return}}if(!l){return}if(typeof m=="string"){m={src:m}}var o=f({},i);f(o,m);return new d(l,o,k)};f(window.flashembed,{getVersion:function(){var m=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var l=navigator.plugins["Shockwave Flash"].description;if(typeof l!="undefined"){l=l.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var n=parseInt(l.replace(/^(.*)\..*$/,"$1"),10);var r=/r/.test(l)?parseInt(l.replace(/^.*r(.*)$/,"$1"),10):0;m=[n,r]}}else{if(window.ActiveXObject){try{var p=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7")}catch(q){try{p=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");m=[6,0];p.AllowScriptAccess="always"}catch(k){if(m[0]==6){return m}}try{p=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")}catch(o){}}if(typeof p=="object"){l=p.GetVariable("$version");if(typeof l!="undefined"){l=l.replace(/^\S+\s+(.*)$/,"$1").split(",");m=[parseInt(l[0],10),parseInt(l[2],10)]}}}}return m},isSupported:function(k){var m=flashembed.getVersion();var l=(m[0]>k[0])||(m[0]==k[0]&&m[1]>=k[1]);return l},domReady:c,asString:g,getHTML:a});if(e){jQuery.fn.flashembed=function(l,k){var m=null;this.each(function(){m=flashembed(this,l,k)});return l.api===false?this:m}}})(); \ No newline at end of file diff --git a/assets/javascripts/flowplayer.rtmp.swf b/assets/javascripts/flowplayer.rtmp.swf new file mode 100644 index 0000000..fab819a Binary files /dev/null and b/assets/javascripts/flowplayer.rtmp.swf differ diff --git a/assets/javascripts/flowplayer.swf b/assets/javascripts/flowplayer.swf new file mode 100644 index 0000000..63f3934 Binary files /dev/null and b/assets/javascripts/flowplayer.swf differ diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..545be92 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,3 @@ +ActionController::Routing::Routes.draw do |map| + map.connect 'wiki_external_filter/:filename', :controller => 'wiki_external_filter', :action => 'filter', :macro => 'flowplayer', :index => '1', :requirements => { :filename => /\S+\.flv/ } +end diff --git a/init.rb b/init.rb index 46d36a6..dab9f8e 100644 --- a/init.rb +++ b/init.rb @@ -18,8 +18,8 @@ Redmine::Plugin.register :wiki_external_filter do Redmine::WikiFormatting::Macros.register do info = config[name] desc info['description'] - macro name do |wiki_content_obj, args| - m = WikiExternalFilterHelper::Macro.new(self, args.to_s, name, info) + macro name do |obj, args| + m = WikiExternalFilterHelper::Macro.new(self, args.to_s, obj.page.attachments, name, info) m.render end @@ -33,7 +33,7 @@ Redmine::Plugin.register :wiki_external_filter do @included_wiki_pages ||= [] raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title) @included_wiki_pages << page.title - m = WikiExternalFilterHelper::Macro.new(self, page.content.text, name, info) + m = WikiExternalFilterHelper::Macro.new(self, page.content.text, page.attachments, name, info) @included_wiki_pages.pop m.render_block(args.to_s) end diff --git a/routes.rb b/routes.rb index c8d80e2..e030364 100644 --- a/routes.rb +++ b/routes.rb @@ -1,2 +1 @@ - -connect 'wiki_external_filter/:macro/:name', :controller => 'wiki_external_filter', :action => 'filter', :macro => /\S+/ +connect 'wiki_external_filter/:filename', :controller => 'wiki_external_filter', :action => 'filter', :macro => 'flowplayer', :index => '1', :requirements => { :filename => /\S+\.flv/ }