public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof TorrentDownloaderImpl) { TorrentDownloaderImpl other = (TorrentDownloaderImpl) obj; if (other.getURL().equals(this.url.toString())) { File other_file = other.getFile(); File this_file = file; if (other_file == this_file) { return (true); } if (other_file == null || this_file == null) { return (false); } return (other_file.getAbsolutePath().equals(this_file.getAbsolutePath())); } else { return false; } } else { return false; } }
protected static long getTorrentDataSizeFromFileOrDirSupport(File file) { String name = file.getName(); if (name.equals(".") || name.equals("..")) { return (0); } if (!file.exists()) { return (0); } if (file.isFile()) { return (file.length()); } else { File[] dir_files = file.listFiles(); long length = 0; for (int i = 0; i < dir_files.length; i++) { length += getTorrentDataSizeFromFileOrDirSupport(dir_files[i]); } return (length); } }
protected TOTorrentCreateImpl( File _torrent_base, URL _announce_url, boolean _add_other_hashes, long _piece_length) throws TOTorrentException { super(_torrent_base.getName(), _announce_url, _torrent_base.isFile()); torrent_base = _torrent_base; piece_length = _piece_length; add_other_hashes = _add_other_hashes; }
private void save() { File file = getCacheFile(); file.getParentFile().mkdirs(); System.out.println("Writing cache: " + file); FileUtil.writeResilientFile(file, contents); dirty = false; }
private void loadExportedParameters() { synchronized (exported_parameters) { try { File parent_dir = new File(SystemProperties.getUserPath()); File props = new File(parent_dir, "exported_params.properties"); if (props.exists()) { LineNumberReader lnr = new LineNumberReader(new InputStreamReader(new FileInputStream(props), "UTF-8")); try { while (true) { String line = lnr.readLine(); if (line == null) { break; } String[] bits = line.split("="); if (bits.length == 2) { String key = bits[0].trim(); String value = bits[1].trim(); if (key.length() > 0 && value.length() > 0) { imported_parameters.put(key, value); } } } } finally { lnr.close(); } } } catch (Throwable e) { e.printStackTrace(); } } COConfigurationManager.setIntDefault("instance.port", Constants.INSTANCE_PORT); registerExportedParameter("instance.port", "instance.port"); }
public String getDirectoryParameter(String parameter) throws IOException { String dir = getStringParameter(parameter); if (dir.length() > 0) { File temp = new File(dir); if (!temp.exists()) { FileUtil.mkdirs(temp); } if (!temp.isDirectory()) { throw new IOException("Configuration error. This is not a directory: " + dir); } } return dir; }
private Map<String, List<Long>> getContents() { if (contents == null) { File file = getCacheFile(); if (file.exists()) { System.out.println("Reading cache: " + file); contents = FileUtil.readResilientFile(file); } else { contents = new HashMap<String, List<Long>>(); } } return (contents); }
protected TOTorrentCreateImpl( File _torrent_base, URL _announce_url, boolean _add_other_hashes, long _piece_min_size, long _piece_max_size, long _piece_num_lower, long _piece_num_upper) throws TOTorrentException { super(_torrent_base.getName(), _announce_url, _torrent_base.isFile()); torrent_base = _torrent_base; add_other_hashes = _add_other_hashes; long total_size = calculateTotalFileSize(_torrent_base); piece_length = getComputedPieceSize( total_size, _piece_min_size, _piece_max_size, _piece_num_lower, _piece_num_upper); }
protected long getTotalFileSizeSupport(File file) throws TOTorrentException { String name = file.getName(); ///////////////////////////////////////// ///////////////////////////////////// if (name.equals(".") || name.equals("..")) { return (0); } if (!file.exists()) { throw (new TOTorrentException( "TOTorrentCreate: file '" + file.getName() + "' doesn't exist", TOTorrentException.RT_FILE_NOT_FOUND)); } if (file.isFile()) { if (!ignoreFile(name)) { total_file_count++; return (file.length()); } else { return (0); } } else { File[] dir_files = file.listFiles(); if (dir_files == null) { throw (new TOTorrentException( "TOTorrentCreate: directory '" + file.getAbsolutePath() + "' returned error when listing files in it", TOTorrentException.RT_FILE_NOT_FOUND)); } long length = 0; for (int i = 0; i < dir_files.length; i++) { length += getTotalFileSizeSupport(dir_files[i]); } return (length); } }
public long[] getTotalUsageInPeriod(Date start_date, Date end_date) { synchronized (this) { long[] result = new long[STAT_ENTRY_COUNT]; long start_millis = start_date.getTime(); long end_millis = end_date.getTime(); long now = SystemTime.getCurrentTime(); long now_day = (now / DAY_IN_MILLIS) * DAY_IN_MILLIS; if (end_millis > now) { end_millis = now; } long start_day = (start_millis / DAY_IN_MILLIS) * DAY_IN_MILLIS; long end_day = (end_millis / DAY_IN_MILLIS) * DAY_IN_MILLIS; if (start_day > end_day) { return (result); } long start_offset = start_millis - start_day; start_offset = start_offset / MIN_IN_MILLIS; boolean offset_cachable = start_offset % 60 == 0; System.out.println( "start=" + debug_utc_format.format(start_date) + ", end=" + debug_utc_format.format(end_date) + ", offset=" + start_offset); MonthCache month_cache = null; for (long this_day = start_day; this_day <= end_day; this_day += DAY_IN_MILLIS) { String[] bits = utc_date_format.format(new Date(this_day)).split(","); String year_str = bits[0]; String month_str = bits[1]; String day_str = bits[2]; int year = Integer.parseInt(year_str); int month = Integer.parseInt(month_str); int day = Integer.parseInt(day_str); if (month_cache == null || !month_cache.isForMonth(year_str, month_str)) { if (month_cache != null && month_cache.isDirty()) { month_cache.save(); } month_cache = getMonthCache(year_str, month_str); } boolean can_cache = this_day != now_day && (this_day > start_day || (this_day == start_day && offset_cachable)) && this_day < end_day; long cache_offset = this_day == start_day ? start_offset : 0; if (can_cache) { long[] cached_totals = month_cache.getTotals(day, cache_offset); if (cached_totals != null) { for (int i = 0; i < cached_totals.length; i++) { result[i] += cached_totals[i]; } continue; } } else { if (this_day == now_day) { if (day_cache != null) { if (day_cache.isForDay(year_str, month_str, day_str)) { long[] cached_totals = day_cache.getTotals(cache_offset); if (cached_totals != null) { for (int i = 0; i < cached_totals.length; i++) { result[i] += cached_totals[i]; } continue; } } else { day_cache = null; } } } } String current_rel_file = bits[0] + File.separator + bits[1] + File.separator + bits[2] + ".dat"; File stats_file = new File(stats_dir, current_rel_file); if (!stats_file.exists()) { if (can_cache) { month_cache.setTotals(day, cache_offset, new long[0]); } } else { LineNumberReader lnr = null; try { System.out.println("Reading " + stats_file); lnr = new LineNumberReader(new FileReader(stats_file)); long file_start_time = 0; long[] file_totals = null; long[] file_result_totals = new long[STAT_ENTRY_COUNT]; long[] session_start_stats = null; long session_start_time = 0; long session_time = 0; while (true) { String line = lnr.readLine(); if (line == null) { break; } // System.out.println( line ); String[] fields = line.split(","); if (fields.length < 6) { continue; } String first_field = fields[0]; if (first_field.equals("s")) { session_start_time = Long.parseLong(fields[2]) * MIN_IN_MILLIS; if (file_totals == null) { file_totals = new long[STAT_ENTRY_COUNT]; file_start_time = session_start_time; } session_time = session_start_time; session_start_stats = new long[STAT_ENTRY_COUNT]; for (int i = 3; i < 9; i++) { session_start_stats[i - 3] = Long.parseLong(fields[i]); } } else if (session_start_time > 0) { session_time += MIN_IN_MILLIS; int field_offset = 0; if (first_field.equals("e")) { field_offset = 3; } long[] line_stats = new long[STAT_ENTRY_COUNT]; for (int i = 0; i < 6; i++) { line_stats[i] = Long.parseLong(fields[i + field_offset]); file_totals[i] += line_stats[i]; } if (session_time >= start_millis && session_time <= end_millis) { for (int i = 0; i < 6; i++) { result[i] += line_stats[i]; file_result_totals[i] += line_stats[i]; } } // System.out.println( getString( line_stats )); } } System.out.println( "File total: start=" + debug_utc_format.format(file_start_time) + ", end=" + debug_utc_format.format(session_time) + " - " + getString(file_totals)); if (can_cache) { month_cache.setTotals(day, cache_offset, file_result_totals); if (cache_offset != 0) { month_cache.setTotals(day, 0, file_totals); } } else { if (this_day == now_day) { if (day_cache == null) { System.out.println("Creating day cache"); day_cache = new DayCache(year_str, month_str, day_str); } day_cache.setTotals(cache_offset, file_result_totals); if (cache_offset != 0) { day_cache.setTotals(0, file_totals); } } } } catch (Throwable e) { Debug.out(e); } finally { if (lnr != null) { try { lnr.close(); } catch (Throwable e) { } } } } } if (month_cache != null && month_cache.isDirty()) { month_cache.save(); } System.out.println(" -> " + getString(result)); return (result); } }
private void write(int record_type, long[] line_stats) { synchronized (this) { try { final long now = SystemTime.getCurrentTime(); final long now_mins = now / (1000 * 60); String[] bits = utc_date_format.format(new Date(now)).split(","); String year = bits[0]; String month = bits[1]; String day = bits[2]; String current_rel_file = year + File.separator + month + File.separator + day + ".dat"; String line; String stats_str = ""; if (record_type == RT_SESSION_START) { // absolute values for (int i = 0; i < line_stats.length; i++) { stats_str += "," + line_stats[i]; line_stats_prev[i] = 0; } day_cache = null; } else { // relative values long[] diffs = new long[STAT_ENTRY_COUNT]; for (int i = 0; i < line_stats.length; i++) { long diff = line_stats[i] - line_stats_prev[i]; session_total += diff; diffs[i] = diff; stats_str += "," + diff; line_stats_prev[i] = line_stats[i]; stat_averages[i].update(diff); } if (day_cache != null) { if (day_cache.isForDay(year, month, day)) { day_cache.addRecord(now_mins, diffs); } } } if (record_type != RT_SESSION_STATS) { line = (record_type == RT_SESSION_START ? "s," : "e,") + VERSION + "," + now_mins + stats_str; } else { line = stats_str.substring(1); } if (writer == null || !writer_rel_file.equals(current_rel_file)) { // first open of a file or file switch if (writer != null) { // file switch if (record_type != RT_SESSION_START) { writer.println(line); } writer.close(); if (writer.checkError()) { writer = null; throw (new IOException("Write faled")); } writer = null; } // no point in opening a new file just to record the session-end if (record_type != RT_SESSION_END) { File file = new File(stats_dir, current_rel_file); file.getParentFile().mkdirs(); writer = new PrintWriter(new FileWriter(file, true)); writer_rel_file = current_rel_file; if (record_type == RT_SESSION_START) { writer.println(line); } else { // first entry in a new file, files always start with a session-start so they // can be processed in isolation so reset the session data and start a new one st_p_sent += line_stats[0]; st_d_sent += line_stats[1]; st_p_received += line_stats[2]; st_d_received += line_stats[3]; st_dht_sent += line_stats[4]; st_dht_received += line_stats[5]; ss_p_sent += line_stats[0]; ss_d_sent += line_stats[1]; ss_p_received += line_stats[2]; ss_d_received += line_stats[3]; ss_dht_sent += line_stats[4]; ss_dht_received += line_stats[5]; stats_str = ""; long[] st_stats = new long[] { st_p_sent, st_d_sent, st_p_received, st_d_received, st_dht_sent, st_dht_received }; for (int i = 0; i < st_stats.length; i++) { stats_str += "," + st_stats[i]; line_stats_prev[i] = 0; } line = "s," + VERSION + "," + now_mins + stats_str; writer.println(line); } } } else { writer.println(line); } } catch (Throwable e) { Debug.out("Failed to write long term stats", e); } finally { if (writer != null) { if (record_type == RT_SESSION_END) { writer.close(); } if (writer.checkError()) { Debug.out("Failed to write long term stats"); writer.close(); writer = null; } else { if (record_type == RT_SESSION_END) { writer = null; } } } } } if (record_type != RT_SESSION_END) { final List<LongTermStatsListener> to_fire = new ArrayList<LongTermStatsListener>(); for (Object[] entry : listeners) { long diff = session_total - (Long) entry[2]; if (diff >= (Long) entry[1]) { entry[2] = session_total; to_fire.add((LongTermStatsListener) entry[0]); } } if (to_fire.size() > 0) { dispatcher.dispatch( new AERunnable() { @Override public void runSupport() { for (LongTermStatsListener l : to_fire) { try { l.updated(LongTermStatsImpl.this); } catch (Throwable e) { Debug.out(e); } } } }); } } }
protected void processDir(TOTorrentFileHasher hasher, File dir, Vector encoded, String root) throws TOTorrentException { File[] dir_file_list = dir.listFiles(); if (dir_file_list == null) { throw (new TOTorrentException( "TOTorrentCreate: directory '" + dir.getAbsolutePath() + "' returned error when listing files in it", TOTorrentException.RT_FILE_NOT_FOUND)); } // sort contents so that multiple encodes of a dir always // generate same torrent List file_list = new ArrayList(Arrays.asList(dir_file_list)); Collections.sort(file_list); long offset = 0; for (int i = 0; i < file_list.size(); i++) { File file = (File) file_list.get(i); String file_name = file.getName(); if (!(file_name.equals(".") || file_name.equals(".."))) { if (file.isDirectory()) { if (root.length() > 0) { file_name = root + File.separator + file_name; } processDir(hasher, file, encoded, file_name); } else { if (!ignoreFile(file_name)) { if (root.length() > 0) { file_name = root + File.separator + file_name; } long length = hasher.add(file); TOTorrentFileImpl tf = new TOTorrentFileImpl(this, offset, length, file_name); offset += length; if (add_other_hashes) { byte[] ed2k_digest = hasher.getPerFileED2KDigest(); byte[] sha1_digest = hasher.getPerFileSHA1Digest(); // System.out.println( "file:ed2k = " + ByteFormatter.nicePrint( ed2k_digest, true )); // System.out.println( "file:sha1 = " + ByteFormatter.nicePrint( sha1_digest, true )); tf.setAdditionalProperty("sha1", sha1_digest); tf.setAdditionalProperty("ed2k", ed2k_digest); } encoded.addElement(tf); } } } } }
public void runSupport() { try { new URL(url_str); // determine if this is already a proper URL } catch (Throwable t) { // it's not // //check if the string is just a base32/hex-encoded torrent infohash // // String magnet_uri = UrlUtils.normaliseMagnetURI( url_str ); // // if ( magnet_uri != null ){ // // url_str = magnet_uri; // } } try { url = AddressUtils.adjustURL(new URL(url_str)); String protocol = url.getProtocol().toLowerCase(); // hack here - the magnet download process requires an additional paramter to cause it to // stall on error so the error can be reported // if ( protocol.equals( "magnet" ) || protocol.equals( "dht" )){ // // url = AddressUtils.adjustURL( new URL(url_str+"&pause_on_error=true")); // } for (int i = 0; i < 2; i++) { try { // if ( protocol.equals("https")){ // // // see ConfigurationChecker for SSL client defaults // // HttpsURLConnection ssl_con = (HttpsURLConnection)url.openConnection(); // // // allow for certs that contain IP addresses rather than dns names // // ssl_con.setHostnameVerifier( // new HostnameVerifier() // { // public boolean // verify( // String host, // SSLSession session ) // { // return( true ); // } // }); // // con = ssl_con; // // }else{ // con = (HttpURLConnection) url.openConnection(); // } con.setRequestProperty( "User-Agent", Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION); if (referrer != null && referrer.length() > 0) { con.setRequestProperty("Referer", referrer); } if (request_properties != null) { Iterator it = request_properties.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); // currently this code doesn't support gzip/deflate... if (!key.equalsIgnoreCase("Accept-Encoding")) { con.setRequestProperty(key, value); } } } this.con.connect(); break; // }catch( SSLException e ){ // // if ( i == 0 ){ // // if ( SESecurityManager.installServerCertificates( url ) != null ){ // // // certificate has been installed // // continue; // retry with new certificate // } // } // // throw( e ); // } catch (IOException e) { if (i == 0) { URL retry_url = UrlUtils.getIPV4Fallback(url); if (retry_url != null) { url = retry_url; } else { throw (e); } } } } int response = this.con.getResponseCode(); if (!ignoreReponseCode) { if ((response != HttpURLConnection.HTTP_ACCEPTED) && (response != HttpURLConnection.HTTP_OK)) { this.error(response, Integer.toString(response) + ": " + this.con.getResponseMessage()); return; } } /* Map headerFields = this.con.getHeaderFields(); System.out.println("Header of download of " + url_str); for (Iterator iter = headerFields.keySet().iterator(); iter.hasNext();) { String s = (String) iter.next(); System.out.println(s + ":" + headerFields.get(s)); } */ filename = this.con.getHeaderField("Content-Disposition"); if ((filename != null) && filename .toLowerCase() .matches(".*attachment.*")) // Some code to handle b0rked servers. while (filename.toLowerCase().charAt(0) != 'a') filename = filename.substring(1); if ((filename == null) || !filename.toLowerCase().startsWith("attachment") || (filename.indexOf('=') == -1)) { String tmp = this.url.getFile(); if (tmp.length() == 0 || tmp.equals("/")) { filename = url.getHost(); } else if (tmp.startsWith("?")) { // probably a magnet URI - use the hash // magnet:?xt=urn:sha1:VGC53ZWCUXUWVGX7LQPVZIYF4L6RXSU6 String query = tmp.toUpperCase(); int pos = query.indexOf("XT=URN:SHA1:"); if (pos == -1) { pos = query.indexOf("XT=URN:BTIH:"); } if (pos != -1) { pos += 12; int p2 = query.indexOf("&", pos); if (p2 == -1) { filename = query.substring(pos); } else { filename = query.substring(pos, p2); } } else { filename = "Torrent" + (long) (Math.random() * Long.MAX_VALUE); } filename += ".tmp"; } else { if (tmp.lastIndexOf('/') != -1) tmp = tmp.substring(tmp.lastIndexOf('/') + 1); // remove any params in the url int param_pos = tmp.indexOf('?'); if (param_pos != -1) { tmp = tmp.substring(0, param_pos); } filename = URLDecoder.decode(tmp, Constants.DEFAULT_ENCODING); } } else { filename = filename.substring(filename.indexOf('=') + 1); if (filename.startsWith("\"") && filename.endsWith("\"")) filename = filename.substring(1, filename.lastIndexOf('\"')); filename = URLDecoder.decode(filename, Constants.DEFAULT_ENCODING); // not sure of this piece of logic here but I'm not changing it at the moment File temp = new File(filename); filename = temp.getName(); } filename = FileUtil.convertOSSpecificChars(filename, false); // directoryname = // COConfigurationManager.getDirectoryParameter("General_sDefaultTorrent_Directory"); // boolean useTorrentSave = COConfigurationManager.getBooleanParameter("Save Torrent // Files"); directoryname = "D:\\Development\\testDownloads\\"; boolean useTorrentSave = true; if (file_str != null) { // not completely sure about the whole logic in this block File temp = new File(file_str); // if we're not using a default torrent save dir if (!useTorrentSave || directoryname.length() == 0) { // if it's already a dir if (temp.isDirectory()) { // use it directoryname = temp.getCanonicalPath(); } // it's a file else { // so use its parent dir directoryname = temp.getCanonicalFile().getParent(); } } // if it's a file if (!temp.isDirectory()) { // set the file name filename = temp.getName(); } } // what would happen here if directoryname == null and file_str == null?? this.state = STATE_INIT; this.notifyListener(); } catch (java.net.MalformedURLException e) { this.error(0, "Exception while parsing URL '" + url + "':" + e.getMessage()); } catch (java.net.UnknownHostException e) { this.error( 0, "Exception while initializing download of '" + url + "': Unknown Host '" + e.getMessage() + "'"); } catch (java.io.IOException ioe) { this.error(0, "I/O Exception while initializing download of '" + url + "':" + ioe.toString()); } catch (Throwable e) { this.error(0, "Exception while initializing download of '" + url + "':" + e.toString()); } if (this.state == STATE_ERROR) { return; } try { final boolean status_reader_run[] = {true}; this.state = STATE_START; notifyListener(); this.state = STATE_DOWNLOADING; notifyListener(); Thread status_reader = new AEThread("TorrentDownloader:statusreader") { public void runSupport() { boolean changed_status = false; while (true) { try { Thread.sleep(100); try { this_mon.enter(); if (!status_reader_run[0]) { break; } } finally { this_mon.exit(); } String s = con.getResponseMessage(); if (!s.equals(getStatus())) { if (!s.toLowerCase().startsWith("error:")) { if (s.toLowerCase().indexOf("alive") != -1) { if (percentDone < 10) { percentDone++; } } int pos = s.indexOf('%'); if (pos != -1) { int i; for (i = pos - 1; i >= 0; i--) { char c = s.charAt(i); if (!Character.isDigit(c) && c != ' ') { i++; break; } } try { percentDone = Integer.parseInt(s.substring(i, pos).trim()); } catch (Throwable e) { } } setStatus(s); } else { error(con.getResponseCode(), s.substring(6)); } changed_status = true; } } catch (Throwable e) { break; } } if (changed_status) { setStatus(""); } } }; status_reader.setDaemon(true); status_reader.start(); InputStream in; try { in = this.con.getInputStream(); } catch (FileNotFoundException e) { if (ignoreReponseCode) { in = this.con.getErrorStream(); } else { throw e; } } finally { try { this_mon.enter(); status_reader_run[0] = false; } finally { this_mon.exit(); } } // handle some servers that return gzip'd torrents even though we don't request it! String encoding = con.getHeaderField("content-encoding"); if (encoding != null) { if (encoding.equalsIgnoreCase("gzip")) { in = new GZIPInputStream(in); } else if (encoding.equalsIgnoreCase("deflate")) { in = new InflaterInputStream(in); } } if (this.state != STATE_ERROR) { this.file = new File(this.directoryname, filename); boolean useTempFile = false; try { this.file.createNewFile(); useTempFile = !this.file.exists(); } catch (Throwable t) { useTempFile = true; } if (useTempFile) { this.file = File.createTempFile("AZU", ".torrent", new File(this.directoryname)); this.file.createNewFile(); } FileOutputStream fileout = new FileOutputStream(this.file, false); bufBytes = 0; int size = (int) UrlUtils.getContentLength(con); this.percentDone = -1; do { if (this.cancel) { break; } try { bufBytes = in.read(buf); this.readTotal += bufBytes; if (size != 0) { this.percentDone = (100 * this.readTotal) / size; } notifyListener(); } catch (IOException e) { } if (bufBytes > 0) { fileout.write(buf, 0, bufBytes); } } while (bufBytes > 0); in.close(); fileout.flush(); fileout.close(); if (this.cancel) { this.state = STATE_CANCELLED; if (deleteFileOnCancel) { this.cleanUpFile(); } } else { if (this.readTotal <= 0) { this.error(0, "No data contained in '" + this.url.toString() + "'"); return; } // if the file has come down with a not-so-useful name then we try to rename // it to something more useful try { if (!filename.toLowerCase().endsWith(".torrent")) { TOTorrent torrent = TorrentUtils.readFromFile(file, false); String name = TorrentUtils.getLocalisedName(torrent) + ".torrent"; File new_file = new File(directoryname, name); if (file.renameTo(new_file)) { filename = name; file = new_file; } } } catch (Throwable e) { Debug.printStackTrace(e); } // TorrentUtils.setObtainedFrom( file, original_url ); this.state = STATE_FINISHED; } this.notifyListener(); } } catch (Exception e) { if (!cancel) { Debug.out("'" + this.directoryname + "' '" + filename + "'", e); } this.error(0, "Exception while downloading '" + this.url.toString() + "':" + e.getMessage()); } }