Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-10 of 115 total  RSS 

Adding helpful error messages to your Ruby code

This Ruby code raises an error if the XPath query fails because the attribute being queried did not exist for the given element.

  def map_pattr(node, fieldx, valuex)
    begin
    parameter = node.root.elements["parameter[@field='#{fieldx}']"]
    parameter.add_attribute('value', valuex)
    parameter
    
    rescue
      puts 'feedpopulated.rb: map_attr() the field ' + fieldx + ' was not found in params.'
      raise
    end
  end

Notice that a raise statement is used to ensure that the system error message is raised and any further code execution is halted.

Without adding a customized helpful message I would be left scratching my head trying to work out what the following system error message meant.
./feedpopulated.rb:27:in `map_pattr': undefined method `add_attribute' for nil:NilClass (NoMethodError)
     from ./feedpopulated.rb:51:in `create_record'
     from ./feedpopulated.rb:49:in `each'
     from ./feedpopulated.rb:49:in `create_record'
     from ./recordx.rb:91:in `call_create'
     from ./s3fileuploader_handler.rb:14:in `call'
     from ./s3fileuploader_handler.rb:40:in `invoke'
     from ./uploadtwitteraudio.rb:22:in `initialize'
     from /usr/lib/ruby/1.8/rexml/element.rb:890:in `each'
     from /usr/lib/ruby/1.8/rexml/xpath.rb:53:in `each'
     from /usr/lib/ruby/1.8/rexml/element.rb:890:in `each'
     from ./uploadtwitteraudio.rb:18:in `initialize'
     from ./uploadtwitteraudio.rb:72:in `new'
     from ./uploadtwitteraudio.rb:72


Reference: Programming Ruby: The Pragmatic Programmer's Guide - Exceptions, Catch, and Throw [ruby-doc.org]

Helpful XPath examples

A few XPath examples copied from XPath Syntax [w3schools.com]

Predicates
/bookstore/book[1] 	# Selects the first book element that is the child of the bookstore element. 
                        # Note: IE5 and later has implemented that [0] should be the first node, 
                        # but according to the W3C standard it should have been [1]!!
/bookstore/book[last()] 	# Selects the last book element that is the child of the bookstore element
/bookstore/book[last()-1] 	# Selects the last but one book element that is the child of the bookstore element
/bookstore/book[position()<3] 	# Selects the first two book elements that are children of the bookstore element
//title[@lang] 	# Selects all the title elements that have an attribute named lang

Selecting Unknown Nodes
/bookstore/* 	# Selects all the child nodes of the bookstore element
//* 	# Selects all elements in the document
//title[@*] 	# Selects all title elements which have any attribute

Selecting Several Paths
//book/title | //book/price  	# Selects all the title AND price elements of all book elements

Using ruby to upload multiple files to Amazon S3

This ruby code builds upon the code S3 upload client for Ruby [dzone.com] by reading the account details and file details from XML files.

#!/usr/bin/env ruby
#file : rubys3file2upload.rb

require 'rubygems'
require 'aws/s3'
require 'rexml/document'
include REXML

class S3FileUpload

  def initialize(xml_accounts_file, xml_upload_file)
    initialize_account(xml_accounts_file)
    main(xml_upload_file)
  end

  def initialize_account(accounts_file)

    file = File.new(accounts_file)
    doc = Document.new(file)

    account = doc.root.elements['records/access']
    h = Hash.new
    h[:access_key_id] = account.elements['key_id'].text.to_s
    h[:secret_access_key] = account.elements['secret'].text.to_s
    AWS::S3::Base.establish_connection!(h)

  end

  def main(xml_upload_file)
    file = File.new(xml_upload_file)
    doc = Document.new(file)
puts doc
    doc.root.elements.each('records/file') do |f|
      local_file = f.elements['local'].text.to_s
      bucket = f.elements['bucket'].text.to_s
      mime_type = f.elements['mime_type'].text.to_s
      upload(local_file, mime_type, bucket)
    end
  end

  def upload(local_file, mime_type, bucket)

    base_name = File.basename(local_file)

    puts "Uploading #{local_file} as '#{base_name}' to '#{bucket}'"

    AWS::S3::S3Object.store(
      base_name,
      File.open(local_file),
      bucket,
      :content_type => mime_type,
      :access => :public_read
    )

    puts "Uploaded!"
  end

end

if __FILE__ == $0
  s3fu = S3FileUpload.new('s3accounts.xml', 's3files2upload.xml')
end


file: s3accounts.xml
<s3accounts>
  <summary/>
  <records>
    <access id="100"><name>REPLACE_ME</name><key_id>REPLACE_ME</key_id><secret>REPLACE_ME</secret></access>
  </records>
</s3accounts>


file: s3files2upload.xml
<s3files2upload>
  <summary/>
  <records>
    <file>
      <local>autocomplete.html</local>
      <bucket>t2000</bucket>
      <mime_type>text/html</mime_type>
    </file>
    <file>
      <local>autocomplete2.html</local>
      <bucket>t2000</bucket>
      <mime_type>text/html</mime_type>
    </file>
    <file>
      <local>autocomplete3.html</local>
      <bucket>t2000</bucket>
      <mime_type>text/html</mime_type>
    </file>
  </records>
</s3files2upload>


Note: The file given the correct permission could be read from http://t2000.s3.amazonaws.com/autocomplete.html

Reference: http://amazon.rubyforge.org/

Adding style to SVG

To reference a CSS file within an SVG file refer to the following example code.

<?xml-stylesheet href="styles_austria_1.css" type="text/css"?> 

Here's what an SVG CSS file looks like.
.str1 {stroke:#0093DD;stroke-width:16;color:#0093DD}
.str2 {stroke:#0093DD;stroke-width:12}
.str3 {stroke:#0093DD;stroke-width:10}
.str4 {stroke:#0093DD;stroke-width:6}

.str0 {stroke:#DA251D;stroke-width:55;color:#DA251D}
.str6 {stroke:#BB90BB;stroke-width:44;color:#BB90BB}
.str5 {stroke:#0093DD;stroke-width:4}
.str7 {stroke:#1F1A17;stroke-width:13}

.fil0 {fill:none}
.fil2 {fill:#1F1A17}
.fil1 {fill:#C4E5FA}
.fil3 {fill:#FFFFFF}


Source: Example for using CSS-Styles [carto.net]
Reference: Styling - SVG 1.1 - 20030114 [w3.org]

Converting text to SVG

First of all the Ruby code reads the text, splits it into an array and then saves it in XML format.
require 'rexml/document'
include REXML

a = "Open source is a development method for software that harnesses the power of distributed peer 
review and transparency of process. The promise of open source is better quality, higher reliability, 
more flexibility, lower cost, and an end to predatory vendor lock-in.".split(' ') 

doc = Document.new
doc.add_element('text')
oline = Element.new('line')

char_count = 0
a.each do |word|
  
  oword = Element.new('word')
  oword.text = word.to_s
  oword.add_attribute('length',char_count)
  oline << oword 
  char_count += word.length
  
  if char_count > 50
    doc.root << oline
    oline = Element.new('line')
    char_count = 0
  end
end
doc.root << oline
puts char_count
puts doc

Here's a sample of the XML created
<text>
  <line>
    <word length='0'>Open</word><word length='4'>source</word><word length='10'>is</word>
    <word length='12'>a</word><word length='13'>development</word><word length='24'>method</word>
    <word length='30'>for</word><word length='33'>software</word><word length='41'>that</word>
    <word length='45'>harnesses</word>
  </line>
  <line>
    <word length='0'>the</word><word length='3'>power</word>
    <word length='8'>of</word><word length='10'>distributed</word><word length='21'>peer</word>
    <word length='25'>review</word><word length='31'>and</word><word length='34'>transparency</word>
    <word length='46'>of</word><word length='48'>process.</word>
  </line>
  <line>
    <word length='0'>The</word>
    <word length='3'>promise</word><word length='10'>of</word><word length='12'>open</word>
    <word length='16'>source</word><word length='22'>is</word><word length='24'>better</word>
    <word length='30'>quality,</word><word length='38'>higher</word><word length='44'>reliability,</word>
  </line>
  <line>
    <word length='0'>more</word><word length='4'>flexibility,</word><word length='16'>lower</word>
    <word length='21'>cost,</word><word length='26'>and</word><word length='29'>an</word>
    <word length='31'>end</word><word length='34'>to</word><word length='36'>predatory</word>
    <word length='45'>vendor</word>
  </line>
  <line>
    <word length='0'>lock-in.</word>
  </line>
</text>

The XML is then transformed to SVG using the following XSL file
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output encoding="UTF-8"
            method="xml"
            indent="yes"/>
            
  <xsl:template match="text">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%"
                  xmlns:xlink="http://www.w3.org/1999/xlink" >
      <g id="sketch" class="sketch">
        <xsl:apply-templates select="line"/>
      </g>
    </svg>
  </xsl:template>
  
  <xsl:template match="line">
    <xsl:variable name="xfactor">12</xsl:variable>
    <xsl:variable name="yfactor">20</xsl:variable>
    <xsl:variable name="pos" select="position()"></xsl:variable>
    <xsl:apply-templates select="word">
      <xsl:with-param name="xfactor" select="$xfactor"></xsl:with-param>
      <xsl:with-param name="y" select="$pos * $yfactor + 10"></xsl:with-param>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="word">
    <xsl:param name="xfactor"/>
    <xsl:param name="y"/>
    <text xmlns="http://www.w3.org/2000/svg" font-size="12pt" x="{@length * $xfactor +10}" y="{$y}" id="t1"><xsl:value-of select="."/></text>
  </xsl:template>
</xsl:stylesheet>

The final SVG output [twitxr.com] shows 5 lines of text with each word as a separate SVG text element.

Append an XML element using the append operator

This Ruby code appends an XML node to an XML document using the append << operator.
      doc2 = Document.new(xml_svg)
      obody.text = ''
      obody << doc2.root

In this example the original obody.text contained escaped xml, which was then initialised as an XML document and appended to obody to be processed as pure XML.

Using XSLT to generate SVG

This XSL file is intended to be used as an SVG XSL template file which displays SVG content using Gorg (XSLT back-end processor).
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output encoding="UTF-8"
            method="xml"
            indent="yes"/>
            
  <xsl:template match="mainpage">
  <svg xmlns="http://www.w3.org/2000/svg" width="100%"
                xmlns:xlink="http://www.w3.org/1999/xlink" >

    <g>
    <text font-size="12pt" x="50" y="50" id="t2" stroke="olive"><xsl:value-of select="title"/></text>
    </g>

  </svg>
  </xsl:template>
</xsl:stylesheet>


Reference: 'using XSLT to generate SVG' http://snurl.com/24pwo [carto.net]

Instruct a shared whiteboard to save and refresh

The following code used with the ProjectX API informs the client web browser that the whiteboard will be refreshed in 5 seconds. It then archives the current whiteboard information, formats it, and sends a message to each web browser to refresh their view.

<project name="whiteboardqueue">
  <methods>
    <method name="create">
      <params>
        <param var="type">ecmascript</param>
        <param var="body">startRefresh(5)</param>
        <param var="sender">system</param>
      </params>
    </method>
    <method name="timer">
      <params>
        <param var="timer">5</param>
      </params>
    </method>
    <method name="archive_and_format">
      <params/>
    </method>
    <method name="create">
      <params>
        <param var="type">ecmascript</param>
        <param var="body">reloadDocument()</param>
        <param var="sender">system</param>
      </params>
    </method>
  </methods>
</project>


*update 1:14am*
The whiteboard demo [rorbuilder.info] allows the user to draw using the mouse within the web browser which renders SVG. Tested on Flock and Firefox.

*update 4:42pm 28 Mar 08*
You can also view the whiteboard message queue [rorbuilder.info].

*update 6:29pm Mar 08*
I've created a short url (http://rubyurl.com/vxHD) (to demonstrate the cleaning of the whiteboard) which redirects to this http://rorbuilder.info/api/projectx.cgi?xml_project=<project name="whiteboardqueue"><methods><method name="create"><params><param var="type">ecmascript</param><param var="body">startRefresh(5)</param><param var="sender">system</param></params></method><method name="timer"><params><param var="timer">5</param></params></method><method name="archive_and_format"><params/></method><method name="create"><params><param var="type">ecmascript</param><param var="body">reloadDocument()</param><param var="sender">system</param></params></method></methods></project>

I've

Load PRX document and display elements

//Using a simple curl library (not shown) to get xml text
$curl = new CURL();
//$prx contains the url of a PRX document (e.g. http://www.prxbuilder.com/link.aspx?p=1)
$xml = $curl->get($prx);

//Load the XML file
$doc = new DOMDocument();
$doc->loadXML($xml);

//Retrieve specific PRX elements (subheadline, dateline, body)
$subheadline = $doc->getElementsByTagName('subheadline')->item(0)->nodeValue;
$dateline = $doc->getElementsByTagName('dateline')->item(0)->nodeValue;
$body = $doc->getElementsByTagName('body')->item(0)->nodeValue;

//Format and display - apply_filters is a WP function.
$content = '<p>'.$subheadline.'</p>';
$content .= '<p>'.$dateline.'</p>';
$content .= '<p>'.$body.'</p>';
$content = apply_filters('the_content_rss', $content);
$content = str_replace(']]>', ']]&gt;', $content);

echo $content;

Load PRX document and display elements

//Using a simple curl library (not shown) to get xml text
$curl = new CURL();
//$prx contains the url of a PRX document (e.g. http://www.prxbuilder.com/link.aspx?p=1)
$xml = $curl->get($prx);

//Load the XML file
$doc = new DOMDocument();
$doc->loadXML($xml);

//Retrieve specific PRX elements (subheadline, dateline, body)
$subheadline = $doc->getElementsByTagName('subheadline')->item(0)->nodeValue;
$dateline = $doc->getElementsByTagName('dateline')->item(0)->nodeValue;
$body = $doc->getElementsByTagName('body')->item(0)->nodeValue;

//Format and display - apply_filters is a WP function.
$content = '<p>'.$subheadline.'</p>';
$content .= '<p>'.$dateline.'</p>';
$content .= '<p>'.$body.'</p>';
$content = apply_filters('the_content_rss', $content);
$content = str_replace(']]>', ']]&gt;', $content);

echo $content;

« Newer Snippets
Older Snippets »
Showing 1-10 of 115 total  RSS