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 21-30 of 170 total

Using TTS to read a text file with Asterisk

This configuration reads a text file (limiting it to 130 characters or less) and then speaks the message to the caller.

exten => 3200,1,ReadFile(test=/tmp/test.txt,130)
exten => 3200,n,Festival(${test})
exten => 3200,n,Hangup

Using text-to-speech in Asterisk

Use instructions to get Asterisk to use text-to-speech. Tested on Ubuntu 8.04 Sever.

*packages required*
festival
festvox-rablp16k

file: extensions.conf
detail
exten => 3250,1,Answer()
exten => 3250,n,Festival('hello world')
exten => 3250,n,Hangup


From the command-line type 'festival --server'
Then restart Asterisk

Simple Bluetooth Proximity

Following on from my earlier investigation into bluetooth proximity, I wanted something which returned a value which could be used to determine distance. The output from hcitool rssi ranges from 0 for close object down to -10 for far away objects.

rfcomm connect 0 00:12:D1:E6:57:BE

hcitool rssi 00:12:D1:E6:57:BE


Proximity Results:
-4 .. 0 : Bedroom - nearest to my bed
-4 .. -6 : Hallway
-8 .. -9 : Livingroom - on the computer desk
-9 .. -10 : Livingroom - nearest to the window

Executing a Ruby script from Asterisk

To run a Ruby script from Asterisk you need 2 things 1) an extension to run the script from 2) a Ruby script.

* Preparing the evironment *
1) create a script directory for Asterisk and ensure it has permission to run the scripts.

* Running the script *
1) Dial extension 3000
2) Listen to the voice say 'hello world'
3) Observe a new output.txt file has been created containing the message 'hello world!'

file: hello-world.rb
#!/usr/bin/ruby

#file : hello-world.rb

file = File.new('/etc/asterisk/ruby/output.txt','w')
file.puts 'hello world!'
file.close

file: extensions.rb
exten => 3000,1,Playback(hello-world)
exten => 3000,n,System(/etc/asterisk/ruby/./hello-world.rb)
exten => 3000,n,Hangup


file: output.txt
hello world!

Configuring Asterisk to phone you

The following instructions to call a telephone extension were copied into a file within the /var/spool/asterisk/outgoing file directory.
Channel: SIP/line1
MaxRetries: 2
RetryTime: 60
WaitTime: 30
Context: my-phones
Extension: 10

The extension 10 initiates the call to phone line1 within the context of my-phones.

Configuring Asterisk as a Jabber client

Here's my working instructions to connect my Asterisk box as a client to my Jabber server. When a call comes in on extension 10 a message is sent to me.


file: jabber.conf
[general]
debug=yes                               ;;Turn on debugging by default.
autoprune=no                            ;;Auto remove users from buddy list.
autoregister=yes                        ;;Auto register users from buddy list. 

[asterisk]                              ;;label
type=client                             ;;Client or Component connection
serverhost=jamesrobertson.eu
                                        ;;      talk.google.com
username=asterisk@jamesrobertson.eu/Home        ;;Username with optional roster.

secret=XXXXXXXX                         ;;Password
port=5222                               ;;Port to use defaults to 5222
usetls=no                               ;;Use tls or not
;usesasl=yes                            ;;Use sasl or not
buddy=james@jamesrobertson.eu
statusmessage="I am available"          ;;Have custom status message for
                                        ;;Asterisk.
timeout=100                             ;;Timeout on the message stack.


file: extensions.conf
exten => 10,1,JABBERSend(asterisk,james@jamesrobertson.eu, Call from ${CALLERID(name)} at number <${CALLERID(num)}> on ${STRFTIME(,GMT-1,%A %B %d %G at %l:%M:%S %p)} )
exten => 10,n,Macro(stdexten,100,100)



output (observed in my chat window from user Asterisk)
Call from Line 1 - Home at number <6200> on Sunday May 18 2008 at 8:53:24 PM

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

Creating a bucket in Amazon S3 through an irb session

1) Log into an irb session, and enter your S3 login details.
require 'rubygems'
require 'aws/s3'

  AWS::S3::Base.establish_connection!(
    :access_key_id     => 'REPLACE_ME',
    :secret_access_key => 'REPLACE_ME'
  )

output:
=> #<AWS::S3::Connection:0xb75e0594 @http=#<Net::HTTP s3.amazonaws.com:80 open=false>, @secret_access_key="", @options={:server=>"s3.amazonaws.com", :access_key_id=>"", :port=>80, :secret_access_key=>"", :persistent=>true}, @access_key_id="19S45GYAGWK8DC2B8VG2">

2) Browse the existing buckets.
AWS::S3::Service.buckets

output:
=> [#<AWS::S3::Bucket:0xb75cc850 @object_cache=[], @attributes={"name"=>"ogg.twitteraudio.com", "creation_date"=>Sat Apr 26 10:40:16 UTC 2008}>, #<AWS::S3::Bucket:0xb75cc83c @object_cache=[], @attributes={"name"=>"t1000", "creation_date"=>Fri Apr 25 21:35:21 UTC 2008}>, #<AWS::S3::Bucket:0xb75cc814 @object_cache=[], @attributes={"name"=>"t2000", "creation_date"=>Fri Apr 25 21:53:15 UTC 2008}>]

3) Browse the buckets in a programmatical way.
AWS::S3::Service.buckets.each {|b| puts b.name}

output:
ogg.twitteraudio.com
t1000
t2000


4) Add a new bucket called t3000.
AWS::S3::Bucket.create('t3000')

output:
=> true

5) Observe adding the bucket again doesn't cause an error.
AWS::S3::Bucket.create('t3000')

output:
=> true

6) View the buckets again.
AWS::S3::Service.buckets

output:
=> [#<AWS::S3::Bucket:0xb75cc850 @object_cache=[], @attributes={"name"=>"ogg.twitteraudio.com", "creation_date"=>Sat Apr 26 10:40:16 UTC 2008}>, #<AWS::S3::Bucket:0xb75cc83c @object_cache=[], @attributes={"name"=>"t1000", "creation_date"=>Fri Apr 25 21:35:21 UTC 2008}>, #<AWS::S3::Bucket:0xb75cc814 @object_cache=[], @attributes={"name"=>"t2000", "creation_date"=>Fri Apr 25 21:53:15 UTC 2008}>]

Note: You would expect t3000 to be in there however it didn't appear possibly because of the bucket permissions.

7) Let's then look for bucket t3000.
t3000 = AWS::S3::Bucket.find('t3000')

output:
=> #<AWS::S3::Bucket:0xb76df724 @object_cache=[], @attributes={"prefix"=>nil, "name"=>"t3000", "marker"=>nil, "max_keys"=>1000, "is_truncated"=>false, "xmlns"=>"http://s3.amazonaws.com/doc/2006-03-01/"}>

8) Now that we've found the bucket let's upload a text file called works.txt.
file = "works.txt"

output:
=> "works.txt"
AWS::S3::S3Object.store(file, open(file), 't3000', :access => :public_read)

output:
=> #<AWS::S3::S3Object::Response:0x-608926458 200 OK>

9) Setting the file access to :public_read allows us to view the file from the http location http://t3000.s3.amazonaws.com/works.txt

References:
http://amazon.rubyforge.org/
upload_to_s3 - Ruby S3 upload client [dzone.com]

*update: 14:30 30 April 2008 *
I didn't use Bucket.objects(:reload) which is the reason why the bucket t3000 didn't show up with the statement Service.buckets

Reference: spatten design - Amazon S3, Ruby and Rails slides [spattendesign.com]

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/
« Newer Snippets
Older Snippets »
Showing 21-30 of 170 total