<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Authoritative Opinion &#187; Code</title>
	<atom:link href="http://authoritativeopinion.com/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://authoritativeopinion.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 19 Jul 2010 00:04:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>Open source happenings</title>
		<link>http://authoritativeopinion.com/blog/2010/02/02/open-source-happenings/</link>
		<comments>http://authoritativeopinion.com/blog/2010/02/02/open-source-happenings/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 02:18:49 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://authoritativeopinion.com/blog/2010/02/02/open-source-happenings/">chris</span></dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://authoritativeopinion.com/blog/?p=292</guid>
		<description><![CDATA[Just some quick notes: I got a patch into FITS to add some basic video metadata extraction. I&#8217;d like to take it further to ensure support for the formats that exiftool supports, but it&#8217;s a good start. Today I pushed out a first release of ave-sync, a media/xml synchronization tool. Also a good start, and [...]]]></description>
			<content:encoded><![CDATA[<p>Just some quick notes:</p>
<ol>
<li>I got a patch into <a href="http://code.google.com/p/fits/">FITS</a> to add some basic video metadata extraction. I&#8217;d like to take it further to ensure support for the formats that exiftool supports, but it&#8217;s a good start.
</li>
<li>Today I pushed out a first release of <a href="http://github.com/cbeer/ave-sync">ave-sync</a>, a media/xml synchronization tool. Also a good start, and should be a starting place to play with the <a href="http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/">w3c FileAPI</a> in Firefox 3.6.</li>
<li>XForms applications are painful to write, but probably a good choice for XML-based workflows.. more on that later..</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://authoritativeopinion.com/blog/2010/02/02/open-source-happenings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery and SVG (and inline SVG)</title>
		<link>http://authoritativeopinion.com/blog/2010/01/13/jquery-and-svg/</link>
		<comments>http://authoritativeopinion.com/blog/2010/01/13/jquery-and-svg/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 19:45:06 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://authoritativeopinion.com/blog/2010/01/13/jquery-and-svg/">greg</span></dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[inline svg]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[svg]]></category>

		<guid isPermaLink="false">http://authoritativeopinion.com/blog/?p=277</guid>
		<description><![CDATA[If you&#8217;re using Keith Wood&#8217;s great jQuery SVG plugin, you may find that the .css() function doesn&#8217;t work on SVG elements, as in: var elem = $('#test'); if (elem.css('display') == 'none') { elem.css('display', ''); } will generate an error when CSS properties are written, but not when they are read. To address this, add this [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using <a href="http://keith-wood.name/svg.html">Keith Wood&#8217;s great jQuery SVG plugin</a>, you may find that the .css() function doesn&#8217;t work on SVG elements, as in:</p>
<pre name="code" class="javascript">
var elem = $('#test');
if (elem.css('display') == 'none') {
    elem.css('display', '');
}
</pre name="code" class="javascript">

will generate an error when CSS properties are written, but not when they are read. To address this, add this code to jquery.svgdom.js:
<pre name="code" class="javascript">
/* Support CSS on SVG nodes. */
var origCSS = $.fn.css;
$.fn.css = function(name, value, type) {
	if (typeof name === 'string' &#038;&#038; value === undefined) {
		var val = origCSS.apply(this, [name, value, type]);
		return (val &#038;&#038; val.baseVal ? val.baseVal.valueAsString : val);
	}
	var options = name;
	if (typeof name === 'string') {
		options = {};
		options[name] = value;
	}
	return this.each(function() {
		if (isSVGElem(this)) {
			for (var n in options) {
				this.style[n] = (typeof options[n] == 'function' ? options[n]() : options[n]);
			}
		}
		else {
			origCSS.apply($(this), [name, value, type]);
		}
	});
}
</pre>
<p>I make no guarantees that it works on all platforms or browsers, but I mimicked the way Keith implemented .attr() for SVG elements, using the style attribute instead, so it hopefully has similar levels of portability. So far it works for me in Firefox 3.5 and Chrome 3.0. I'm going to guess that it works in Safari, because old code that used the style attribute worked there as well. No idea about IE, because my SVG doesn't load in that to begin with...</p>
<p>In addition to this, I needed to use the plugin to modify existing <a href="http://wiki.svg.org/Inline_SVG">inline SVG</a>, which seemed daunting given that the plugin normally created its own SVG canvas to render on. However, by hacking together a few calls to some of the internal functions I was able to get a jQuery SVG Wrapper with which I could call methods such as circle(), etc.:</p>
<pre name="code" class="javascript">
var theDiv = $("#svg-container-div")[0];
$.svg._afterLoad(theDiv, $("#svg-root-element"), {});
var svgRoot = $.svg._getSVG($("#svg-container-div"));
var svgDoc = $("#svg-root-element");
svgRoot._svg = svgDoc[0];
svgRoot.circle(svgDoc[0], 270, 150, 25, {'id' : 'testcircle', 'fill' : "#ffffff", 'stroke' : '#ff0000'});
</pre>
<p>I'm not sure that this method of doing things is entirely acceptable as far as using the plugin correctly, but for me it successfully modified the DOM and I was able to reference the created elements without incident afterwards. At this point there was one last thing that I wanted to change about the plugin: when creating an SVG element I needed to specify a DOM element, not a jQuery wrapper. Usually this just means that the jQuery wrapper must be de-referenced to get the node, i.e. svgDoc[0] above, but I would get annoyed having to remember to add the array de-reference, so I modified jquery.svg.js again, this time changing the definition of _args, which handles argument decoding for all of the svg functions:</p>
<pre name="code" class="javascript">
_args: function(values, names, optSettings) {
		names.splice(0, 0, 'parent');
		names.splice(names.length, 0, 'settings');
		var args = {};
		var offset = 0;
		var vOffset = 0;
		if (values[0] != null &#038;&#038; (typeof values[0] != 'object' || !values[0].nodeName)) {
			if (!(values[0].jquery &#038;&#038; values[0][0].nodeName)) {
				args['parent'] = null;
				offset = 1;
				vOffset = 0;
			}
			else {
				args['parent'] = values[0][0];
				offset = 1;
				vOffset = 1;
			}
		}
		for (var i = 0; i < values.length; i++) {
			args[names[i + offset]] = values[i+vOffset];
		}
		if (optSettings) {
			$.each(optSettings, function(i, value) {
				if (typeof args[value] == 'object') {
					args.settings = args[value];
					args[value] = null;
				}
			});
		}
		return args;
	},
</pre>
<p>This should provide the same behavior but allow the results of $(selector) to be supplied directly as the first argument to any SVG drawing methods (circle, rect, etc.), but only the first of these will be painted to, which is most useful when selecting an id, not a class. In addition the previous method of directly supplying an SVG DOM element will still work, as will falling back to using the default internal reference that is established when the SVG canvas is created.</p>
]]></content:encoded>
			<wfw:commentRss>http://authoritativeopinion.com/blog/2010/01/13/jquery-and-svg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improved Poster Generator</title>
		<link>http://authoritativeopinion.com/blog/2009/09/18/improved-poster-generator/</link>
		<comments>http://authoritativeopinion.com/blog/2009/09/18/improved-poster-generator/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 03:49:15 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://authoritativeopinion.com/blog/2009/09/18/improved-poster-generator/">greg</span></dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[matlab]]></category>

		<guid isPermaLink="false">http://authoritativeopinion.com/blog/?p=174</guid>
		<description><![CDATA[Partly due to a lack of complete functionality with the Obama Poster Generator, I decided to turn it into a much more generic and useful script for taking an image, smoothing/filtering it, and then changing the palette of the result. Most often this is used to generate things like President Obama&#8217;s campaign posters, any t-shirt [...]]]></description>
			<content:encoded><![CDATA[<p>Partly due to a lack of complete functionality with the <a href="http://authoritativeopinion.com/blog/2009/08/13/obama-poster-generator/">Obama Poster Generator</a>, I decided to turn it into a much more generic and useful script for taking an image, smoothing/filtering it, and then changing the palette of the result. Most often this is used to generate things like President Obama&#8217;s campaign posters, any t-shirt graphic that has 2 to 4 colors and very smooth lines&#8211;at least, the ones based on existing images of people and things, and I think it could be used, in principle, to create the effect of some of the cel-shaded video games, in the style of Jet Grind Radio, or even to create an animation style similar to that of A Scanner Darkly or the Charles Schwab commercials. Why? A normal image contains 8 bits of data per color channel, if it is a truecolor image. If one were to take a picture of a &#8220;solid&#8221; color, then the lower order bits will be integral in the &#8220;texture&#8221; of the image, created by variations in the color strength. However, if we chop off these lower order bits and then repaint the whole image in a specific subset of the 24-bit truecolor image, <em>but still using 24-bits to get very precise colors</em>, the textures of things disappear, and the only variations that are visible correspond mostly to edges of things and differences in lighting. I&#8217;ve included an example of what our President would look like as a video game character, for effect, but the results aren&#8217;t the best because it would take a very long time to determine the correct palette for the effect that we want, and I simply generated a uniform palette that discards the lowest bits when converting, but the similarity is still apparent.</p>
<p>In practice, generating high quality animated-style images based on real photographs will require hours of tweaking the palette&#8217;s colors, and while I was able to get away with only a few bits of resolution (I used 2 bits), to have something that looks high quality or has a large number of colors, a larger resolution will be necessary. Interestingly enough, for resolutions above 4 bits, the image looks basically the same, but weird in subtle ways that humans have trouble pin pointing. A resolution like this with a very restricted palette (say, the 3 bit one, properly expanded to provide information for all of the combinations) could provide very fine-grained control of the animated styled.</p>
<p>Without further ado, a re-post of the original picture, a much more accurate campaign-style poster, and a video game/commercial version of a portrait of president Obama, along with the palette files that I used for each of them:</p>
<p><center><div id="attachment_160" class="wp-caption alignnone" style="width: 232px"><a href="http://authoritativeopinion.com/blog/wp-content/uploads/2009/08/obama.jpg"><img class="size-medium wp-image-160" title="President Obama" src="http://authoritativeopinion.com/blog/wp-content/uploads/2009/08/obama-222x300.jpg" alt="Original portrait of President Obama" width="222" height="300" /></a><p class="wp-caption-text">Original portrait of President Obama</p></div> <div id="attachment_176" class="wp-caption alignnone" style="width: 232px"><a href="http://authoritativeopinion.com/blog/wp-content/uploads/2009/09/obama_filt_out.png"><img class="size-medium wp-image-176" title="Obama Poster-style Image" src="http://authoritativeopinion.com/blog/wp-content/uploads/2009/09/obama_filt_out-222x300.png" alt="A Campaign Poster-style Version of the original portrait" width="222" height="300" /></a><p class="wp-caption-text">A Campaign Poster-style Version of the original portrait</p></div> <div id="attachment_177" class="wp-caption alignnone" style="width: 232px"><a href="http://authoritativeopinion.com/blog/wp-content/uploads/2009/09/obama_celshade.png"><img class="size-medium wp-image-177" title="&quot;Cel-Shaded&quot; Obama" src="http://authoritativeopinion.com/blog/wp-content/uploads/2009/09/obama_celshade-222x300.png" alt="A more cartoony, Jet Grind Radio-style version of the Portrait" width="222" height="300" /></a><p class="wp-caption-text">A more cartoony, Jet Grind Radio-style version of the Portrait</p></div></center></p>
<p>Palettes:<br />
For the campaign poster (this will need modification on a per-image basis, but the colors should be the same): <a href="http://authoritativeopinion.com/blog/wp-content/uploads/2009/09/palette2bit.png">click here</a>.<br />
For the cartoon-y image (I would recommend making one that is more appropriate for how you want the image to be transformed, this was just a rough starting point): <a href="http://authoritativeopinion.com/blog/wp-content/uploads/2009/09/palette4.png">click here.</a></p>
<p>And, the code. My first contribution to the open source movement, incidentally.</p>
<pre name="code" class="matlab">
% *************************************************************************
% Image Poster Generator, v2.0
% This filters, decreases the resolution, and then repaints and image with
% values from a specified palette.
%
%   Copyright (C) 2009 Greg Malysa
% *************************************************************************
%    This program is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program.  If not, see < http://www.gnu.org/licenses/ >.
% *************************************************************************

% Specify the names of the palette image, the input, and the output
paletteName = 'palette2bit.png';
inputName = 'obama.jpg';
outputName = 'obama_filt_out.png';
outputType = 'png';

% The darken factor divides all of the pixel values in the image by the
% amount given here in order to change the brightness or darkness of the
% image as a whole.
darken = 1.35;

% Amount of smoothing to apply, between 1 and any integer. Large values
% will make things become far too smooth though, so be careful. 1 does no
% smoothing.
smooth = 4;

% The new target resolution (in bits), which also determines the palette
% size. This must be &gt;= 1 or nothing particularly interesting happens.
% Higher resolutions require larger palettes and allow for more colors.
% With resolution = 8, nothing happens, as all of these images are 8-bits
% per channel anyway (24-bit truecolor images).
targetBits = 2;
paletteSize = 2^targetBits;
divideFactor = 256 / paletteSize;

% The palette itself is a column of bits number of bits by bits blocks,
% where the block number indicates the red channel index, the x offset
% within a block indicates the green channel index, and the y offset
% indicates the blue channel index. For some reason, MATLAB specifies y
% first and x second when accessing an image.
paletteBase = cast(imread(paletteName), 'uint8');
palette = zeros([paletteSize paletteSize paletteSize 3]);
for block = 1:paletteSize
    blockBase = (block-1)*paletteSize;
    for green = 1:paletteSize   %x
        for blue = 1:paletteSize    %y
            palette(block, green, blue, :) = paletteBase(blue, blockBase+green, :);
        end
    end
end

% Format is columns by lines by channels (y, x, 3)
image = imread(inputName)/darken;

% Create a filter coefficient matrix based on the order of smoothness
% requested (this is like a 2-D averager, which is a form of low-pass
% filter). This can be changed to create an edge-detector, for instance.
B = ones(smooth)/(smooth*smooth);

% Apply to each channel separately
imagenew(:,:,1) = filter2(B, image(:,:,1));
imagenew(:,:,2) = filter2(B, image(:,:,2));
imagenew(:,:,3) = filter2(B, image(:,:,3));

% Decrease the resolution based on the bit number requested above, dealing
% with some inconsistencies between MATLAB's casting and traditional
% conventions, and MATLAB's array access mechanisms.
imagenew = cast(imagenew, 'double');
image = cast(floor(imagenew/divideFactor), 'uint8')+1;

% Channel 1 is red, channel 2 is green, and channel 3 is blue
for n = 1:length(image(:,1,1))
    for k = 1:length(image(1,:,1))
        image(n, k, :) = palette(image(n, k, 1), image(n, k, 2), image(n, k, 3), :);
    end
end

% Write out the final image
imwrite(cast(image, 'uint8'), outputName, outputType);
</pre>
</p>
<div class='wp_likes' id='wp_likes_post-174'><a class='like' href="javascript:wp_likes.like(174);" title='' ><img src="http://authoritativeopinion.com/blog/wp-content/plugins/wp-likes/images/like.png" alt='' border='0'/>Like</a><span class='text'></span>
<div class='unlike'><a href="javascript:wp_likes.unlike(174);">Unlike</a></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://authoritativeopinion.com/blog/2009/09/18/improved-poster-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Repository workflows</title>
		<link>http://authoritativeopinion.com/blog/2009/08/02/repository-workflows/</link>
		<comments>http://authoritativeopinion.com/blog/2009/08/02/repository-workflows/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 20:39:55 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://authoritativeopinion.com/blog/2009/08/02/repository-workflows/">chris</span></dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruote]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://authoritativeopinion.com/blog/?p=128</guid>
		<description><![CDATA[One of the sessions at RIRI &#8217;09, and a common theme across many of the conferences I attended this year, is workflows, workflow engines, and tools. Workflows initial came out of &#8220;enterprise&#8221; systems to managing web services, which moved into the repository in the hands of the repository managers. They establish, in advance, rule based [...]]]></description>
			<content:encoded><![CDATA[<p>One of the sessions at RIRI &#8217;09, and a common theme across many of the conferences I attended this year, is workflows, workflow engines, and tools. </p>
<p>Workflows initial came out of &#8220;enterprise&#8221; systems to managing web services, which moved into the repository in the hands of the repository managers. They establish, in advance, rule based workflows to manage (primarily) submission and dissemination with the <a href="http://en.wikipedia.org/wiki/Business_Process_Execution_Language">Business Process Execution Language</a> (BPEL). While this may be perfect for describing complex interactions, the burden of creating workflows and additional overhead makes this approach seem like overkill.</p>
<p>From the scientific community comes two more basic workflow systems, Taverna and Kepler. The key difference between these systems and BPEL seems to be the intended audience, which for these two applications are the scientists themselves looking to manage and marshal their data in a manner specific to their needs. At this point, many of the applications seem ad-hoc (although, judging by <a href="http://www.myexperiment.org/workflows">myExperiement</a>, seem to be gathering interest in the scientific community. While certainly applicable to making use of the material in a repository environment, at this point it seems like its application to repository management may be questionable.</p>
<p>A third option is a programmatic workflow engine like <a href="http://openwferu.rubyforge.org/">Ruote</a>, which allows one to specify business processes in either Ruby, JSON, or an XML syntax, and can be linked with Fedora&#8217;s Java Messaging Service using <a href="http://stomp.codehaus.org/Ruby+Client">stomp</a> and some Fedora objects.</p>
<p>After the fold, I&#8217;ve outlined a very basic Ruote workflow for updating a solr search index every time a Fedora object is updated, similar to the GSearch plugin. Forgive my rather ugly Ruby code, this is just a quick sketch of a possible service.<br />
<span id="more-128"></span><br />
Here&#8217;s a simple Fedora jms/ruote driver:</p>
<pre name="code" class="ruby">
#--
# Copyright (c) 2009, Chris Beer, chris@authoritativeopinion.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#++

require 'rubygems'
require 'uri'
require 'cgi'
require 'net/http'
require 'rexml/document'
require 'rest_client'
require 'stomp'
require 'openwfe/engine'
require 'openwfe/participants'
require 'tempfile'
require 'set'

gem 'soap4r'
require 'FedoraAPIMDriver'
require 'FedoraMessage'

$driver = FedoraAPIM.new
$driver.options["protocol.http.basic_auth"] << ['http://localhost:8080/fedora/services/management', 'fedoraAdmin', 'fedora']

#Workflow engine
$engine = OpenWFE::Engine.new(:definition_in_launchitem_allowed => true)

# Participants
$engine.register_participant('file', OpenWFE::FileParticipant)
require 'participants/dam'
require 'participants/solr'
require 'participants/bagit'

#Message queue
client = Stomp::Client.open "stomp://localhost:61613"

client.subscribe('/topic/fedora.apim.update') do |msg|
  begin
    FedoraMessage.new(msg)
  rescue Exception => e
    #log
    puts e
  end
end

client.join
</pre>
<p>This triggers the message handler, which asks a Fedora disseminator for an XML workflow definition (which easily allows us to tailor custom workflows per object type, and with some XSLT magic, per message type):</p>
<pre name="code" class="ruby">
class FedoraMessage

  def initialize( msg )
    @msg = msg
    @doc = REXML::Document.new msg.body
    @repository_uri = REXML::XPath.first( @doc, "//author/uri").text
    @type = REXML::XPath.first( @doc, "//title" ).text
    @pid = REXML::XPath.first( @doc, "//summary" ).text
    @dsID = REXML::XPath.first( @doc, '//category[@scheme="fedora-types:dsID"]/@term' ).to_s

    handle_msg
  end

  #
  # Handle an incoming message
  #
  def handle_msg
    begin
      d = get_definition @pid + '/sdef:WORKFLOW'
      launch_workflow d
      #select $a from <#ri> where $a  <info:fedora/fedora-system:def/relations-external#hasWorkflow> $b
   # rescue
      #log
    end

    if self.respond_to? @type
      self.send @type
    end
  end

  #
  # Get the appropriate workflow definition from the repository
  #
  def get_definition( action = nil, params = {} )
    if action.empty?
      action = CGI::escape(@pid)
    end
    RestClient.get( [@repository_uri, "get", action, @type].compact.join('/') + hash_to_qs(params) )

  end

  def hash_to_qs(args={})
  	if args.empty?
  	  return ''
  	end
    '?' + args.map { |k,v| "%s=%s" % [URI.encode(k.to_s),
URI.encode(v.to_s)] }.join('&#038;')
  end

  #
  # Launch a Ruote workflow process
  #
  def launch_workflow( definition, params={} )
    li = OpenWFE::LaunchItem.new definition

    li.repository_uri = @repository_uri
    li.pid = @pid
    li.type = @type
    li.msg = @msg

    params.each do |k,v|
      li[k] = v
    end

    fei = $engine.launch li
  end

#--
# Relationship workflow handlers
#++
[...]
end
</pre>
<p>The workflow definition returned by this sdef:WORKFLOW may be a way to trigger updating a solr search index (if one wanted to do some more advanced routing outside the scope of gsearch, say):</p>
<pre name="code" class="xml">
<process-definition name="solr">
  <sequence>
<participant ref="solr_prepare"></participant>
    <if test="${field:status} = A">
      <! -- then -->
<participant ref="solr_update"></participant>
      <!-- else -->
<participant ref="solr_purge"></participant>
    </if>
<participant ref="solr_close"></participant>
  </sequence>
</process-definition>
</pre>
<p>and, finally, a couple of small solr participants that make the magic happen:</p>
<pre name="code" class="ruby">
require 'solr'
require 'add_xml_document'

$conn_solr = Solr::Connection.new('http://localhost:8983/solr', :autocommit => :on)

$engine.register_participant(:solr_prepare) do |workitem|
	profile = RestClient.get workitem.repository_uri + "/objects/" +workitem. pid + "?format=xml", :accept => 'text/xml'
    profile = REXML::Document.new profile
    workitem.status = REXML::XPath.first( profile, "//objState").text
end

$engine.register_participant(:solr_update) do |workitem|
    data = RestClient.get workitem.repository_uri + "/get/" + workitem.pid + "/sdef:METADATA/SolrXML"
    doc = Solr::Request::AddXMLDocument.new data
    $conn_solr.post doc
    $conn_solr.commit
end

$engine.register_participant(:solr_purge) do |workitem|
  $conn_solr.delete workitem.pid
end

$engine.register_participant(:solr_close) do |workitem|
  # purge cache?
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://authoritativeopinion.com/blog/2009/08/02/repository-workflows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Video4All: HTML5 &lt;video&gt; alternative [updated]</title>
		<link>http://authoritativeopinion.com/blog/2009/07/07/video4all-html5-alternative/</link>
		<comments>http://authoritativeopinion.com/blog/2009/07/07/video4all-html5-alternative/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 21:37:33 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://authoritativeopinion.com/blog/2009/07/07/video4all-html5-alternative/">chris</span></dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://authoritativeopinion.com/blog/?p=116</guid>
		<description><![CDATA[Earlier this week, Matt Mastracci released his video4all project, which replaces the HTML5 &#60;video&#62; element with a flowplayer-based alternative for non-compatible browsers. Independently, I&#8217;ve been working on bringing the HTML5 javascript API to some video plugins using a javascript wrapper. At this point it is still very basic, but hopefully proves useful or interesting. I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, Matt Mastracci released his <a href="http://grack.com/blog/2009/07/07/more-on-video4all-html5-video-everywhere/">video4all</a> project, which replaces the HTML5 &lt;video&gt; element with a flowplayer-based alternative for non-compatible browsers. Independently, I&#8217;ve been working on bringing the HTML5 javascript API to some video plugins using a javascript wrapper. At this point it is still very basic, but hopefully proves useful or interesting. I&#8217;ve created a <a href="http://authoritativeopinion.com/~chris/video/fp_to_html5.js">basic flowplayer version</a>, which currently requires the <a href="http://prototypejs.org">Prototype</a> javascript library (although should trivially port to the flowplayer subset). This layer supports functionality like play/pause, volume control, seeking/currentTime and metadata as well as more advanced features like cue ranges. Error states and events are not yet supported.</p>
<p>Here is a very <a href="http://authoritativeopinion.com/~chris/video/index.html">basic demo</a> that demonstrates play/pause and seeking to a time. I&#8217;ve only tested this in Safari 4/Firefox 3.5, but I believe it should work in earlier versions. There is some __getter_/__setter__ javascript which likely fails in Internet Explorer (although I am aware of a project that offers a workaround, I haven&#8217;t tried it out yet).</p>
<div class='wp_likes' id='wp_likes_post-116'><a class='like' href="javascript:wp_likes.like(116);" title='' ><img src="http://authoritativeopinion.com/blog/wp-content/plugins/wp-likes/images/like.png" alt='' border='0'/>Like</a><span class='text'></span>
<div class='unlike'><a href="javascript:wp_likes.unlike(116);">Unlike</a></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://authoritativeopinion.com/blog/2009/07/07/video4all-html5-alternative/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
