/*
* XNap
*
* A pure java file sharing client.
*
* See AUTHORS for copyright information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package xnap.util;
import xnap.cmdl.*;
import xnap.net.*;
import xnap.plugin.PluginManager;
import xnap.util.*;
import xnap.util.event.SearchManagerListener;
import gnu.getopt.Getopt;
import java.util.*;
public class SearchManager extends EventVector
{
//--- Constant(s) ---
//--- Data field(s) ---
private static SearchManager singleton = new SearchManager();
private static Console console = Console.getInstance();
private SearchResultContainer[] lastResults;
private ISearchContainer lastSearch;
private SearchManagerListener listener = null;
private int readyCount = 0;
private boolean resumed = false;
//--- Constructor(s) ---
public SearchManager()
{
Executer.addCommand(new ListSearchesCmd());
Executer.addCommand(new ListResultsCmd());
Executer.addCommand(new SearchCmd());
Executer.addCommand(new DownloadCmd());
}
//--- Method(s) ---
public static synchronized SearchManager getInstance()
{
return singleton;
}
public void browse(IBrowse b)
{
Browser sc = new Browser(b);
super.add(sc);
}
public ISearchContainer[] getSearches()
{
ISearchContainer[] array = new ISearchContainer[super.size()];
System.arraycopy(super.toArray(), 0, array, 0, array.length);
return array;
}
/**
* Called by plugins to notify XNap to resume downloads.
*/
public synchronized void resumeDownloads()
{
if (!resumed && Preferences.getInstance().getAutoResumeDownloads()) {
DownloadQueue.getInstance().resumeAll();
resumed = true;
}
}
/**
* Called by plugins to notify XNap of their search status
*
* @param isReady true, if plugin is able to serve serach requests; false,
* otherwise.
*/
public synchronized void readyToSearch(boolean isReady)
{
readyCount += isReady ? 1 : -1;
notifyListener();
}
private synchronized void notifyListener()
{
if (listener != null) {
listener.readyToSearch(readyCount > 0);
}
}
public void remove(ISearchContainer sc)
{
super.remove(sc);
}
public void search(SearchFilter filter)
{
ISearch[] searches
= PluginManager.getInstance().search(filter, ISearch.PRIORITY_USER);
Searcher sc = new Searcher(searches, filter);
super.add(sc);
}
public synchronized void setListener(SearchManagerListener listener)
{
this.listener = listener;
notifyListener();
}
protected class ListSearchesCmd extends AbstractCommand
{
public ListSearchesCmd()
{
putValue(CMD, new String[] {"listsearches", "ls"});
putValue(SHORT_HELP,
"Prints a list of running or finished searches.");
}
public boolean execute(String[] argv)
{
ISearchContainer[] searches = getSearches();
String[] table = new String[searches.length];
for (int i = 0; i < searches.length; i++) {
StringBuffer sb = new StringBuffer();
sb.append(i);
sb.append("|");
sb.append(searches[i].toString());
sb.append("|");
sb.append(searches[i].getCollector().getResults().length);
sb.append(" results");
sb.append("|");
sb.append(searches[i].getStatus());
table[i] = sb.toString();
}
int L = Formatter.LEFT;
int R = Formatter.RIGHT;
int[] cols = new int[] { R, L, R, L };
console.println(Formatter.formatTable(table, cols));
return true;
}
}
protected class ListResultsCmd extends AbstractCommand
{
public ListResultsCmd()
{
putValue(CMD, new String[] {"listresults", "lr"});
putValue(PARAMETER, "id");
putValue(SHORT_HELP, "Prints a list of searches.");
}
public boolean execute(String[] argv)
{
if (argv.length != 2) {
return false;
}
lastSearch = (ISearchContainer)get(Integer.parseInt(argv[1]));
if (lastSearch == null) {
console.println("Wrong search id.");
return true;
}
lastResults = lastSearch.getCollector().getGroupedResults();
String[] table = new String[lastResults.length];
for (int i = 0; i < lastResults.length; i++) {
StringBuffer sb = new StringBuffer();
sb.append(i);
sb.append("|" + lastResults[i].getShortFilename());
sb.append("|" + lastResults[i].getUsername());
table[i] = sb.toString();
}
int L = Formatter.LEFT;
int R = Formatter.RIGHT;
int[] cols = new int[] { R, L, L };
console.println(Formatter.formatTable(table, cols));
return true;
}
}
protected class DownloadCmd extends AbstractCommand
{
public DownloadCmd()
{
putValue(CMD, new String[] {"download", "d"});
putValue(PARAMETER, "id");
putValue(SHORT_HELP, "Download a search result.");
}
public boolean execute(String[] argv)
{
int i = getResultIndex(argv);
if (i >= 0) {
IDownloadContainer d
= new AutoDownload(lastResults[i].getSearchResults(),
new SearchFilter());
DownloadQueue.getInstance().add(d);
}
else if (i == -1) {
return false;
}
return true;
}
}
protected class SearchCmd extends AbstractCommand
{
public SearchCmd()
{
putValue(CMD, new String[] {"search"});
putValue(PARAMETER, "[-b [>|<|=]bitrate] [-s [>|<|=]size] query");
putValue(SHORT_HELP, "Search.");
}
public boolean execute(String[] argv)
{
SearchFilter filter = new SearchFilter();
// remove command
System.arraycopy(argv, 1, argv, 0, argv.length - 1);
Getopt g = new Getopt("xnap search", argv, "b:s:");
g.setOpterr(false);
try {
int c;
NumberParser p;
while ((c = g.getopt()) != -1) {
switch (c) {
case 'b':
p = new NumberParser(g.getOptarg(),
SearchFilter.COMPARE_AT_LEAST);
filter.setBitrateCompare(p.getCompare());
filter.setBitrate(p.getValue());
break;
case 's':
p = new NumberParser (g.getOptarg(),
SearchFilter.COMPARE_AT_LEAST);
filter.setFilesizeCompare(p.getCompare());
filter.setFilesize(p.getValue());
default:
return false;
}
}
}
catch (NumberFormatException e) {
return false;
}
StringBuffer sb = new StringBuffer();
for (int i = g.getOptind(); i < argv.length - 1; i++) {
sb.append(argv[i]);
sb.append(" ");
}
String s = sb.toString().trim();
if (s.length() == 0) {
return false;
}
filter.setSearchText(s);
search(filter);
return true;
}
}
protected int getResultIndex(String[] argv)
{
if (argv.length != 2) {
return -1;
}
if (lastResults == null) {
console.println("Please list results first.");
return -2;
}
int i;
try {
i = Integer.parseInt(argv[1]);
}
catch (NumberFormatException e) {
return -1;
}
if (i < 0 || i > lastResults.length - 1) {
console.println("Wrong search result id.");
return -2;
}
return i;
}
}