Package com.aelitis.azureus.plugins.extseed

Source Code of com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin

/*
* Created on 15-Dec-2005
* Created by Paul Gardner
* Copyright (C) 2005, 2006 Aelitis, 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.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/

package com.aelitis.azureus.plugins.extseed;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;

import org.gudy.azureus2.core3.util.AEThread2;
import org.gudy.azureus2.core3.util.SystemTime;
import org.gudy.azureus2.plugins.Plugin;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.download.Download;
import org.gudy.azureus2.plugins.download.DownloadManagerListener;
import org.gudy.azureus2.plugins.download.DownloadManagerStats;
import org.gudy.azureus2.plugins.download.DownloadPeerListener;
import org.gudy.azureus2.plugins.logging.LoggerChannel;
import org.gudy.azureus2.plugins.logging.LoggerChannelListener;
import org.gudy.azureus2.plugins.peers.PeerManager;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
import org.gudy.azureus2.plugins.ui.components.UITextField;
import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
import org.gudy.azureus2.plugins.utils.*;
import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;

import com.aelitis.azureus.core.tracker.TrackerPeerSource;
import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
import com.aelitis.azureus.plugins.extseed.impl.getright.ExternalSeedReaderFactoryGetRight;
import com.aelitis.azureus.plugins.extseed.impl.webseed.ExternalSeedReaderFactoryWebSeed;

public class
ExternalSeedPlugin
  implements Plugin, DownloadManagerListener
{
  private static ExternalSeedReaderFactory[]  factories = {
    new ExternalSeedReaderFactoryGetRight(),
    new ExternalSeedReaderFactoryWebSeed(),
  };
 
  private PluginInterface      plugin_interface;
  private DownloadManagerStats  dm_stats;
 
  private UITextField        status_field;
  private LoggerChannel      log;
 
  private     Random  random = new Random();
 
  private Map    download_map  = new HashMap();
  private Monitor  download_mon;
 
  public static void
  load(
    PluginInterface    plugin_interface )
  {
    plugin_interface.getPluginProperties().setProperty( "plugin.version",   "1.0" );
    plugin_interface.getPluginProperties().setProperty( "plugin.name",     "External Seed" );
  }
 
  public void
  initialize(
    PluginInterface  _plugin_interface )
  {
    plugin_interface  = _plugin_interface;
   
    dm_stats = plugin_interface.getDownloadManager().getStats();
   
    log  = plugin_interface.getLogger().getTimeStampedChannel( "External Seeds" );
   
    final BasicPluginViewModel  view_model =
      plugin_interface.getUIManager().createBasicPluginViewModel( "Plugin.extseed.name" );

   
    view_model.getActivity().setVisible( false );
    view_model.getProgress().setVisible( false );
   
    log.addListener(
        new LoggerChannelListener()
        {
          public void
          messageLogged(
            int    type,
            String  content )
          {
            view_model.getLogArea().appendText( content + "\n" );
          }
         
          public void
          messageLogged(
            String    str,
            Throwable  error )
          {
            if ( str.length() > 0 ){
              view_model.getLogArea().appendText( str + "\n" );
            }
           
            StringWriter sw = new StringWriter();
           
            PrintWriter  pw = new PrintWriter( sw );
           
            error.printStackTrace( pw );
           
            pw.flush();
           
            view_model.getLogArea().appendText( sw.toString() + "\n" );
          }
        });   
   
    status_field = view_model.getStatus();
   
    setStatus( "Initialising" );
   
    download_mon  = plugin_interface.getUtilities().getMonitor();
   
    Utilities utilities = plugin_interface.getUtilities();
   
    final DelayedTask dt = plugin_interface.getUtilities().createDelayedTask(new Runnable()
      {
        public void
        run()
        {
          AEThread2 t =
            new AEThread2( "ExternalSeedInitialise", true )
            {
              public void
              run()
              {
                setStatus( "Running" );
               
                plugin_interface.getDownloadManager().addListener( ExternalSeedPlugin.this);
              }
            };
         
          t.setPriority( Thread.MIN_PRIORITY );
         
          t.start();
         
        }
      });
   
    dt.queue();   
   
    UTTimer timer = utilities.createTimer("ExternalPeerScheduler", true);
   
    timer.addPeriodicEvent(
        5000,
        new UTTimerEventPerformer()
        {
          public void
          perform(
            UTTimerEvent    event )
          {
            try{
              Iterator  it = download_map.values().iterator();
             
              while( it.hasNext()){
               
                List  peers = randomiseList((List)it.next());
               
                for (int i=0;i<peers.size();i++){
                 
                    // bail out early if the state changed for this peer
                    // so one peer at a time gets a chance to activate
                 
                  if (((ExternalSeedPeer)peers.get(i)).checkConnection()){
                   
                    break;
                  }
                }
              }
             
            }catch( Throwable e ){
              // we do this without holding the monitor as doing so causes potential
              // deadlock between download_mon and the connection's connection_mon
             
              // so ignore possible errors here that may be caused by concurrent
              // modification to the download_map ans associated lists. We are only
              // reading the data so errors will only be transient
            }
          }
        });
   
  }
 
  public void
  downloadAdded(
    Download  download )
  {
    Torrent  torrent = download.getTorrent();
   
    if ( torrent == null ){
     
      return;
    }
   
    List  peers = new ArrayList();
   
    for (int i=0;i<factories.length;i++){


      String attributeID = "no-ext-seeds-" + factories[i].getClass().getSimpleName();
      TorrentAttribute attribute = plugin_interface.getTorrentManager().getPluginAttribute( attributeID );

      boolean noExternalSeeds = download.getBooleanAttribute(attribute);
      if (noExternalSeeds) {
        continue;   
      }
     
      ExternalSeedReader[]  x = factories[i].getSeedReaders( this, download );
     
      if (x.length == 0) {
        download.setBooleanAttribute(attribute, true);
      } else {

        for (int j=0;j<x.length;j++){
         
          ExternalSeedReader  reader = x[j];
         
          ExternalSeedPeer  peer = new ExternalSeedPeer( this, download, reader );
         
          peers.add( peer );
        }
      }
    }
   
    addPeers( download, peers );
  }
   
  public void
  downloadChanged(
    Download  download )
  {
    downloadRemoved( download );
   
    downloadAdded( download );
  }
 
  public List<ExternalSeedPeer>
  addSeed(
    Download  download,
    Map      config )
  {
    Torrent  torrent = download.getTorrent();
   
    List<ExternalSeedPeer>  peers = new ArrayList<ExternalSeedPeer>();
    
    if ( torrent != null ){
           
      for (int i=0;i<factories.length;i++){
       
        String attributeID = "no-ext-seeds-" + factories[i].getClass().getSimpleName();
        TorrentAttribute attribute = plugin_interface.getTorrentManager().getPluginAttribute( attributeID );

        ExternalSeedReader[]  x = factories[i].getSeedReaders( this, download, config );
       
        download.setBooleanAttribute(attribute, x.length == 0);
       
        for (int j=0;j<x.length;j++){
         
          ExternalSeedReader  reader = x[j];
         
          ExternalSeedPeer  peer = new ExternalSeedPeer( this, download, reader );
         
          peers.add( peer );
        }
      }
     
      addPeers( download, peers );
    }
   
    return( peers );
  }
 
  protected void
  addPeers(
    final Download  download,
    List      _peers )
  {
    final List peers = new ArrayList();
   
    peers.addAll( _peers );
 
    if ( peers.size() > 0 ){
     
      boolean  add_listener = false;
     
      try{
        download_mon.enter();
       
        List  existing_peers = (List)download_map.get( download );
       
        if ( existing_peers == null ){
         
          add_listener  = true;
         
          existing_peers = new ArrayList();
         
          download_map.put( download, existing_peers );
        }
 
        Iterator  it = peers.iterator();
         
        while( it.hasNext()){
         
          ExternalSeedPeer  peer = (ExternalSeedPeer)it.next();
         
          boolean  skip = false;
         
          for (int j=0;j<existing_peers.size();j++){
           
            ExternalSeedPeer  existing_peer = (ExternalSeedPeer)existing_peers.get(j);
           
            if ( existing_peer.sameAs( peer )){
             
              skip  = true;
             
              break;
            }
          }

          if ( skip ){
           
            it.remove();
           
          }else{
           
            log( download.getName() + " found seed " + peer.getName());
           

            existing_peers.add( peer );
          }
        }
       
       
        setStatus( "Running: Downloads with external seeds = " + download_map.size());
       
      }finally{
       
        download_mon.exit();
      }
     
      if ( add_listener ){
     
        download.addPeerListener(
          new DownloadPeerListener()
          {
            public void
            peerManagerAdded(
              Download    download,
              PeerManager    peer_manager )
            {
              List  existing_peers = getPeers();
 
              if ( existing_peers== null ){
               
                return;
              }
             
              for (int i=0;i<existing_peers.size();i++){
               
                ExternalSeedPeer  peer = (ExternalSeedPeer)existing_peers.get(i);
               
                peer.setManager( peer_manager );
              }
            }
           
            public void
            peerManagerRemoved(
              Download    download,
              PeerManager    peer_manager )
            {
              List  existing_peers = getPeers();
             
              if ( existing_peers== null ){
               
                return;
              }
             
              for (int i=0;i<existing_peers.size();i++){
               
                ExternalSeedPeer  peer = (ExternalSeedPeer)existing_peers.get(i);
               
                peer.setManager( null );
              }
            }
           
            protected List
            getPeers()
            {
              List  existing_peers = null;
             
              try{
                download_mon.enter();
               
                List  temp = (List)download_map.get( download );
               
                if ( temp != null ){
                 
                  existing_peers = new ArrayList( temp.size());
                 
                  existing_peers.addAll( temp );
                }
              }finally{
               
                download_mon.exit();
              }
             
              return( existing_peers );
            }
          });
      }else{
       
          // fix up newly added peers to current peer manager
       
        PeerManager  existing_pm = download.getPeerManager();
       
        if ( existing_pm != null ){
         
          for (int i=0;i<peers.size();i++){
           
            ExternalSeedPeer  peer = (ExternalSeedPeer)peers.get(i);

            if ( peer.getManager() == null ){
             
              peer.setManager( existing_pm );
            }
          }
        }
      }
    }
  }
 
  protected void
  removePeer(
    ExternalSeedPeer  peer )
  {
    Download  download = peer.getDownload();
   
    try{
      download_mon.enter();
   
      List  existing_peers = (List)download_map.get( download );

      if ( existing_peers != null ){
       
        if ( existing_peers.remove( peer )){
         
          log( download.getName() + " removed seed " + peer.getName());
        }
      }
    }finally{
     
      download_mon.exit();
    }
  }

  public void
  downloadRemoved(
    Download  download )
  {
    try{
      download_mon.enter();
     
      download_map.remove( download );
     
      setStatus( "Running: Downloads with external seeds = " + download_map.size());
     
    }finally{
     
      download_mon.exit();
   
  }
 
  public ExternalSeedManualPeer[]
  getManualWebSeeds(
    Download  download )
  {
    try{
      download_mon.enter();
   
      List  peers = (List)download_map.get( download );
 
      if ( peers == null ){
       
        return( new ExternalSeedManualPeer[0] );
      }
     
      ExternalSeedManualPeer[]  result = new ExternalSeedManualPeer[peers.size()];
     
      for (int i=0;i<peers.size();i++){
       
        result[i] = new ExternalSeedManualPeer((ExternalSeedPeer)peers.get(i));
      }
     
      return( result );
     
    }finally{
     
      download_mon.exit();
   
  }
 
  public TrackerPeerSource
  getTrackerPeerSource(
    final Download    download )
  {
    return(
      new TrackerPeerSourceAdapter()
      {
        private long  fixup_time;
       
        private ExternalSeedManualPeer[]  peers;           
        private boolean            running;
       
        public int
        getType()
        {
          return( TP_HTTP_SEED );
        }
       
        public int
        getStatus()
        {
          fixup();
         
          if ( running ){
         
            return( peers.length==0?ST_UNAVAILABLE:ST_AVAILABLE );
           
          }else{
           
            return( ST_STOPPED );
          }
        }
       
        public String
        getName()
        {
          fixup();
         
          if ( peers.length == 0 ){
           
            return( "" );
          }
         
          StringBuffer sb = new StringBuffer();
         
          for ( ExternalSeedManualPeer peer: peers ){
           
            if ( sb.length() > 0 ){
             
              sb.append( ", " );
            }
           
            String str = peer.getDelegate().getURL().toExternalForm();
           
            int pos = str.indexOf( '?' );
           
            if ( pos != -1 ){
             
              str = str.substring( 0, pos );
            }
           
            sb.append( str );
          }
         
          return( sb.toString());
        }
       
        public int
        getPeers()
        {
          fixup();
         
          if ( running ){
         
            return( peers.length );
           
          }else{
           
            return( -1 );
          }
        }
       
        protected void
        fixup()
        {
          long  now = SystemTime.getMonotonousTime();
         
          if ( now - fixup_time > 10*1000 ){
         
            fixup_time = now;
           
            peers = getManualWebSeeds(download);
           
            int  state = download.getState();
           
            running = state == Download.ST_DOWNLOADING || state == Download.ST_SEEDING;
          }
        }
      });
  }
 
  public int
  getGlobalDownloadRateBytesPerSec()
  {
    return( dm_stats.getDataAndProtocolReceiveRate());
  }
 
  protected void
  setStatus(
    String    str )
  {
    status_field.setText( str );
  }
 
  public void
  log(
    String    str )
  {
    log.log( str );
  }
 
  public void
  log(
    String    str,
    Throwable   e )
  {
    log.log( str, e );
  }
 
  public PluginInterface
  getPluginInterface()
  {
    return( plugin_interface );
  }
 
  protected List
  randomiseList(
    List  l )
  {
    if ( l.size() < 2 ){
     
      return(l);
    }
   
    List  new_list = new ArrayList();
   
    for (int i=0;i<l.size();i++){
     
      new_list.add( random.nextInt(new_list.size()+1), l.get(i));
    }
   
    return( new_list );
  }
}
TOP

Related Classes of com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.