/*
* Created on 22 Aug 2008
* Created by Allan Crooks
* Copyright (C) 2008 Vuze Inc., All Rights Reserved.
*
* 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 org.gudy.azureus2.ui.console.commands;
import java.io.File;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import org.gudy.azureus2.core3.util.AESemaphore;
import org.gudy.azureus2.core3.util.AEThread2;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.FileUtil;
import org.gudy.azureus2.plugins.PluginException;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.PluginManager;
import org.gudy.azureus2.plugins.installer.InstallablePlugin;
import org.gudy.azureus2.plugins.installer.PluginInstallationListener;
import org.gudy.azureus2.plugins.installer.PluginInstaller;
import org.gudy.azureus2.plugins.installer.StandardPlugin;
import org.gudy.azureus2.plugins.update.Update;
import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
import org.gudy.azureus2.plugins.update.UpdateCheckInstanceListener;
import org.gudy.azureus2.plugins.update.UpdateManager;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderAdapter;
import org.gudy.azureus2.pluginsimpl.update.sf.SFPluginDetails;
import org.gudy.azureus2.pluginsimpl.update.sf.SFPluginDetailsLoaderFactory;
import org.gudy.azureus2.ui.console.ConsoleInput;
import org.gudy.azureus2.ui.console.util.TextWrap;
public class Plugin extends IConsoleCommand {
public Plugin()
{
super("plugin");
}
public String getCommandDescriptions()
{
return("plugin [various options]\t\tRun with no parameter for more help.");
}
public void printHelpExtra(PrintStream out, List args) {
out.println("> -----");
out.println("Subcommands:");
out.println("install\t[pluginid]\tLists plugins available to install or installs a given plugin");
out.println("location\t\tLists where plugins are being loaded from");
out.println("list\t\t\tList all running plugins");
out.println("listall\t\t\tList all plugins - running or not");
out.println("status pluginid\t\tPrints the status of a given plugin");
out.println("startup pluginid on|off\tEnables or disables the plugin running at startup");
out.println("uninstall pluginid\t\tUninstalls a plugin");
out.println("update\t\tUpdates all plugins with outstanding updates");
out.println("> -----");
}
public void execute(String commandName, final ConsoleInput ci, List args) {
if (args.isEmpty()) {
printHelpExtra(ci.out, args);
return;
}
String subcmd = (String)args.get(0);
if (!java.util.Arrays.asList(new String[] {
"location", "list", "listall", "status", "startup", "install", "uninstall", "update"
}).contains(subcmd)) {
ci.out.println("Invalid subcommand: " + subcmd);
ci.out.println();
return;
}
PluginManager plugin_manager = ci.getCore().getPluginManager();
if (subcmd.equals("list") || subcmd.equals("listall")) {
boolean all_plugins = subcmd.equals("listall");
ci.out.println("> -----");
PluginInterface[] plugins = plugin_manager.getPluginInterfaces();
TreeSet plugin_ids = new TreeSet(String.CASE_INSENSITIVE_ORDER);
for (int i=0; i<plugins.length; i++) {
if (!all_plugins && !plugins[i].getPluginState().isOperational()) {continue;}
String plugin_id = plugins[i].getPluginID();
plugin_ids.add(plugin_id);
}
TextWrap.printList(plugin_ids.iterator(), ci.out, " ");
ci.out.println("> -----");
return;
}
if (subcmd.equals("location")) {
// Taken from ConfigSectionPlugins.
File fUserPluginDir = FileUtil.getUserFile("plugins");
String sep = File.separator;
String sUserPluginDir;
try{
sUserPluginDir = fUserPluginDir.getCanonicalPath();
}catch( Throwable e ){
sUserPluginDir = fUserPluginDir.toString();
}
if (!sUserPluginDir.endsWith(sep)) {
sUserPluginDir += sep;
}
File fAppPluginDir = FileUtil.getApplicationFile("plugins");
String sAppPluginDir;
try{
sAppPluginDir = fAppPluginDir.getCanonicalPath();
}catch( Throwable e ){
sAppPluginDir = fAppPluginDir.toString();
}
if (!sAppPluginDir.endsWith(sep)) {
sAppPluginDir += sep;
}
ci.out.println("Shared plugin location:");
ci.out.println(" " + sAppPluginDir);
ci.out.println("User plugin location:");
ci.out.println(" " + sUserPluginDir);
ci.out.println();
return;
}
if ( subcmd.equals( "update" )){
if ( args.size() != 1 ){
ci.out.println( "Usage: update" );
return;
}
UpdateManager update_manager = plugin_manager.getDefaultPluginInterface().getUpdateManager();
final UpdateCheckInstance checker = update_manager.createUpdateCheckInstance();
checker.addListener(
new UpdateCheckInstanceListener()
{
public void
cancelled(
UpdateCheckInstance instance )
{
}
public void
complete(
UpdateCheckInstance instance )
{
Update[] updates = instance.getUpdates();
try{
for ( Update update: updates ){
ci.out.println( "Updating " + update.getName());
for ( ResourceDownloader rd: update.getDownloaders()){
rd.addListener(
new ResourceDownloaderAdapter()
{
public void
reportActivity(
ResourceDownloader downloader,
String activity )
{
ci.out.println( "\t" + activity );
}
public void
reportPercentComplete(
ResourceDownloader downloader,
int percentage )
{
ci.out.println( "\t" + percentage + "%" );
}
});
rd.download();
}
}
boolean restart_required = false;
for (int i=0;i<updates.length;i++){
if ( updates[i].getRestartRequired() == Update.RESTART_REQUIRED_YES ){
restart_required = true;
}
}
if ( restart_required ){
ci.out.println( "**** Restart required to complete update ****" );
}
}catch( Throwable e ){
ci.out.println( "Plugin update failed: " + Debug.getNestedExceptionMessage( e ));
}
}
});
checker.start();
return;
}
if ( subcmd.equals( "install" )){
if ( args.size() == 1 ){
ci.out.println( "Contacting plugin repository for list of available plugins..." );
try{
SFPluginDetails[] plugins = SFPluginDetailsLoaderFactory.getSingleton().getPluginDetails();
for ( SFPluginDetails p: plugins ){
String category = p.getCategory();
if ( category != null ){
if ( category.equalsIgnoreCase( "hidden" ) || ( category.equalsIgnoreCase( "core" ))){
continue;
}
}
String id = p.getId();
if ( plugin_manager.getPluginInterfaceByID( id, false ) == null ){
String desc = p.getDescription();
int pos = desc.indexOf( "<br" );
if ( pos > 0 ){
desc = desc.substring( 0, pos );
}
ci.out.println( "\t" + id + ": \t\t" + desc );
}
}
}catch( Throwable e ){
ci.out.println( "Failed to list plugins: " + Debug.getNestedExceptionMessage( e ));
}
}else{
String target_id = (String)args.get(1);
if ( plugin_manager.getPluginInterfaceByID( target_id, false ) != null ){
ci.out.println( "Plugin '" + target_id + "' already installed" );
return;
}
final PluginInstaller installer = plugin_manager.getPluginInstaller();
try{
final StandardPlugin sp = installer.getStandardPlugin( target_id );
if ( sp == null ){
ci.out.println( "Plugin '" + target_id + "' is unknown" );
return;
}
new AEThread2( "Plugin Installer" )
{
public void
run()
{
try{
Map<Integer, Object> properties = new HashMap<Integer, Object>();
properties.put( UpdateCheckInstance.PT_UI_STYLE, UpdateCheckInstance.PT_UI_STYLE_NONE );
properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
final AESemaphore sem = new AESemaphore( "plugin-install" );
final boolean[] restart_required = { false };
UpdateCheckInstance instance =
installer.install(
new InstallablePlugin[]{ sp },
false,
properties,
new PluginInstallationListener() {
public void
completed()
{
ci.out.println( "Installation complete" );
sem.release();
}
public void
cancelled()
{
ci.out.println( "Installation cancelled" );
sem.release();
}
public void
failed(
PluginException e )
{
ci.out.println( "Installation failed: " + Debug.getNestedExceptionMessage( e ));
sem.release();
}
});
instance.addListener(
new UpdateCheckInstanceListener() {
public void
cancelled(
UpdateCheckInstance instance )
{
ci.out.println( "Installation cancelled" );
}
public void
complete(
UpdateCheckInstance instance )
{
Update[] updates = instance.getUpdates();
for ( final Update update: updates ){
ResourceDownloader[] rds = update.getDownloaders();
for ( ResourceDownloader rd: rds ){
rd.addListener(
new ResourceDownloaderAdapter()
{
public void
reportActivity(
ResourceDownloader downloader,
String activity )
{
ci.out.println( "\t" + activity );
}
public void
reportPercentComplete(
ResourceDownloader downloader,
int percentage )
{
ci.out.println( "\t" + percentage + "%" );
}
});
// go ahead and actually initiate the install, someone has to do it!
try{
rd.download();
}catch( Throwable e ){
}
}
if ( update.getRestartRequired() != Update.RESTART_REQUIRED_NO ){
restart_required[0] = true;
}
}
}
});
sem.reserve();
if ( restart_required[0] ){
ci.out.println( "**** Restart required to complete installation ****" );
}
}catch( Throwable e ){
ci.out.println( "Install failed: " + Debug.getNestedExceptionMessage( e ));
}
}
}.start();
}catch( Throwable e ){
ci.out.println( "Install failed: " + Debug.getNestedExceptionMessage( e ));
}
}
return;
}
// Commands from this point require a plugin ID.
if (args.size() == 1) {
ci.out.println("No plugin ID given.");
ci.out.println();
return;
}
String plugin_id = (String)args.get(1);
PluginInterface plugin = plugin_manager.getPluginInterfaceByID(plugin_id, false);
if (plugin == null) {
ci.out.println("Invalid plugin ID: " + plugin_id);
ci.out.println();
return;
}
if (subcmd.equals("status")) {
ci.out.println("ID : " + plugin.getPluginID());
ci.out.println("Name : " + plugin.getPluginName());
ci.out.println("Version: " + plugin.getPluginVersion());
ci.out.println("Running: " + plugin.getPluginState().isOperational());
ci.out.println("Runs at startup: " + plugin.getPluginState().isLoadedAtStartup());
if (!plugin.getPluginState().isBuiltIn()) {
ci.out.println("Location: " + plugin.getPluginDirectoryName());
}
ci.out.println();
return;
}
if (subcmd.equals("startup")) {
if (args.size() == 2) {
ci.out.println("Need to pass either \"on\" or \"off\"");
ci.out.println();
return;
}
String enabled_mode = (String)args.get(2);
if (enabled_mode.equals("on")) {
plugin.getPluginState().setLoadedAtStartup(true);
}
else if (enabled_mode.equals("off")) {
plugin.getPluginState().setLoadedAtStartup(false);
}
else {
ci.out.println("Need to pass either \"on\" or \"off\"");
ci.out.println();
return;
}
ci.out.println("Done.");
ci.out.println();
return;
}
if ( subcmd.equals( "uninstall" )){
PluginInterface pi = plugin_manager.getPluginInterfaceByID( plugin_id, false );
if ( pi == null ){
ci.out.println( "Plugin '" + plugin_id + "' is not installed" );
return;
}
final PluginInstaller installer = plugin_manager.getPluginInstaller();
try{
final StandardPlugin sp = installer.getStandardPlugin( plugin_id );
if ( sp == null ){
ci.out.println( "Plugin '" + plugin_id + "' is not a standard plugin" );
return;
}
final PluginInstaller uninstaller = plugin_manager.getPluginInstaller();
Map<Integer, Object> properties = new HashMap<Integer, Object>();
final AESemaphore sem = new AESemaphore( "plugin-uninstall" );
UpdateCheckInstance instance =
uninstaller.uninstall(
new PluginInterface[]{ pi },
new PluginInstallationListener() {
public void
completed()
{
ci.out.println( "Uninstallation complete" );
sem.release();
}
public void
cancelled()
{
ci.out.println( "Uninstallation cancelled" );
sem.release();
}
public void
failed(
PluginException e )
{
ci.out.println( "Uninstallation failed: " + Debug.getNestedExceptionMessage( e ));
sem.release();
}
},
properties );
instance.addListener(
new UpdateCheckInstanceListener() {
public void
cancelled(
UpdateCheckInstance instance )
{
ci.out.println( "InsUninstallationtallation cancelled" );
}
public void
complete(
UpdateCheckInstance instance )
{
Update[] updates = instance.getUpdates();
for ( final Update update: updates ){
ResourceDownloader[] rds = update.getDownloaders();
for ( ResourceDownloader rd: rds ){
try{
rd.download();
}catch( Throwable e ){
}
}
}
}
});
sem.reserve();
Object obj = properties.get( UpdateCheckInstance.PT_UNINSTALL_RESTART_REQUIRED );
if ( obj instanceof Boolean && (Boolean)obj ){
ci.out.println( "**** Restart required to complete uninstallation ****" );
}
}catch( Throwable e ){
ci.out.println( "Uninstall failed: " + Debug.getNestedExceptionMessage( e ));
}
}
}
}