Wednesday, July 15, 2015

Livejournal XML-RPC anonymous access

The question about anonymous access (i.e. read posts and comments without authorization) is often raised during development applications using XML-RPC interface. Livejournal protocol is poorly documented and it is not obvious how to implement that. However source code is available and could help to clarify some issues (LiveJournal Server Source Code (stale history from before it went closed-source) (https://github.com/apparentlymart/livejournal). The ljprotocol.pl file is of interest to us.

First of all, there is list of handlers:
my %HANDLERS = (
...
getrecentcomments => \&getrecentcomments,
getcomments => \&getcomments,
deletecomments => \&deletecomments,
updatecomments => \&updatecomments,
editcomment => \&editcomment,
...
); 
Where we can find the methods to deal with comments, while they are not mentioned in official guide (http://www.livejournal.com/doc/server/ljp.csp.xml-rpc.protocol.html).

Also the following methods allow anonymous access:
  • getevents
  • getcomments
  • getuserpics
Example of Java code:

getevents



XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://www.livejournal.com/interface/xmlrpc"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);

Map<String, Object> struct = new HashMap<String, Object>();
struct.put("usejournal", "jbearz");
struct.put("ver", 1);
struct.put("selecttype", "lastn");

Map result = (Map)client.execute("LJ.XMLRPC.getevents", new Object[]{struct});
for(Object name: result.keySet()) {
    System.out.println("result: " + name + "  " + result.get(name));
}
Object[] events = (Object[])result.get("events");
String event = "";
String subject = "";
int ditemid = 0; // will be used for comments
for(Object ev: events) {
    System.out.println("events " + ev);
    event = toUnicodeString(((Map)ev).get("event"));
    System.out.println("event " + event);
    subject = toUnicodeString(((Map)ev).get("subject"));
    System.out.println("subject " + subject);
    ditemid = (int)((Map)ev).get("ditemid");
}

toUnicodeString is a service method to read Cyrillic text:
private static String toUnicodeString(Object text) throws UnsupportedEncodingException {
    if (text == null) {
        return null;
    } else if (text instanceof byte[]) {
        return new String((byte[]) text, Charset.forName("UTF-8"));
    } else {
        return String.valueOf(text);
    }
}

Result output:

getcomments 


  struct = new HashMap<String, Object>();
  struct.put("journal", "jbearz");
  struct.put("ditemid", ditemid);
  struct.put("page", 1);

  result = (Map)client.execute("LJ.XMLRPC.getcomments", new Object[]{struct});
  for(Object name: result.keySet()) {
      System.out.println("result: " + name + "  " + result.get(name));
  }
  Object[] comments = (Object[])result.get("comments");

  for (Object comment: comments) {
      System.out.println("comment " + comment);
      String body  = toUnicodeString(((Map)comment).get("body"));
      System.out.println("body " + body);
      Object[] children = (Object[])((Map)comment).get("children");
      System.out.println("children " + toUnicodeString(((Map)children[0]).get("body")));
  }
In response we will get array of first level comments. Replies to comment are also received as array.
Result output:
result: page_size  500
result: topitem_first  1
result: page  1
result: pages  1
result: topitems  1
result: topitem_last  1
result: ditemid  617
result: comments  [Ljava.lang.Object;@194566d
comment {body=[B@1b64b70, is_show=1, level=0, datepost=2015-07-14 10:55:44, dtalkid=361, postername=, parentdtalkid=0, state=A, children=[Ljava.lang.Object;@112bc7b, posterid=0, datepostunix=1436871344, is_loaded=1}
body красиво
children спасибо

getuserpicss 

We do not need to pass any arguments to get user pictures.
struct = new HashMap<String, Object>();
struct.put("journal", "jbearz");
result = (Map)client.execute("LJ.XMLRPC.getuserpics", new Object[]{struct});
for(Object name: result.keySet()) {
    System.out.println("result: " + name + "  " + result.get(name));
}
Result output:
result: pickwurls  [Ljava.lang.Object;@11456c5
result: pickws  [Ljava.lang.Object;@4ca42b
result: defaultpicurl  http://l-userpic.livejournal.com/125218233/76439974

No comments:

Post a Comment