blog.dotkam.com stats

Install rtGui on Ubuntu

rtorrent project logortGui is a web based front end for rTorrent - the Linux command line BitTorrent client. It’s written in PHP and uses XML-RPC to communicate with the rTorrent client.

There are several guides on how to install rtGui on Ubuntu or just POL (Plain Old Linux), but all of them seem to be missing one or two things to make them complete.

Here I went from scratch, step by step to install rtGui on Ubuntu (actually KUbuntu, and to be more specific linuxMCE but it would not matter in this case, since this guide is for any more or less recent Ubuntu distro). I tried to make this guide as complete as possible so it does not miss any installation steps, and if you have any questions/comments, you are welcome to post them in comments section. Now sit back, relax and… let’s get to work! :)

Step 1.  Install PHP with XML-RPC and a SCGI apache module:

sudo apt-get install php5 php5-xmlrpc libapache2-mod-scgi

Step 2. Edit Apache default server config:

sudo vi /etc/apache2/sites-enabled/000-default

(If you are using linuxMCE, edit /etc/apache2/sites-enabled/pluto file instead)
Add the following lines, above the last “</VirtualHost>” (or download example from http://rtgui.googlecode.com/files/000-default ):

LoadModule scgi_module /usr/lib/apache2/modules/mod_scgi.so
SCGIMount /RPC2 127.0.0.1:5000

Restart apache:

sudo apache2ctl restart

Step 3. Create .rtorrent.rc file - see http://libtorrent.rakshasa.no/browser/trunk/rtorrent/doc/rtorrent.rc?rev=latest or download example from http://rtgui.googlecode.com/files/.rtorrent.rc and save to your home directory - ~/.rtorrent.rc

* make sure .rtorrent.rc has this line:

scgi_port = 127.0.0.1:5000

Step 4. Create directories for rtorrent to use, and change the ownership to the user that runs rtorrent:

mkdir /Torrents /Torrents/Downloading /Torrents/Downloading/rtorrent.session 
/Torrents/Complete /Torrents/TorrentFiles /Torrents/TorrentFiles/Auto
chown username /Torrents /Torrents/Downloading /Torrents/Downloading/rtorrent.session 
/Torrents/Complete /Torrents/TorrentFiles /Torrents/TorrentFiles/Auto

* here “username” is the user who will run rtorrent 

Step 5. Instal XML-RPC library:

sudo apt-get install libxmlrpc-c3-dev
sudo apt-get install libxmlrpc-c3

Step 6. Install latest version of both - libtorrent & rtorrent:

Download latest version (X.Y.Z) of libtorrent from http://libtorrent.rakshasa.no/downloads/ into /usr/local/ directory:

wget http://libtorrent.rakshasa.no/downloads/libtorrent-X.Y.Z.tar.gz
sudo tar xvf libtorrent-X.Y.Z.tar.gz
cd libtorrent-0.11.1
 
sudo ./configure
sudo make
sudo make install

Download rtorrent latest version (X.Y.Z) from http://libtorrent.rakshasa.no/downloads/ in /usr/local/ directory.

wget http://libtorrent.rakshasa.no/downloads/rtorrent-X.Y.Z.tar.gz
sudo tar xvf rtorrent-X.Y.Z.tar.gz
cd rtorrent-X.Y.Z
 
sudo ./configure --with-xmlrpc-c
sudo make
sudo make install

* make sure  you configure rtorrent with “–with-xmlrpc-c” option

After the above 6 steps we are ready to install rtGui (and other GUIs for rtorrent: wTorrent, etc..)

Step 7. Install rtGui:

Download rtgui from http://code.google.com/p/rtgui/downloads/list
Extract files to webserver directory:

sudo tar xvzf ~/rtgui-0.2.3.tgz -C /var/www

* 0.2.3 is the current version at the moment of writing

You can edit “/var/www/rtgui/config.php” if you’d like to change rtGui default settings. Most of the time you don’t have to.

*** Step 8. Start rtorrent:

rtorrent

Step 9. Done! :) Open your browser, and go to http://localhost/rtgui/

*** (!) Since rtGui talks to rtorrent via XML-RPC gateway, rtorrent has to be started - otherwise rtGui has nobody to talk to :) In case rtorrent is not started when you accessing rtGui via web browser, you would get:

Warning: file_get_contents(http://localhost/RPC2) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error in /var/www/rtgui/functions.php on line 10

This is because there is nobody listening on port 5000 - remember the line “scgi_port = 127.0.0.1:5000″ in .rtorrent.rc? We have configured rtorrent with ” –with-xmlrpc-c” option, hence when rtorrent is up and running it will listen on “scgi_port” (in this case 5000) and will be able to handle XML-RPC requests/responses.

Happy rTorrenting!

AddThis Social Bookmark Button

Spring Web Application Context Visibility

spring framework logoWhile developing a Web App using Spring little things can take a lot of time to resolve. At the end they may appear to be very simple, and you may ask your self “how could I not think of it before - it is so obvious!”. Well, yea, it is obvious, but you just have to know it! One of the places that helps you to solve the “obvious” (and not so obvious), so you do not have to spin your wheels is, with no doubts, the spring forum. However you need to know the right search criteria to find what you need.

Here I just want to share something small but important about the visibility of Spring Contexts in a Web App.

Looking at org.springframework.web.servlet.DispatcherServlet API notice this:

“A web application can define any number of DispatcherServlets. Each servlet will operate in its own namespace, loading its own application context with mappings, handlers, etc. Only the root application context as loaded by ContextLoaderListener, if any, will be shared.”

This brings an interesting point - in a Spring Web App you have one root application context which is private, and many dispatcher servlet application contexts which are children of the root application context:

<context-param>
<param-name>contextConfigLocation</param-name>
   <param-value>
      /WEB-INF/classes/applicationContext.xml
      /WEB-INF/classes/otherContext.xml
   </param-value>
 </context-param>
 
...
 
 <servlet>
  <servlet-name>context</servlet-name>
  <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
...
 
 <servlet>
  <servlet-name>dispatcher-servlet-number-x</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
 </servlet>

In the above, everything that is defined in “contextConfigLocation” is your root application context. Every “dispatcher-servlet-number-x” (”dispatcher-servlet-number-1″, “dispatcher-servlet-number-2″, etc..) would represent a child application context which will see (have the visibility to) all the beans from the parent (root) context, but will not see any of the beans defined by its siblings - another dispatcher servlet contexts.

The only gotcha in the above visibility is BeanFactoryPostProcessor / BeanPostProcessor (s) - like “PropertyPlaceholderConfigurer” for example. These guys apply ONLY to beans in its own context. For example, if you have PropertyPlaceholderConfigurer defined in the root application context, none of root’s children will be able to use it (see) the ${properties}.

Here is the semi-official version “why” from Juergen (Spring Lead Developer):

“PropertyPlaceholderConfigurer is an implementation of the BeanFactoryPostProcessor interface: This interface and its sibling BeanPostProcessor just apply to the BeanFactory that defines them, that is, to the application context that defines them.

If you combine multiple config files into a single contextConfigLocation, a PropertyPlaceholderConfigurer defined in any of the files will apply to all of the files, because they are loaded into a single application context.

However, a DispatcherServlet has its own application context, just using the root web application context as parent. Therefore, it needs to define its own BeanFactoryPostProcessors and/or BeanPostProcessors, in this case its own PropertyPlaceholderConfigurer.”

Happy Springing!

AddThis Social Bookmark Button

Map Objects to/from XML with Castor

object xml mapping

Mapping Objects to XML and back is called Marshalling / Unmarshalling, and it is widely used in technology of the 21st century. It is not that easy to send your friend an Object you created in Java/Python/Ruby/.Net/C++ etc.., but it is very easy to send a text file - right?

Since XML is just a simple text file - would not it be great if we can convert an Object to XML, send it to our friend, who could then read our XML back into an Object and “enjoy it”? Sure it would! :)

There are many tools that can help us do that, but the one which is recommended by many is called Castor. So here is a simple example on how to map an Object into xml (marshal it to XML):

By default Castor will marshal/unmarshal with “-” in between the words, so MyObject will get marshaled into “my-object”, since that is a default behavior.

In order to create a “custom look” for your object and fields, you would need to create a mapping file - which is really not all that difficult. Here is a great example from castor.org:

Let’s say you have a class OrderItem:

public class OrderItem {
 
private String id;
private Integer orderQuantity;
 
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getOrderQuantity() {
return orderQuantity;
}
public void setOrderQuantity(Integer orderQuantity) {
this.orderQuantity = orderQuantity;
}
}

normally, if you map it with Castor without any mapping file, you would get:

<?xml version="1.0" ?>
   <order-item>
      <id>12</id>
      <order-quantity>100</order-quantity>
   </order-item>

but what if you need to marshal it (map it) to something like this which is way more natural and more readable:

<?xml version="1.0" ?>
   <item identity="12">
      <quantity>100</quantity>
   </item>

then you need to create a very simple mapping file:

<class name="mypackage.OrderItem">
 
   <map-to xml="item"/>
 
      <field name="id" type="string">
         <bind-xml name="identity" node="attribute"/>
      </field>
 
      <field name="orderQuantity" type="integer">
         <bind-xml name="quantity" node="element"/>
      </field>
 
</class>

It is very simple - you map:

"OrderItem"         to         "item"
"id"                to         "identity" (and making it an attribute by: node="attribute")
"orderQuantity"     to         "quantity"

img source

AddThis Social Bookmark Button

Generate XSD from XML

There are several tools out there to create (or to infer) an XSD schema from XML document. I liked trang command line tool the most. Found it first when reading about Spring web services in Spring in Action book (very good book btw).

Here are four simple steps how to create XSD from XML* using trang:

1. Download trang.zip from here (at the moment of writing “trang-20030619.zip”)
2. Extract it
3. Make an alias to the trang.jar -> in my case (Ubuntu) edited ~/.bashrc:

you don’t have to create an alias, but it just makes it simpler to run

# execute trang.jar (create XSD from XMLs)
alias xml2xsd='java -jar ~/soft/utils/trang/trang-20030619/trang.jar'

(”~/soft/utils/trang/” is where trang.zip was extracted)

4. Create XSD from XML:

$ ls -l
total 4
-rw-r--r-- 1 user group 357 2008-05-28 15:38 holiday-request.xml

$ cat holiday-request.xml
<?xml version="1.0" encoding="UTF-8"?>

<HolidayRequest xmlns="http://mycompany.com/hr/schemas">
    <Holiday>
        <StartDate>2006-07-03</StartDate>
        <EndDate>2006-07-07</EndDate>
    </Holiday>
    <Employee>
        <Number>42</Number>
        <FirstName>Ultimate</FirstName>
        <LastName>Answer</LastName>
    </Employee>
</HolidayRequest>

$ xml2xsd holiday-request.xml hr.xsd
$ cat hr.xsd 

<?xml version=”1.0″ encoding=”UTF-8″?>
<xs:schema xmlns:xs=”http://www.w3.org/2001/XMLSchema” elementFormDefault=”qualified” targetNamespace=”http://mycompany.com/hr/schemas” xmlns:schemas=”http://mycompany.com/hr/schemas”>
  <xs:element name=”HolidayRequest”>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref=”schemas:Holiday”/>
        <xs:element ref=”schemas:Employee”/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name=”Holiday”>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref=”schemas:StartDate”/>
        <xs:element ref=”schemas:EndDate”/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name=”StartDate” type=”xs:NMTOKEN”/>
  <xs:element name=”EndDate” type=”xs:NMTOKEN”/>
  <xs:element name=”Employee”>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref=”schemas:Number”/>
        <xs:element ref=”schemas:FirstName”/>
        <xs:element ref=”schemas:LastName”/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name=”Number” type=”xs:integer”/>
  <xs:element name=”FirstName” type=”xs:NCName”/>
  <xs:element name=”LastName” type=”xs:NCName”/>
</xs:schema>

$

* - BTW, trang can create an XSD from multiple XML documents, not just one.

List of other tools to use as an alternative to trang:
xmlbeans: http://xmlbeans.apache.org/docs/2.0.0/guide/tools.html#inst2xsd
online tool: http://www.flame-ware.com/xml2xsd/
oxygenxml: http://www.oxygenxml.com/
(eclipse plugin: http://www.oxygenxml.com/eclipse_plugin.html)
stylus studio: http://www.stylusstudio.com/autogen_xsd.html

AddThis Social Bookmark Button