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

About this user

James Robertson http://www.r0bertson.co.uk

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

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/

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.

Deleting a redundant shape message from the whiteboard queue

This code is used to remove a message from the whiteboard queue containing a shape which has recently moved it's position (x and y coordinates) on the board. Code extract from whiteboardqueue.rb

  def call_delete_shape(params)
    #get the shape's message id.
    doc = Document.new(params)
    shape_id = doc.root.elements["param[@var='id']"].text.to_s
    initialize_doc

    doc_xml = Document.new(decode2(@doc_file.root.to_s))
    id = doc_xml.root.elements["records/message/body/*[@id='#{shape_id}']"].parent.parent.attributes.get_attribute('id')
    delete_record(id)
    save_file
  end


*update 10:04pm*
Added the link to the project code http://github.com/jrobertson/whiteboardqueue/tree

Save a Ruby source text file to XML.

This code will output a text file as an XML file which can later be transformed into an HTML file using a back-end XSLT processor called Gorg.

#!/usr/bin/ruby 

#file: rubytxt2xml.rb

require 'rexml/document'
include REXML

class RubyTxt2XML
  
  def rubytxt2xml(h)
    h[:infilepath] = './' if h[:infilepath].nil?
    h[:outfilepath] = './' if h[:outfilepath].nil?
    h[:xmlfile] = h[:sourcefile][/^(.*)\.\w+$/,1] + '.xml' if h[:xmlfile].nil?
    buffer = File.new(h[:infilepath] + h[:sourcefile],'r').read
    
    doc = Document.new
    doc.add_element('ruby_txt')
    body = Element.new('source')
    body.text = CData.new(buffer)
    doc.root.add_element(body)
    
    file = File.new(h[:outfilepath] + h[:xmlfile],'w')
    file.puts doc
    file.close
    
  end
end

if __FILE__ == $0
  rt2x = RubyTxt2XML.new
  rt2x.rubytxt2xml(:sourcefile  => 'rubytxt2xml.rb')
end

output:
<ruby_txt>
  <source>
    <![CDATA[
      #!/usr/bin/ruby 

      #file: rubytxt2xml.rb

      require 'rexml/document'
      include REXML

      class RubyTxt2XML
        
        def rubytxt2xml(h)
          h[:infilepath] = './' if h[:infilepath].nil?
          h[:outfilepath] = './' if h[:outfilepath].nil?
          h[:xmlfile] = h[:sourcefile][/^(.*)\.\w+$/,1] + '.xml' if h[:xmlfile].nil?
          buffer = File.new(h[:infilepath] + h[:sourcefile],'r').read
          
          doc = Document.new
          doc.add_element('ruby_txt')
          body = Element.new('source')
          body.text = CData.new(buffer)
          doc.root.add_element(body)
          
          file = File.new(h[:outfilepath] + h[:xmlfile],'w')
          file.puts doc
          file.close
          
        end
      end

      if __FILE__ == $0
        rt2x = RubyTxt2XML.new
        rt2x.rubytxt2xml(:sourcefile  => 'rubytxt2xml.rb')
      end
    ]]>
  </source>
</ruby_txt>

ProjectX client-side code

This Ruby code uses a unified XML format to create a password record on a web server. It's intended to be run as a batch file which gets called from another Ruby application called maintain_projectx which gets called from a cronjob.

In this example the password is stored on the server not for authentication but simply to provide a reminder service in the event the user forgets it.

require 'net/http'
require 'rexml/document'
include REXML

class ProjectXClient
  attr :doc
  def initialize(raw_url)
    url = URI.escape(raw_url)
    xml_data = Net::HTTP.get_response(URI.parse(url)).body
    @doc = Document.new(xml_data)
  end
  
end

if __FILE__ == $0

  xml_project = <<PROJECT
  <project name='password'>
    <method name='create'>
      <params>
        <param var='password' val='p6789c'/>
        <param var='title' val='hotmail'/>
      </params>
    </method>
  </project>
PROJECT
  
  pxc = ProjectXClient.new("http://yourdomain.com/p/projectx.cgi?xml_project=" + xml_project)
  doc = pxc.doc
  puts doc
    
end


output -what's returned from the server is an XML response containing a result. The result echos the method executed and the output from that method, which in this instance is the xml record node 'entry'.
<result method='rtn_create'>
  <append id='19367'>
    <entry id='19367'>
      <password>p6789c</password>
      <title>hotmail</title>
      <description/>
    </entry>
  </append>
</result>


Scrape an XHTML document using Ruby

A simple Ruby script to scrape an XHTML file with the selected content being saved to an xml file ready for transformation into an RSS feed. This example uses the XHTML file from http://newsgang.net/audio/ which is then saved locally as 'thegang.xml'.

#!/usr/bin/ruby
# file: thegang.rb

require 'rexml/document'
include REXML

class TheGang
  def initialize()
  end
  
  def rssify()
    file = File.new('thegang.xml','r')
    doc = Document.new(file)
    rss_doc = Document.new
    root = Element.new('rss')
    rss_doc.add_element(root)
    
    doc.root.elements.each("body/div/ul/li/h2/a") do |node|    
      o_rssitem = Element.new('item')
      o_li = node.parent.parent
      
      o_rsstitle = Element.new('title')
      o_rsstitle.text = node.text.gsub(/[\n,' ']/,'')
      o_rssitem.add_element(o_rsstitle)
      
      o_rsshref_audio = Element.new('href_audio')
      o_rsshref_audio.text = node.attributes.get_attribute('href').to_s.gsub('amp;&','')      
      o_rssitem.add_element(o_rsshref_audio)
      
      o_rsshref = Element.new('href')
      o_rsshref.text = o_rsshref_audio.text.gsub('&amp;from=audio','')      
      o_rssitem.add_element(o_rsshref)
      
      o_rssdate = Element.new('date')
      o_rssdate.text = "#{o_li.elements["p/span[1]"].text} #{o_li.elements["p/span[2]"].text}"
      o_rssitem.add_element(o_rssdate)
      rss_doc.root.add_element(o_rssitem)
      
    end

    file = File.new('thegang_rss.xml','w')
    file.puts rss_doc
    file.close
  end
end


if __FILE__ == $0
  gang = TheGang.new
  gang.rssify
end


see also: www.dapper.net

output (extract)
<rss>
  <item><title>TheGangXII-II</title><href_audio>/gangitem/id=6501&amp;from=audio</href_audio><href>/gangitem/id=6501</href><date>Jan 25</date></item>
  <item><title>TheGangXII-I</title><href_audio>/gangitem/id=6499&amp;from=audio</href_audio><href>/gangitem/id=6499</href><date>Jan 25</date></item>
  <item><title>NewsGangLive01.24.08</title><href_audio>/gangitem/id=6445&amp;from=audio</href_audio><href>/gangitem/id=6445</href><date>Jan 24</date></item>
  <item><title>NewsGangLiveII</title><href_audio>/gangitem/id=6377&amp;from=audio</href_audio><href>/gangitem/id=6377</href><date>Jan 23</date></item>
  ...
</rss>

Automate the insertion of text into a file.

This example updates an xsl file with a new xsl:include declaration, and with a javascript header declaration. It reads 'guide.xsl' as a text file, and reads the template 'guide_ptemplate.xml' as a rexml document.

#!/usr/bin/ruby
#file: create add2guide_xsl.rb

require 'rexml/document'
include REXML

class Add2GuideTxt
  def initialize
    @guide = 'guide.xsl'
    @guide_template = 'guide_ptemplate.xml'
  end
  
  def insertText(project)
    # read guide.txt and return the buffer
    buffer = readGuide(@guide)    
    replaceBuffer(project, buffer, @guide) if not buffer.match("<xsl:include href='/xsl/#{project}.xsl'/>")
  end
  
  def replaceBuffer(project, buffer, output_file)
    # read guide_ptemplate.xsl and return the doc
    doc = readGuideTemplate(@guide_template)    
    # read the xsl:include
    xsl_include = buildIncludeTemplate(project, doc)
    # read the xsl:if
    xsl_if = buildIfTemplate(project,doc)
    
    eoi = "<!-- </xsl_includes> -->"
    buffer = buffer.gsub(eoi, "#{xsl_include}\n" + eoi)
    eoj = "<!--</xsl_javascript> -->"
    buffer = buffer.gsub(eoj, "\n#{xsl_if}\n" + eoj)
    
    file = File.new(output_file,'w')
    file.puts buffer.gsub("&quot;","'")
    file.close
  end
  
  def buildIncludeTemplate(project, doc)
    xsl_include = doc.root.elements['xsl:include']
    xsl_include.attributes['href'] = '/xsl/' + project + '.xsl'
    xsl_include
  end
  
  def buildIfTemplate(project, doc)
    xsl_if = doc.root.elements['xsl:if']
    xsl_if.attributes['test'] = project
    xsl_if.elements['script[3]'].text = 'const ProjectX = "' + project + '";'
    xsl_if
  end
  
  def readGuide(filename) 
    file = File.new(filename,'r')
    buffer = file.read
    file.close
    buffer
  end
  
  def readGuideTemplate(filename) 
    file = File.new(filename)
    Document.new(file)
  end
  
end

if __FILE__ == $0
  a2g = Add2GuideTxt.new
  #add the new project to the guide.xsl file  
  a2g.insertText('tasks')
end


file: guide.xsl (target file)
<!-- <xsl_includes> -->

<!-- <xsl_car_log.xsl/> -->
<xsl:include href="/xsl/car_log.xsl"/>
<!-- </xsl_includes> -->

...

<xsl:if test="car_logpage|car_log">
  <script type="text/javascript" src="/p/js/edit_recordx.js"></script>
  <script type="text/javascript" src="/p/js/itasks5.js"></script>
  <script type="text/javascript">const ProjectX = "car_log";</script>
</xsl:if>
<!--</xsl_javascript> -->

file: guide_ptemplate.xml (template used to insert blocks of code into guide.xsl)
<template>
  <xsl:include href="[x]"/>
  <xsl:if test="[x]">
    <script type="text/javascript" src="/p/js/edit_recordx.js"></script>
    <script type="text/javascript" src="/p/js/itasks5.js"></script>
    <script type="text/javascript">[x]</script>
  </xsl:if>
</template>

Unify the handling of XML records

This Ruby code creates, updates or deletes an XML record, using a hash, record handling objects, and XML to invoke the correct method.

#file: recordx_handler.rb
require 'recordx'

class RecordX_Update < RecordX
  def call(params)
    #todo: write the code to read the xml parameter string
    update_record(h)
    save_file 
  end
end

class RecordX_Create < RecordX
  def call(params)
    #todo: write the code to read the xml parameter string  
    create_record(h)
  end
end

class RecordX_Delete < RecordX
  def call(params)
    doc = Document.new(params)
    node = doc.root.elements["param[@var='id']"]
    puts node
    id = node.attributes.get_attribute('val').to_s
    delete_record(id)
    puts 'deleted record ' + id
    save_file
  end
end

class RecordX_handler
  def invoke(method, params)
    h = Hash.new
    h["create"] = RecordX_Create.new
    h["update"] = RecordX_Update.new
    h["delete"] = RecordX_Delete.new
    h[method].call(params)
  end
end

if __FILE__ == $0
  xml_method = "<method name='delete'><params><param var='id' val='17648' /></params></method>"
  doc = Document.new(xml_method)
  method = doc.root.attributes.get_attribute('name').to_s
  params = doc.root.elements['params'].to_s

  rh = RecordX_handler.new
  rh.invoke(method, params)
end


This code is intended to be called by a Ruby CGI script which can simply relay the cgi post argument to the recordx_handler object.

Deleting an xml node from a REXML::document

// Reads an XML file, then deletes the root element's 1st child element.

require 'rexml/document'
include REXML

file = File.new('journal250907.xml')
doc = Document.new(file)

puts doc

o_element = Element.new('abc')
o_element.text = "123"

o_node = doc.elements['journal/entry']

o_node.parent.delete(o_node)
« Newer Snippets
Older Snippets »
Showing 1-10 of 11 total  RSS