package org.transdroid.daemon.Ktorrent;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import org.transdroid.daemon.DaemonException;
import org.transdroid.daemon.Priority;
import org.transdroid.daemon.TorrentFile;
import org.transdroid.daemon.DaemonException.ExceptionType;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
/**
* A Ktorrent-specific parser for it's /data/torrent/files.xml output.
*
* @author erickok
*
*/
public class FileListParser {
public static List<TorrentFile> parse(Reader in, String torrentDownloadDir) throws DaemonException, LoggedOutException {
try {
// Use a PullParser to handle XML tags one by one
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
xpp.setInput(in);
// Temp variables to load into torrent objects
int i = 0;
String path = "";
long size = 0;
float partDone = 0;
Priority priority = Priority.Normal;
// Start pulling
List<TorrentFile> torrents = new ArrayList<TorrentFile>();
int next = xpp.nextTag();
String name = xpp.getName();
// Check if we had a proper XML result
if (name.equals("html")) {
// Apparently we were returned an HTML page instead of the expected XML
// This happens in particular when we were logged out (because somebody else logged into KTorrent's web interface)
throw new LoggedOutException();
}
while (next != XmlPullParser.END_DOCUMENT) {
if (next == XmlPullParser.END_TAG && name.equals("file")) {
// End of a 'transfer' item, add gathered torrent data
torrents.add(new TorrentFile(
"" + i,
path,
path,
(torrentDownloadDir == null? null: torrentDownloadDir + path),
size,
(long) (size * partDone),
priority));
} else if (next == XmlPullParser.START_TAG && name.equals("file")){
// Start of a new 'transfer' item; reset gathered torrent data
i++; // Increase the file index identifier
path = "";
size = 0;
partDone = 0;
priority = Priority.Normal;
} else if (next == XmlPullParser.START_TAG){
// Probably encountered a file property, i.e. '<percentage>73.09</percentage>'
next = xpp.next();
if (next == XmlPullParser.TEXT) {
if (name.equals("path")) {
path = xpp.getText().trim();
} else if (name.equals("size")) {
size = StatsParser.convertSize(xpp.getText());
} else if (name.equals("priority")) {
priority = convertPriority(xpp.getText());
} else if (name.equals("percentage")) {
partDone = StatsParser.convertProgress(xpp.getText());
}
}
}
next = xpp.next();
if (next == XmlPullParser.START_TAG || next == XmlPullParser.END_TAG) {
name = xpp.getName();
}
}
return torrents;
} catch (XmlPullParserException e) {
throw new DaemonException(ExceptionType.ParsingFailed, e.toString());
} catch (IOException e) {
throw new DaemonException(ExceptionType.ConnectionError, e.toString());
}
}
/**
* Returns the priority of a file, as parsed from some string
* @param priority The priority in a numeric string, i.e. '20'
* @return The priority as enum type, i.e. Priority.Off
*/
private static Priority convertPriority(String priority) {
if (priority.equals("20")) {
return Priority.Off;
} else if (priority.equals("30")) {
return Priority.Low;
} else if (priority.equals("50")) {
return Priority.High;
} else {
return Priority.Normal;
}
}
}