| 1 | === Using XMLRPC from Ruby === |
| 2 | |
| 3 | You can either use the XMLRPC functionality included in the [http://ruby-doc.org/stdlib/libdoc/xmlrpc/rdoc/index.html Ruby Standard Library] or [/attachment/wiki/XmlRpcPlugin/trac4r.tar.gz download the trac4r library] which does all the trivial stuff for you. |
| 4 | |
| 5 | please refer to the '''SSL Support''' section if you need one. |
| 6 | |
| 7 | ==== trac4r Example ==== |
| 8 | This example uses trac4r: |
| 9 | {{{ |
| 10 | #!ruby |
| 11 | require 'trac4r/trac' |
| 12 | # initialize the connection (username and password can be ommitted if not needed, but most of the time you will need them if anonymous doesn't have XMLRPC permissions) |
| 13 | trac = Trac.new "https://dev.example.com/trac/my_awesome_project", "myusername", "mypassword" |
| 14 | # get a list of all tickets (as an array of numbers) |
| 15 | trac.tickets.list :include_closed => true # this is the default anyway |
| 16 | # get all the tickets |
| 17 | # NOTE: the results here are cached, so you can call it as often as you want without producing traffic more than once. |
| 18 | # use ":cached_results => false" to get the latest version |
| 19 | trac.tickets.get_all :include_closed => true |
| 20 | # get a single ticket |
| 21 | ticket = trac.tickets.get 5 |
| 22 | # print the data |
| 23 | puts "Title: #{ticket.summary}" |
| 24 | puts "Description: #{ticket.description}" |
| 25 | puts "Milestone: #{ticket.milestone}" |
| 26 | puts "Status: #{ticket.status}" |
| 27 | puts "Type: #{ticket.type}" |
| 28 | puts "Priority: #{ticket.priority}" |
| 29 | # get a list of all wiki pages |
| 30 | trac.wiki.list |
| 31 | # download one page |
| 32 | trac.wiki.get_html "SomeRandomPageName" # HTML version |
| 33 | trac.wiki.get_raw "AnotherRandomPageName" # trac syntax version (e.g. for editing) |
| 34 | # for previews use |
| 35 | trac.wiki.raw_to_html "content of a page in [wiki:WikiFormatting Trac syntax] as a ''String''" |
| 36 | # to post a page use |
| 37 | trac.wiki.put "NameOfThePage", "content in Trac syntax" |
| 38 | # list the attachments of a wiki page |
| 39 | trac.wiki.attachments "NameOfThePage" |
| 40 | # save an attachment |
| 41 | File.new("my_cool_document","w") do |f| |
| 42 | f.write trac.wiki.get_attachment "NameOfThePage", "my_cool_document.pdf" |
| 43 | end |
| 44 | |
| 45 | # upload an attachment to the page above |
| 46 | page = "NameOfThePage" |
| 47 | fn = "my_nice_doc.pdf" |
| 48 | fh = File.new(fn, "rb") |
| 49 | sdata = fh.read |
| 50 | data = XMLRPC::Base64.new(sdata) |
| 51 | result = trac.wiki.put_attachment(page, name, "uploaded via ruby script", data) |
| 52 | # the correct result should be the name of the file: |
| 53 | puts "ERROR: uploading #{name} didn't work properly!" if result != name |
| 54 | }}} |
| 55 | |
| 56 | Also see the included Documentation in trac4r/doc |
| 57 | |
| 58 | If you need to do a custom query do |
| 59 | {{{ |
| 60 | #!ruby |
| 61 | trac.query("system.getAPIVersion") |
| 62 | }}} |
| 63 | The first argument is the method name, all other arguments are directly passed to XMLRPC. |
| 64 | For this example of cause you could do `trac.api_version` instead ;) |
| 65 | |
| 66 | If you have any problems with trac4r you can email me: niklas.cathor (eat) gmail dot com |
| 67 | |
| 68 | ==== xmlrpc Example ==== |
| 69 | |
| 70 | An example using XML-RPC directly with Ruby to append to a wiki page: |
| 71 | {{{ |
| 72 | #!ruby |
| 73 | require 'xmlrpc/client' |
| 74 | user = "username" |
| 75 | password = "password" |
| 76 | page_name = "SandBoxRPC" |
| 77 | new_content = "\n\nMy new content" |
| 78 | new_comment = "Adding new content from ruby" |
| 79 | |
| 80 | server = XMLRPC::Client.new2("https://#{user}:#{password}@trac.server.com/trac/login/xmlrpc") |
| 81 | content = server.call("wiki.getPage", page_name) + new_content |
| 82 | server.call("wiki.putPage", page_name, content, {"comment" => new_comment}) |
| 83 | }}} |
| 84 | |
| 85 | ==== SSL Support + X509 ==== |
| 86 | The standard ruby xmlrpc client for some reason does not support SSL at all. |
| 87 | In order to be able to use the XMLRPC over SSL with both |
| 88 | * Client Certificate authentication |
| 89 | * Basic Authentication |
| 90 | One must do as follows. |
| 91 | |
| 92 | in order to proceed, you should have: |
| 93 | * ca certificate in .pem format |
| 94 | * personal certificate + RSA key in .p12 format (and its password, of course) |
| 95 | * patched version of xmlrpc/client.rb |
| 96 | * patched version of trac4r |
| 97 | * username/password (for basic authentication) |
| 98 | |
| 99 | Assuming you have the above, and your ca and user certificates are respectively: |
| 100 | {{{ |
| 101 | ~/.openssl/cacert.pem |
| 102 | ~/.openssl/certkey.p12 |
| 103 | }}} |
| 104 | ===== The Instructions ===== |
| 105 | 1. apply the patches: |
| 106 | 1. to the [attachment:"xmlrpc-client.SSL.patch" xmlrpc client] |
| 107 | {{{ |
| 108 | sudo su - |
| 109 | cd /usr/lib/ruby/1.8/ |
| 110 | patch -p0 < /path/to/xmlrpc-client.SSL.patch |
| 111 | }}} |
| 112 | 1. to the [attachment:"trac4r-1.2.3.SSL.patch" trac4r gem] |
| 113 | {{{ |
| 114 | sudo su - |
| 115 | cd /var/lib/gems/1.8/gems/ |
| 116 | patch -p0 < /path/to/trac4r-1.2.3.SSL.patch |
| 117 | }}} |
| 118 | 1. create a .yml file called {{{~/.trac/creds.yml}}} of the following structure: |
| 119 | {{{ |
| 120 | --- |
| 121 | tracurl: https://yourserver.yourdomain/yourproject |
| 122 | tracuser: yourwebuser |
| 123 | tracpass: yourwebpassword |
| 124 | certkey: /home/youruser/.openssl/certkey.p12 |
| 125 | cacert: /home/youruser/.openssl/cacert.pem |
| 126 | keypass: yourkeypassword |
| 127 | }}} |
| 128 | * do not forget to chmod the personal files to 600 or 400 |
| 129 | 1. use the data in the code |
| 130 | {{{ |
| 131 | #!ruby |
| 132 | require 'yaml' |
| 133 | require 'openssl' |
| 134 | require 'xmlrpc/client' |
| 135 | require 'trac4r' |
| 136 | |
| 137 | ## read the data from yaml: |
| 138 | $ymlname= "#{ENV['HOME']}/.trac/creds.yml" |
| 139 | if !File.exists?($ymlname) |
| 140 | raise "Cannot open credentials file!" |
| 141 | end |
| 142 | begin |
| 143 | $vars = YAML::load_file($ymlname) |
| 144 | rescue Exception => e |
| 145 | raise "Cannot load credentials file #{$ymlname}: #{e.message}\nTrace: #{e.stacktrace}" |
| 146 | end |
| 147 | |
| 148 | ## extract the certificate, and the key from the fles. |
| 149 | pkcs = OpenSSL::PKCS12.new(File.open($vars['certkey']),$vars['keypass']) |
| 150 | cert = pkcs.cert |
| 151 | key = pkcs.key |
| 152 | ## connect to the server |
| 153 | trac = Trac.new($vars['tracurl'], $vars['tracuser'], $vars['tracpass'], $vars['cacert'], cert, key) |
| 154 | ## from now you can refer to the connection as open (or query it) |
| 155 | ## use the API as explained above. |
| 156 | }}} |
| 157 | |
| 158 | '''NOTE:''' The working environment of the code (trac4r + ssl) is: |
| 159 | * Debian/GNU system: {{{Linux hostname 2.6.26-2-686 #1 SMP Mon Jun 21 05:58:44 UTC 2010 i686 GNU/Linux}}} |
| 160 | * OpenSSL: {{{OpenSSL 0.9.8g 19 Oct 2007}}} |
| 161 | * Ruby: {{{ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]}}} |
| 162 | * The certificates have been issued by the above OpenSSL setup. |