package edu.washington.cs.oneswarm.ui.gwt.server; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; import org.gudy.azureus2.core3.download.DownloadManager; import org.gudy.azureus2.core3.download.DownloadManagerState; import org.gudy.azureus2.core3.download.DownloadManagerStats; import org.gudy.azureus2.core3.peer.PEPeerManager; import org.gudy.azureus2.core3.peer.impl.PEPeerTransport; import org.gudy.azureus2.core3.torrent.TOTorrent; import org.gudy.azureus2.core3.torrent.TOTorrentException; import org.gudy.azureus2.core3.torrent.TOTorrentFile; import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse; import org.gudy.azureus2.core3.util.Average; import org.gudy.azureus2.core3.util.DisplayFormatters; import org.gudy.azureus2.core3.util.HashWrapper; import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo; import org.gudy.azureus2.plugins.download.Download; import org.gudy.azureus2.plugins.download.DownloadStats; import org.gudy.azureus2.plugins.torrent.Torrent; import com.aelitis.azureus.core.AzureusCoreException; import com.aelitis.azureus.core.impl.AzureusCoreImpl; import edu.washington.cs.oneswarm.f2f.FileCollection; import edu.washington.cs.oneswarm.ui.gwt.F2FInterface; import edu.washington.cs.oneswarm.ui.gwt.rpc.FileListLite; import edu.washington.cs.oneswarm.ui.gwt.rpc.TorrentInfo; public class TorrentInfoFactory { /* * for multi source speeds to be recorded properly, keep track of the number * of bytes and update the download rate displayed to be the max of the * azureus internal version and the calculated value */ private final static String KEY_BYTES = "multisource_downloaded_bytes"; private final static String KEY_AVERAGE_OBJ = "multisource_average_obj"; public static TorrentInfo create(F2FInterface f2fIface, Download download, String defaultVideoFile) { TorrentInfo torrentInfo = new TorrentInfo(); Torrent torrent = download.getTorrent(); DownloadStats downloadStat = download.getStats(); int status = download.getState(); int torrent_seeds = 0; int torrentLeechers = 0; if (status == Download.ST_DOWNLOADING) { try { torrent_seeds = download.getPeerManager().getStats().getConnectedSeeds(); } catch (Throwable e) { torrent_seeds = 0; } try { torrentLeechers = download.getPeerManager().getStats().getConnectedLeechers(); } catch (Throwable e) { torrentLeechers = 0; } } else if (status == Download.ST_SEEDING) { try { torrentLeechers = download.getPeerManager().getStats().getConnectedLeechers(); } catch (Throwable e) { torrentLeechers = 0; } } torrentInfo.setSharePublic(f2fIface.isSharedWithPublic(download.getTorrent().getHash())); torrentInfo.setShareWithFriends(f2fIface.isSharedWithFriends(download.getTorrent() .getHash())); torrentInfo.setStatus(download.getState()); torrentInfo.setTorrentID(OneSwarmHashUtils.createOneSwarmHash(torrent.getHash())); torrentInfo.setName(download.getName()); torrentInfo.setComment(torrent.getComment()); torrentInfo.setDownloaded(downloadStat.getDownloaded()); DownloadManager downloadManager = AzureusCoreImpl.getSingleton().getGlobalManager() .getDownloadManager(new HashWrapper(download.getTorrent().getHash())); if (downloadManager == null) return null; torrentInfo.setProgress(computeSkippedAwareProgress(downloadManager)); DownloadManagerState downloadState = downloadManager.getDownloadState(); Long dateVal = downloadState .getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME); torrentInfo.setAddedDate(dateVal); setErrorStateFromDLManager(torrentInfo, downloadManager); long sizeExcludeSkipped = 0; DiskManagerFileInfo[] files = download.getDiskManagerFileInfo(); for (DiskManagerFileInfo df : files) { if (!df.isSkipped()) { sizeExcludeSkipped += df.getLength(); } } torrentInfo.setTotalSize(sizeExcludeSkipped); torrentInfo.setDownloadRate(downloadStat.getDownloadAverage() / 1024); torrentInfo.setUploadRate(downloadStat.getUploadAverage() / 1024); torrentInfo.setRemaining(downloadStat.getETA()); try { torrentInfo.setDefaultMovieName(URLEncoder.encode(defaultVideoFile, "UTF-8")); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } torrentInfo.setStatusText(downloadStat.getStatus(true)); torrentInfo.setTotalUploaded(downloadStat.getUploaded()); torrentInfo.setTotalDownloaded(downloadStat.getDownloaded()); torrentInfo.setSeeders(torrent_seeds); int torrent_total_seeds = download.getLastScrapeResult().getSeedCount(); torrentInfo.setTotalSeeders(torrent_total_seeds); torrentInfo.setLeechers(torrentLeechers); int torrent_total_leechers = download.getLastScrapeResult().getNonSeedCount(); torrentInfo.setTotalLeechers(torrent_total_leechers); /* * ************** count the number of f2f peers in the swarm */ int f2fSeeds = 0; int f2fLeechers = 0; PEPeerManager peerManager = downloadManager.getPeerManager(); if (peerManager != null) { final List peers = peerManager.getPeers(); final int peersSize = peers.size(); for (int i = 0; i < peersSize; i++) { final PEPeerTransport peer = (PEPeerTransport) peers.get(i); if ("FriendToFriend over SSL".equals(peer.getEncryption())) { if (peer.isSeed()) { f2fSeeds++; } else { f2fLeechers++; } } } } torrentInfo.setSeedersF2F(f2fSeeds); torrentInfo.setLeechersF2f(f2fLeechers); // *************** torrentInfo.setAvailability(downloadStat.getAvailability()); torrentInfo.setNumFiles(download.getDiskManagerFileInfo().length); torrentInfo.calcHashCode(); if (downloadManager.getData("sha1_rate") != null) { Average a = (Average) downloadManager.getData("sha1_rate"); long rate = a.getAverage(); if (rate > 0) { torrentInfo.setExtraSourceSpeed(rate); } } return torrentInfo; } private static void setErrorStateFromDLManager(TorrentInfo torrentInfo, DownloadManager downloadManager) { short errorState = 0; if (downloadManager.getData("oneswarm.no.permissions") != null) { errorState |= TorrentInfo.NO_PERMISSIONS; } torrentInfo.setErrorState(errorState); } public static TorrentInfo create(F2FInterface f2fIface, DownloadManager download, String defaultVideoFile) throws AzureusCoreException, TOTorrentException { TorrentInfo torrentInfo = new TorrentInfo(); TOTorrent torrent = download.getTorrent(); DownloadManagerStats downloadStat = download.getStats(); int status = download.getState(); int torrent_seeds = 0; int torrentLeechers = 0; if (status == Download.ST_DOWNLOADING) { try { torrent_seeds = download.getPeerManager().getNbSeeds(); } catch (Throwable e) { torrent_seeds = 0; } try { torrentLeechers = download.getPeerManager().getNbPeers(); } catch (Throwable e) { torrentLeechers = 0; } } else if (status == Download.ST_SEEDING) { try { torrentLeechers = download.getPeerManager().getNbPeers(); } catch (Throwable e) { torrentLeechers = 0; } } torrentInfo.setSharePublic(f2fIface.isSharedWithPublic(download.getTorrent().getHash())); torrentInfo.setShareWithFriends(f2fIface.isSharedWithFriends(download.getTorrent() .getHash())); torrentInfo.setStatus(convertState(download.getState())); torrentInfo.setTorrentID(OneSwarmHashUtils.createOneSwarmHash(torrent.getHash())); torrentInfo.setName(new String(torrent.getName())); String comment = ""; if (torrent.getComment() != null) { comment = new String(torrent.getComment()); } torrentInfo.setComment(comment); torrentInfo.setDownloaded(downloadStat.getTotalDataBytesReceived()); // torrentInfo.setProgress(download.getStats().getCompleted()); /* * Replaced this to be aware of skipped files */ // torrentInfo.setProgress(downloadStat.getCompleted()); torrentInfo.setProgress(computeSkippedAwareProgress(download)); DownloadManager downloadManager = AzureusCoreImpl.getSingleton().getGlobalManager() .getDownloadManager(new HashWrapper(download.getTorrent().getHash())); if (downloadManager == null) return null; DownloadManagerState downloadState = downloadManager.getDownloadState(); Long dateVal = downloadState .getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME); torrentInfo.setAddedDate(dateVal); setErrorStateFromDLManager(torrentInfo, downloadManager); torrentInfo.setTotalSize(torrent.getSize()); torrentInfo.setDownloadRate(downloadStat.getDataReceiveRate() / 1024.0); torrentInfo.setUploadRate(downloadStat.getDataSendRate() / 1024.0); torrentInfo.setRemaining(downloadStat.getElapsedTime()); try { if (defaultVideoFile == null) { torrentInfo.setDefaultMovieName(""); } else { torrentInfo.setDefaultMovieName(URLEncoder.encode(defaultVideoFile, "UTF-8")); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } torrentInfo.setStatusText(DisplayFormatters.formatDownloadStatusDefaultLocale(download)); torrentInfo.setTotalUploaded(downloadStat.getTotalDataBytesSent() + downloadStat.getTotalProtocolBytesSent()); torrentInfo.setTotalDownloaded(downloadStat.getTotalGoodDataBytesReceived()); torrentInfo.setSeeders(torrent_seeds); TRTrackerScraperResponse trackerScrapeResponse = download.getTrackerScrapeResponse(); if (trackerScrapeResponse != null) { int torrent_total_seeds = trackerScrapeResponse.getSeeds(); int torrent_total_leechers = trackerScrapeResponse.getPeers(); torrentInfo.setTotalLeechers(torrent_total_leechers); torrentInfo.setTotalSeeders(torrent_total_seeds); } torrentInfo.setLeechers(torrentLeechers); /* * ************** count the number of f2f peers in the swarm */ int f2fSeeds = 0; int f2fLeechers = 0; PEPeerManager peerManager = downloadManager.getPeerManager(); if (peerManager != null) { final List peers = peerManager.getPeers(); final int peersSize = peers.size(); for (int i = 0; i < peersSize; i++) { final PEPeerTransport peer = (PEPeerTransport) peers.get(i); if ("FriendToFriend over SSL".equals(peer.getEncryption())) { if (peer.isSeed()) { f2fSeeds++; } else { f2fLeechers++; } } } } torrentInfo.setSeedersF2F(f2fSeeds); torrentInfo.setLeechersF2f(f2fLeechers); // *************** torrentInfo.setAvailability(downloadStat.getAvailability()); torrentInfo.setNumFiles(download.getDiskManagerFileInfo().length); torrentInfo.calcHashCode(); if (downloadManager.getData("sha1_rate") != null) { Average a = (Average) downloadManager.getData("sha1_rate"); long rate = a.getAverage(); if (rate > 0) { torrentInfo.setExtraSourceSpeed(rate); } } return torrentInfo; } private static int computeSkippedAwareProgress(DownloadManager download) { if (download.getState() == DownloadManager.STATE_CHECKING) { return 0; } if (download.isDownloadComplete(false)) { return 1000; } org.gudy.azureus2.core3.disk.DiskManagerFileInfo[] infos = download .getDiskManagerFileInfo(); TOTorrentFile[] files = download.getTorrent().getFiles(); long downloaded = 0, toDownload = 0; for (int i = 0; i < infos.length; i++) { org.gudy.azureus2.core3.disk.DiskManagerFileInfo info = infos[i]; // System.out.println("size: " + downloaded + " / " + toDownload + // " (after: " + info.getFile().getName() + " skipped? " + // (info.isSkipped() ? 'y' : 'n')); if (info.isSkipped()) continue; toDownload += files[i].getLength(); downloaded += info.getDownloaded(); } // System.out.println("downloaded: " + downloaded + " toDownload: " + // toDownload); int completion = (int) (downloaded * 100 / toDownload * 100) / 10; /** * corner case. disk manager seems to report 100% DLs for a short time * during startup before 0ing. */ if (completion == 1000 && download.getStats().getCompleted() == 0) return 0; return completion; } public static TorrentInfo create(F2FInterface f2fIface, DownloadManagerAdapter download, String largestFileName) { TorrentInfo torrentInfo = new TorrentInfo(); // Torrent torrent = download.getTorrent(); // DownloadManagerStats downloadStat = download.getStats(); int torrent_seeds = 0; int torrentLeechers = 0; torrentInfo.setSharePublic(false); torrentInfo.setShareWithFriends(true); torrentInfo.setStatus(download.getState()); try { torrentInfo.setTorrentID(OneSwarmHashUtils.createOneSwarmHash(download.getTorrent() .getHash())); } catch (TOTorrentException e) { e.printStackTrace(); } torrentInfo.setName(download.getDisplayName()); torrentInfo.setComment(""); torrentInfo.setDownloaded(0); torrentInfo.setProgress(1000); DownloadManagerState downloadState = download.getDownloadState(); Long dateVal = downloadState .getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME); torrentInfo.setAddedDate(dateVal); torrentInfo.setTotalSize(download.getTorrent().getSize()); torrentInfo.setDownloadRate(0); torrentInfo.setUploadRate(0); torrentInfo.setRemaining(""); torrentInfo.setDefaultMovieName(largestFileName); torrentInfo.setStatusText("f2f"); torrentInfo.setTotalUploaded(0); torrentInfo.setTotalDownloaded(0); torrentInfo.setSeeders(torrent_seeds); int torrent_total_seeds = 0; torrentInfo.setTotalSeeders(torrent_total_seeds); torrentInfo.setLeechers(torrentLeechers); int torrent_total_leechers = 0; torrentInfo.setTotalLeechers(torrent_total_leechers); torrentInfo.setAvailability(1.0); torrentInfo.setNumFiles(1); torrentInfo.calcHashCode(); torrentInfo.setF2F_ID(download.getFriendID(), download.getFriendNick()); FileCollection coll = download.getCollection(); torrentInfo.setFileListLiteRep(new FileListLite(coll.getUniqueID(), coll.getName(), coll .getChildren().get(0).getFileName(), coll.getChildren().get(0).getLength(), coll .getFileNum(), coll.getAddedTimeUTC(), 1, false, false)); return torrentInfo; } private static int convertState(int dm_state) { // dm states: waiting -> initialising -> initialized -> // disk states: allocating -> checking -> ready -> // dm states: downloading -> finishing -> seeding -> stopping -> stopped // "initialize" call takes from waiting -> initialising -> waiting (no // port) or initialized (ok) // if initialized then disk manager runs through to ready // "startdownload" takes ready -> dl etc. // "stopIt" takes to stopped which is equiv to ready int our_state; switch (dm_state) { case DownloadManager.STATE_WAITING: { our_state = Download.ST_WAITING; break; } case DownloadManager.STATE_INITIALIZING: case DownloadManager.STATE_INITIALIZED: case DownloadManager.STATE_ALLOCATING: case DownloadManager.STATE_CHECKING: { our_state = Download.ST_PREPARING; break; } case DownloadManager.STATE_READY: { our_state = Download.ST_READY; break; } case DownloadManager.STATE_DOWNLOADING: case DownloadManager.STATE_FINISHING: // finishing download - transit to // seeding { our_state = Download.ST_DOWNLOADING; break; } case DownloadManager.STATE_SEEDING: { our_state = Download.ST_SEEDING; break; } case DownloadManager.STATE_STOPPING: { our_state = Download.ST_STOPPING; break; } case DownloadManager.STATE_STOPPED: { our_state = Download.ST_STOPPED; break; } case DownloadManager.STATE_QUEUED: { our_state = Download.ST_QUEUED; break; } case DownloadManager.STATE_ERROR: { our_state = Download.ST_ERROR; break; } default: { our_state = Download.ST_ERROR; } } return (our_state); } }