package atdown; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import javax.xml.bind.DatatypeConverter; import org.apache.commons.io.CopyUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.bitlet.wetorrent.Metafile; import org.gudy.azureus2.core3.logging.Logger; import smartnode.models.Collection; import smartnode.models.Entry; import smartnode.utils.ATFetcher; import smartnode.utils.ATLogger; import smartnode.utils.ATLogger.LogLevel; public class Main { final public static int TIMEOUT = 3000; final public static String ATDIR = System.getProperty("user.home") + "/.atdown/"; public static boolean keepsharing = false; private static PrintStream stdout = System.out; private static PrintStream stderr = System.err; public static void println(String s){ stdout.println(s); } public static void print(String s){ stdout.print(s); } private static void hardLogging() throws FileNotFoundException{ //Logger.allowLoggingToStdErr(true); System.setOut(new PrintStream(new File(ATDIR + "log.out"))); System.setErr(new PrintStream(new File(ATDIR + "log.err"))); } public static void main(String[] args) throws Exception { new File(ATDIR).mkdirs(); List<String> argsl = new ArrayList<String>(Arrays.asList(args)); if (!argsl.remove("-v")){ hardLogging(); } if (argsl.remove("-s")){ keepsharing = true; } Main.println("Welcome to the Academic Torrents Download tool!"); try{ main2(argsl.toArray(new String[]{})); }catch(Exception e){ Main.println("Error: " + e.getMessage()); e.printStackTrace(); } } public static void main2(String[] args) throws Exception { //args = new String[]{"82c64b111b07ff855b8966701a13a25512687521","ls"}; //args = new String[]{"059ed25558b4587143db637ac3ca94bebb57d88d","ls"}; //args = new String[]{"7858fdf307d9fe94aeaaeaeadfc554988b80a3ce"}; //mdim //args = new String[]{"059ed25558b4587143db637ac3ca94bebb57d88d"}; // wiki //args = new String[]{"30ac2ef27829b1b5a7d0644097f55f335ca5241b"}; //args = new String[]{"joseph-paul-cohen-publications"}; //args = new String[]{"ffa02bdccbfd01ac5ce35c2bfee6210abb4ddd0f.torrent"}; //args = new String[]{"tex"}; //args = new String[]{"gnu-radio-rf-captures", "ls"}; //args = new String[]{"massgis-datasets", "ls"}; //args = new String[]{"journal-of-machine-learning-research","ls"}; if (args.length < 1){ Main.println("Usage: atdown ls // list connections"); Main.println("Usage: atdown INFOHASH // download entry"); Main.println("Usage: atdown INFOHASH ls // list contents of entry"); Main.println("Usage: atdown ... -v // verbose"); Main.println("Usage: atdown ... -s // keep sharing"); System.exit(0); } String input = args[0];//"7858fdf307d9fe94aeaaeaeadfc554988b80a3ce"; if (input.equals("ls")){ Main.println("Fetching all collections.."); ATLogger logger = new ATLogger(ATDIR + "log.atlogger", LogLevel.Error); ArrayList<Collection> collections = new ATFetcher(logger).getCollections(); Main.println(String.format("|%-65s|%-25.25s|%6s|%9s|", "url-name", "Name", "count", "total size")); for (Collection c : collections){ Main.println(String.format("|%-65s|%-25.25s|%6s|%9s|", c.getUrlname(), c.getName(), c.getTorrent_count(), Main.humanReadableByteCount(c.getTotal_size_bytes(),true))); //Main.println(c.getUrlname() + ", " + c.getName() + ", " + c.getTorrent_count() + " entries, " + Main.humanReadableByteCount(c.getTotal_size_bytes(),true)); } System.exit(0); } // read torrent filename from command line arg List<Entry> toget = new ArrayList<Entry>(); if (new File(input).exists() && !(new File(input).isDirectory())){ byte[] torrent = IOUtils.toByteArray(new FileInputStream(new File(input))); Metafile meta = new Metafile(new ByteArrayInputStream(torrent)); String infohash = DatatypeConverter.printHexBinary(meta.getInfoSha1()); Entry e = new Entry(infohash); e.setName(meta.getName()); e.setBibtex(meta.getComment()); e.setTorrentFile(torrent); toget.add(e); }else if (input.startsWith("http") || input.startsWith("ftp")){ byte[] torrent = IOUtils.toByteArray(new URL(input)); Metafile meta = new Metafile(new ByteArrayInputStream(torrent)); String infohash = DatatypeConverter.printHexBinary(meta.getInfoSha1()); Entry e = new Entry(infohash); e.setName(meta.getName()); e.setBibtex(meta.getComment()); e.setTorrentFile(torrent); toget.add(e); }else{ try{ // if length 40 we try as info hash if (input.length() != 40) throw new Exception("Cannot be hash, not a big deal"); byte[] torrent = getFromCacheOrDownload(input); Metafile meta = new Metafile(new ByteArrayInputStream(torrent)); String infohash = DatatypeConverter.printHexBinary(meta.getInfoSha1()); Entry e = new Entry(infohash); e.setName(meta.getName()); e.setBibtex(meta.getComment()); e.setTorrentFile(torrent); toget.add(e); }catch(Exception e){ // not a hash, maybe collection ATLogger logger = new ATLogger(ATDIR + "log.atlogger", LogLevel.Error); Map<String, Entry> collection = new ATFetcher(logger).getCollectionEntries(input); if (collection == null || collection.size() == 0){ Main.println("Error fetching collection"); logger.printLastLines(); System.exit(-1); } int count = 0; Main.print("Fetching collection " + count + "/" + collection.size()); for (Entry entry : collection.values()){ count++; try{ //System.out.println(entry.getInfohash()); byte[] torrent = getFromCacheOrDownload(entry.getInfohash()); Metafile meta = new Metafile(new ByteArrayInputStream(torrent)); String infohash = DatatypeConverter.printHexBinary(meta.getInfoSha1()); entry.setTorrentFile(torrent); if (!entry.getInfohash().equalsIgnoreCase(infohash)){ Main.println(entry.getInfohash()); Main.println(infohash); throw new Exception("Collection-Entry Consistancy Error"); } toget.add(entry); }catch(Exception ex){ Main.println("Error with entry: " + entry.getInfohash()); } Main.print("\rFetching collection " + count + "/" + collection.size()); } Main.println(""); } } if (toget.size() < 1){ Main.println("Nothing selected to download"); System.exit(-1); } ///////////////////////////////////////////////// // now toget has the files we are looking for DownloadEngine de; if (args.length >= 2){ // special op if ("ls".equals(args[1])){ // just list files for (Entry e : toget){ new WeTorrentDownloadEngine().ls(e); } }else if ("info".equals(args[1])){ }else{ de = new VuzeATDownloadEngine(); // download specific files // NOT WORKING YET for (Entry e : toget){ de.download(e, args[1]); } } }else{ // just resume or start download it de = new VuzeATDownloadEngine(); for (Entry e : toget){ de.download(e, null); } } //de.shutdown(); } public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + "B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); return String.format("%.1f%sB", bytes / Math.pow(unit, exp), pre); } public static String humanReadableByteCountRatio(long bytes, long totbytes, boolean si) { int unit = si ? 1000 : 1024; if (totbytes < unit) return bytes + "/" + totbytes + "B"; int exp = (int) (Math.log(totbytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); return String.format("%.1f/%.1f%sB", bytes / Math.pow(unit, exp), totbytes / Math.pow(unit, exp), pre); } public static String clean(String s){ return s.replaceAll("[^\\x00-\\x7f]", ""); } private static byte[] getFromCacheOrDownload(String infohash) throws MalformedURLException, IOException{ infohash = infohash.toLowerCase(); try{ byte[] torrent = IOUtils.toByteArray(new FileInputStream(new File(Main.ATDIR + infohash + ".torrent"))); // verify it works Metafile meta = new Metafile(new ByteArrayInputStream(torrent)); return torrent; }catch(Exception e){ byte[] torrent = IOUtils.toByteArray(new URL("http://academictorrents.com/download/" + infohash)); FileOutputStream fw = new FileOutputStream(Main.ATDIR + infohash + ".torrent"); IOUtils.copy(new ByteArrayInputStream(torrent), fw); fw.flush(); fw.close(); return torrent; } } }