wiki:XmlRpcPlugin/Ruby

Using XMLRPC from Ruby

You can either use the XML-RPC functionality included in the Ruby Standard Library or download the trac4r library which does all the trivial stuff for you.

Please refer to the SSL Support section if you need one.

See also: XmlRpcPlugin

trac4r Example

This example uses trac4r:

require 'trac4r'
# initialize the connection: username and password can be omitted if not needed
# most of the time you will need them if anonymous doesn't have XML-RPC permissions
trac = Trac.new "https://dev.example.com/trac/my_awesome_project", "myusername", "mypassword"
# get a list of all tickets (as an array of numbers)
trac.tickets.list :include_closed => true # this is the default anyway
# get all the tickets
# Note: the results here are cached, so you can call it as often as you want without producing traffic more than once.
# use ":cached_results => false" to get the latest version
trac.tickets.get_all :include_closed => true
# get a single ticket
ticket = trac.tickets.get 5
# print the data
puts "Title: #{ticket.summary}"
puts "Description: #{ticket.description}"
puts "Milestone: #{ticket.milestone}"
puts "Status: #{ticket.status}"
puts "Type: #{ticket.type}"
puts "Priority: #{ticket.priority}"
# get a list of all wiki pages
trac.wiki.list
# download one page
trac.wiki.get_html "SomeRandomPageName" # HTML version
trac.wiki.get_raw "AnotherRandomPageName" # trac syntax version (e.g. for editing)
# for previews use
trac.wiki.raw_to_html "content of a page in [wiki:WikiFormatting Trac syntax] as a ''String''"
# to post a page use
trac.wiki.put "NameOfThePage", "content in Trac syntax"
# list the attachments of a wiki page
trac.wiki.attachments "NameOfThePage"
# save an attachment
File.new("my_cool_document","w") do |f|
  f.write trac.wiki.get_attachment "NameOfThePage", "my_cool_document.pdf"
end

# upload an attachment to the page above
page = "NameOfThePage"
fn = "my_nice_doc.pdf"
fh = File.new(fn, "rb")
sdata = fh.read
data = XMLRPC::Base64.new(sdata)
result = trac.wiki.put_attachment(page, name, "uploaded via ruby script", data)
# the correct result should be the name of the file:
puts "ERROR: uploading #{name} didn't work properly!" if result != name

Also see the included Documentation in trac4r/doc

If you need to do a custom query do:

trac.query("system.getAPIVersion")

The first argument is the method name, all other arguments are directly passed to XML-RPC. For this example of course you could do trac.api_version instead.

If you have any problems with trac4r you can email me: niklas.cathor (eat) gmail dot com

XML-RPC example

An example using XML-RPC directly with Ruby to append to a wiki page:

require 'xmlrpc/client'
user = "username"
password = "password"
page_name = "SandBoxRPC"
new_content = "\n\nMy new content"
new_comment = "Adding new content from ruby"

server = XMLRPC::Client.new2("https://#{user}:#{password}@trac.server.com/trac/login/xmlrpc")
content = server.call("wiki.getPage", page_name) + new_content
server.call("wiki.putPage", page_name, content, {"comment" => new_comment})

SSL Support + X509

The standard ruby xmlrpc client for some reason does not support SSL at all. To use the XML-RPC over SSL with both:

...you should have:

  • ca certificate in .pem format
  • personal certificate + RSA key in .p12 format (and its password, of course)
  • patched version of xmlrpc/client.rb
  • patched version of trac4r
  • username/password (for basic authentication)

Assuming you have the above, and your ca and user certificates are respectively:

~/.openssl/cacert.pem
~/.openssl/certkey.p12

Installation and Configuration

  1. Apply the patches:
    1. To the XML-RPC client:
      sudo su -
      cd /usr/lib/ruby/1.8/
      patch -p0  < /path/to/xmlrpc-client.SSL.patch
      
    2. To the trac4r gem:
      sudo su -
      cd /var/lib/gems/1.8/gems/
      patch -p0  < /path/to/trac4r-1.2.3.SSL.patch
      
  2. Create a .yml file called ~/.trac/creds.yml of the following structure:
    --- 
    tracurl: https://yourserver.yourdomain/yourproject
    tracuser: yourwebuser
    tracpass: yourwebpassword
    certkey: /home/youruser/.openssl/certkey.p12
    cacert: /home/youruser/.openssl/cacert.pem
    keypass: yourkeypassword
    
    • Do not forget to chmod the personal files to 600 or 400.
  3. Use the data in the code:
    require 'yaml'
    require 'openssl'
    require 'xmlrpc/client'
    require 'trac4r'
    
    ## read the data from yaml:
    $ymlname= "#{ENV['HOME']}/.trac/creds.yml"
    if !File.exists?($ymlname) 
        raise "Cannot open credentials file!"
    end
    begin
        $vars = YAML::load_file($ymlname)
    rescue Exception => e
        raise "Cannot load credentials file #{$ymlname}: #{e.message}\nTrace: #{e.stacktrace}"
    end
    
    ## extract the certificate, and the key from the fles.
    pkcs = OpenSSL::PKCS12.new(File.open($vars['certkey']),$vars['keypass'])
    cert = pkcs.cert
    key = pkcs.key
    ## connect to the server
    trac = Trac.new($vars['tracurl'], $vars['tracuser'], $vars['tracpass'], $vars['cacert'], cert, key)
    ## from now you can refer to the connection as open (or query it)
    ## use the API as explained above.
    

Notes: The working environment of the code (trac4r + ssl) is:

  • Debian/GNU system: Linux hostname 2.6.26-2-686 #1 SMP Mon Jun 21 05:58:44 UTC 2010 i686 GNU/Linux
  • OpenSSL: OpenSSL 0.9.8g 19 Oct 2007
  • Ruby: ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
  • The certificates have been issued by the above OpenSSL setup.
Last modified 8 years ago Last modified on Sep 6, 2016, 6:53:08 PM

Attachments (3)

Download all attachments as: .zip