Archive for the 'Software' Category

16
Jan

ImageMagick Command Line Option of the Day

-auto-orient

Super nice for converting a bunch of digital photographs and the orientation needs to be corrected for viewing (on a digital photo frame in my case).

06
Jan

New CPAN release of WebService::MusicBrainz

0.20 Mon Jan 5th 2009
    - RT Bug 40597 - Slaven
         - Updated Build.PL perl version
    - RT Bug 42169 - pbryan
         - Fixed PUID object creation
         - Added test cases for PUID objects to Track.t

LINK
16
Nov

Open Source Rules

I submitted a patch to the Perl open source web log analyzer called “awstats” and it was recently accepted and applied.  Glad I could contribute to a product that I use.

20
Aug

Finding the correct XPath…

The idea here is that if a <para> is preceded by 1 or more notes, they need to be grouped with the <para> in a <group> node.  The problem is how do you write the Xpath to only grab the <note> nodes which are between the current <para> and the previous <para> node?

Here is the XML:

<?xml version="1.0"?>
<document>
     <note>First note</note>
     <para>First paragraph</para>
     <note>Second note</note>
     <para>Second paragraph</para>
     <note>Third note</note>
     <note>Fourth note</note>
     <para>Third paragraph</para>
</document>

Here is the XSLT template for the <para> node:

<xsl:template match="para">
    <xsl:choose>
        <xsl:when test="local-name(preceding-sibling::*[1]) = 'note'">
            <xsl:variable name="current_para" select="."/>
              <group>
                <spara>
                   <xsl:apply-templates
                        select="preceding-sibling::note[following-sibling::para[1]=$current_para]"/>
                   <para><xsl:value-of select="."/></para>
                </spara>
              </group>
           </xsl:when>
        <xsl:otherwise>
           <group>
               <para><xsl:value-of select="."/></para>
           </group>
        </xsl:otherwise>
     </xsl:choose>
  </xsl:template>

Here is the output XML:

<?xml version="1.0"?>
<document>
  <group>
    <spara>
       <note>First note</note>
       <para>First paragraph</para>
    </spara>
  </group>
  <group>
    <spara>
       <note>Second note</note>
       <para>Second paragraph</para>
    </spara>
  </group>
  <group>
    <spara>
      <note>Third note</note>
      <note>Fourth note</note>
      <para>Third paragraph</para>
    </spara>
  </group>
</document>

The XPath “preceding-sibling::note” gives us everything that is prior to the current <para>.   The “secret sauce” here is that we are applying a filter to include only <para> nodes which have a “following-sibling::para” which matches the current <para> that we are processing.  If anyone has a more elegant solution, I would be interested in seeing it.

13
Aug

YUI and parsing JSON

Am I missing something here?  I started a web app using YUI.  The server can generate XML or JSON as a response.  I started with XML but I found the parsing rather limited.  I switched to JSON using the XML::XML2JSON module on CPAN.  This produces JSON following a convention set up by Google.  It seems that YUI can not parse data in this format.

{"encoding":"UTF-8","version":"1.0",
 "metadata":{
    "artist-list":{
        "artist":{
           "life-span":{"@begin":"1992-02-14"},
           "sort-name":{"$t":"Weezer"},
           "name":{"$t":"Weezer"},
           "@id":"6fe07aa5-fec0-4eca-a456-f29bff451b04",
           "@ext:score":"100",
           "@type":"Group"
         },
     "@count":"1","@offset":"0"
   }}}

I found that I can get around the invalid “$t” and “-” in the name string by using a different syntax for JSON location code which includes using brackets and single quotes instead of periods.

mySearchDataSource.responseSchema = {
          resultsList: "['metadata']['artist-list']['artist']",
          fields: ["['sort-name']['$t']", "['@type']", "['@ext:score']"],
                 metaFields: {
                    totalRecords: "['metadata']['artist-list']['@count']"
                 }
             };

But YUI still does not like the “@” in the front of names and the “:” in the middle of a name.

I guess I have these choices:

  1. Switch server response to XML.  Write custom parseXMLData method for YUI DataSource.
  2. Write my own parseJSONData method for YUI DataSource.
  3. Write my own XML -> JSON conversion which constucts JSON data that YUI is happy with.
  4. Server side hack to “clean” JSON data of any offending characters.

Now I’m off to do some more research on this…

07
Aug

Blurb.com Recommendation

I recently composed a book of wedding photos through blurb.com.  Now that I have the book printed, I have to say that I am really impressed with this service.  The desktop software used to compose the book is easy to use and very intuitive.  The software was definitely sluggish running on my G4 iMac but it was usable.  The printed book is very high quality.  I chose to get the “Hardcover, ImageWrap” type of book it really is impressive.  Just thought I would pass along this recommendation for this service.  I plan to use this in the future for other photo books now that I have seen the results.

02
Jun

YUI DataSource parseXMLData improved

While working with the YUIDataSource“, I wanted to feed web service generated XML to the user interface which would then populate a YUI “DataTable”.  The default “parseXMLData” function that comes with YUI seems rather limited.  It will handle fetching a “resultNode” and any child nodes which have text data and also attributes of the “resultNode”.  So XML like this works OK.

<artist-list count="1" offset="0">
     <artist id="6fe07aa5-fec0-4eca-a456-f29bff451b04" type="Group" ext:score="100">
         <name>Weezer</name>
         <sort-name>Weezer</sort-name>
     </artist>
</artist-list>

Using the default “parseXMLData”, I could retrieve any of the attributes or child node text of the <artist> node.  But what about XML like this?

<artist-list count="1" offset="0">
     <artist id="6fe07aa5-fec0-4eca-a456-f29bff451b04" type="Group" ext:score="100">
          <name>Weezer</name>
          <sort-name>Weezer</sort-name>
          <life-span begin="1992-02-14"/>
     </artist>
</artist-list>

In this example, the “begin” attribute is not accessible to me.  But I have a patch that makes it work.  I thought the introduction of XPath would be the correct way to express what value to access in the XML.  Granted the patch is very limited and does not implement all possible XPath possibilities but it’s a start.

        myDataSource.responseSchema = {
                  resultNode: 'artist',
                  field:  ["sort-name",
                            "type",
                            {xpath:"life-span/@begin", key:"begin"},
                            {xpath:"life-span/@end", key:"end"},
                            {key:"ext:score", parser:YAHOO.util.DataSource.parseNumber},
                             "id"]};

Another issue I have with “parseXMLData” is when the “resultNode” and the “field” are the same.

<artist id="070d193a-845c-479f-980e-bef15710653e" type="Person">
   <name>Prince</name>
   <sort-name>Prince</sort-name>
   <life-span begin="1958-06-07"/>
   <alias-list>
       <alias>The Artist Formerly Known as Prince</alias>
       <alias>Symbol</alias>
       <alias>Formerly Prince</alias>
       <alias>T.A.F.K.A.P.</alias>
     </alias-list>
</artist>
myDataSource.responseSchema = {  resultNode: 'alias', field: ['alias'] };

A simple patch to “parseXMLData” handles this scenario by checking if the “resultNode” is equal to the current field, then return the “nodeValue”.

Download patch here

09
May

Javascript Library Analysis

A quick pros/cons analysis…

Dojo – Well written and has many features but poor documentation.  There is an O’Reilly book coming out so this will definitely help.

jQuery – Lightweight, good amount of features but not sure I want to invest the time to handle the learning curve of the unique style of Javascript.

YUI – Many features and I’m impressed with the good documentation.