The idea is to batch download a list of movies (torrents) off a torrent site and add them to your server.
I have a little bit of Java experience (sophomore in college), so I'm looking for things that I could improve on.
Main.java
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
public class Main {
public static void main(String[] args) throws IOException, JSchException, InterruptedException, SftpException {
//execution of program
ConfigReader config = new ConfigReader();
List < String > info = new ArrayList < String > ();
info = config.grabUserInfo();
Login login = new Login(info.get(0), info.get(1));
Scanner File1 = new Scanner(new File("C:\\IPDownloader\\movies.txt"));
String token = "";
List < String > temps = new ArrayList < String > ();
while (File1.hasNext()) {
token = File1.nextLine();
temps.add(token);
}
File1.close();
RemoteConnect connect = new RemoteConnect(info.get(2), info.get(3), info.get(4));
for (int i = 0; i <= temps.size() - 1; i++) {
String movie = temps.get(i);
Search search = new Search(login.grabLogin(), movie);
TorrentStarter tor = new TorrentStarter(connect.getAuth(), search.searchMovie(), info.get(5), i);
tor.downloadTorrent();
if (i % 5 == 0 && i != 0) {
System.out.println("Waiting 5 seconds");
Thread.sleep(5000);
}
}
System.exit(0);
}
}
Login.java
import java.io.IOException;
import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
public class Login {
private String username;
private String password;
public Login(String username, String password) {
this.username = username;
this.password = password;
}
public Connection.Response grabLogin() throws IOException {
Response loginRes = Jsoup.connect("https://iptorrents.com/")
.userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0") //robots.txt
.method(Method.GET)
.execute();
Connection.Response res = Jsoup.connect("https://iptorrents.com/")
.userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
.followRedirects(true)
.data("username", username, "password", password)
.method(Method.POST)
.cookies(loginRes.cookies())
.execute();
//posting with cookies using connection.response library
return res;
}
}
ConfigReader.java
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ConfigReader {
/*
* checking for config file or making a new one. can follow format to skip this
*/
public List < String > grabUserInfo() throws IOException {
File configDir = new File("C:\\IPDownloader\\");
File checkFile = new File("C:\\IPDownloader\\config.txt");
boolean exists = configDir.exists();
if (exists && checkFile.length() != 0) {
System.out.println("Reading Config");
String token = "";
Scanner File1 = new Scanner(new File("C:\\IPDownloader\\config.txt"));
List < String > temps = new ArrayList < String > ();
while (File1.hasNext()) {
token = File1.next();
temps.add(token);
}
File1.close();
return temps;
} else {
Scanner s = new Scanner(System. in );
System.out.println("Config not found or it is empty");
System.out.println("Please input your username");
String username = s.nextLine();
System.out.println("Please input your password");
String password = s.nextLine();
System.out.println("Please input the server hostname");
String ipCon = s.nextLine();
System.out.println("Please input server username");
String userCon = s.nextLine();
System.out.println("Please input the server password");
String passCon = s.nextLine();
System.out.println("Please input the watch directory (excluding home directory");
String watchDir = s.nextLine();
System.out.println("Your information has been stored at C:\\IPDownloader\\");
new File("C:\\IPDownloader\\").mkdir();
File configFile = new File("C:\\IPDownloader\\config.txt");
BufferedWriter writer = new BufferedWriter(new FileWriter(configFile));
writer.write(username);
writer.newLine();
writer.write(password);
writer.newLine();
writer.write(ipCon);
writer.newLine();
writer.write(userCon);
writer.newLine();
writer.write(passCon);
writer.newLine();
writer.write(watchDir);
writer.close();
String token = "";
Scanner File1 = new Scanner(new File("C:\\IPDownloader\\config.txt"));
List < String > temps = new ArrayList < String > ();
while (File1.hasNext()) {
token = File1.next();
temps.add(token);
}
File1.close();
return temps;
}
}
}
How could I possibly shorten this?
RemoteConnect.java
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import java.io.*;
public class RemoteConnect {
private String ipCon;
private String userCon;
private String passCon;
public RemoteConnect(String ipCon, String userCon, String passCon) {
this.ipCon = ipCon;
this.userCon = userCon;
this.passCon = passCon;
}
public Object[] getAuth() throws JSchException, InterruptedException, SftpException {
int port = 22;
//using JSch for this
JSch jsch = new JSch();
Session session = jsch.getSession(userCon, ipCon, port);
session.setPassword(passCon);
session.setConfig("StrictHostKeyChecking", "no"); //needed
session.connect(10 * 8000); //timeout
return new Object[] {
jsch, session
}; //need to keep
}
}
Search.java
import java.io.IOException;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class Search {
private Connection.Response res;
private String search = "";
public Search(Connection.Response res, String movie) {
this.res = res;
this.search = movie;
}
public Object[] searchMovie() throws IOException {
String downloadLink = "https://iptorrents.com";
String partLink = "";
//1080p sorted by top seeded movies
Document doc = Jsoup.connect("https://iptorrents.com/t?1080p;q=" + search + ";o=seeders#torrents") //uses jsoup to keep login
.cookies(res.cookies())
.get();
//had to scrape the top DL link. works with dynamic tags. using the icon as a reference
for (Element e: doc.select("td.ac").select("a")) {
if (e.select("i[class=fa fa-download fa-2x]").size() > 0) {
partLink = e.attr("href");
System.out.println(partLink);
downloadLink += partLink;
break;
}
}
if (partLink.isEmpty()) {
System.out.println("going here");
doc = Jsoup.connect("https://iptorrents.com/t?720p;q=" + search + ";o=seeders#torrents") //uses jsoup to keep login
.cookies(res.cookies())
.get();
//had to scrape the top DL link. works with dynamic tags. using the icon as a reference
for (Element a: doc.select("td.ac").select("a")) {
if (a.select("i[class=fa fa-download fa-2x]").size() > 0) {
partLink = a.attr("href");
downloadLink += partLink;
break;
}
}
}
System.out.println("Added " + downloadLink);
return new Object[] {
downloadLink, res
};
}
}
TorrentStarter.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.Connection.Response;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class TorrentStarter {
private String homeDirectory = "";
private String torrent = "";
private Session session = null;
private JSch jsch = null;
private int count = 0;
private Connection.Response res = null;
private ChannelSftp channelSftp = null;
public TorrentStarter(Object[] objectArray, Object[] objectArray2, String watchDir, int count) {
this.torrent = (String) objectArray2[0];
this.jsch = (JSch) objectArray[0];
this.session = (Session) objectArray[1];
this.res = (Response) objectArray2[1];
this.homeDirectory = watchDir;
this.count = count;
}
public void downloadTorrent() throws JSchException, InterruptedException, IOException, SftpException {
//iptorrents requires passkey via cookies for each dl
res = Jsoup.connect(torrent)
.cookies(res.cookies())
.ignoreContentType(true)
.execute();
FileOutputStream out = (new FileOutputStream(new java.io.File("C:\\IPDownloader\\" + "torrent1.torrent")));
out.write(res.bodyAsBytes());
out.close();
Channel channel = session.openChannel("sftp"); //we open the channel here
channel.connect();
channelSftp = (ChannelSftp) channel;
channelSftp.cd(channelSftp.getHome());
File f = new File("C:\\IPDownloader\\torrent1.torrent"); //named torrent1.torrent
FileInputStream fInput = new FileInputStream(f);
channelSftp.put(fInput, f.getName());
fInput.close();
channelSftp.rename((channelSftp.getHome() + "/torrent1.torrent"), (channelSftp.getHome() + homeDirectory + "torrent" + count +".torrent"));
//.rename allows to delete from first directory and then move to new directory. works well
f.delete();
}
}
-
\$\begingroup\$ This question is possibly uninteresting to reviewers. To help reviewers give you better answers, please add sufficient context to your question. The more you tell us about what your code does and what the purpose of doing that is, the easier it will be for reviewers to help you. See also this meta question. \$\endgroup\$Vogel612– Vogel6122015年12月19日 22:13:45 +00:00Commented Dec 19, 2015 at 22:13
1 Answer 1
Some things I noticed while skimming over main:
Encapsulate your configuration
Instead of accessing your configuration through magic indices, you should introduce properly named getters for the properties.
Login login = new Login(info.get(0), info.get(1));
becomes something much more manageable like:
Login login = new Login(config.getUsername(), config.getPassword());
This similarly applies for the construction of RemoteConnect.
Use of intermediary List and old File API
You're using an intermediary List (which uses memory) and the old File
API (which is ... mediocre). Instead of
Scanner File1 = new Scanner(new File("C:\\IPDownloader\\movies.txt")); String token = ""; List < String > temps = new ArrayList < String > (); while (File1.hasNext()) { token = File1.nextLine(); temps.add(token); } File1.close();
you should be able to process the whole "movies.txt" in a Stream:
try (Stream<String> movies = Files.lines(Paths.get(MOVIES_TXT))) {
movies.flatMap(line -> Arrays.stream(line.split("[\\s]+")))
.forEach(movie -> {
//.. the body of your for-loop, best encapsuled in a method
});
} catch (IOException e) {
// handle properly :D
}
Nitpicks
- The initial comment
//execution of program
is needlessness incarnate. File1
should have a camelCased variable name and probably not one with a number in it :DSystem.exit(0);
is superfluous
-
\$\begingroup\$ Thank you so much for the advice! And yeah a lot of the Java I know is from old solutions and stuff in my textbooks / classes, which tends to use deprecated things. \$\endgroup\$Ben– Ben2015年12月15日 10:22:13 +00:00Commented Dec 15, 2015 at 10:22
Explore related questions
See similar questions with these tags.