Skip to content

Instantly share code, notes, and snippets.

@marcoacierno
Last active August 29, 2015 14:10
Show Gist options
  • Select an option

  • Save marcoacierno/5c65d1775d6c5e3c981f to your computer and use it in GitHub Desktop.

Select an option

Save marcoacierno/5c65d1775d6c5e3c981f to your computer and use it in GitHub Desktop.
IntellIJ IDEA Theme downloader
package com.besaba.revonline.themesdownloader;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException, XPathExpressionException {
final int totalThemes = 219; // it will go from 0 to totalThemes
final int maxThreads = Runtime.getRuntime().availableProcessors();
final int urlsPerThread = totalThemes / maxThreads;
final ExecutorService executor = Executors.newCachedThreadPool();
final CompletionService<List<Theme>> completionService = new ExecutorCompletionService<>(executor);
final Set<Future<List<Theme>>> futures = new HashSet<>();
final Path downloadPath = Paths.get(System.getProperty("user.dir"), "Themes");
Files.createDirectories(downloadPath);
final List<Theme> themes = new ArrayList<>();
for (int start = 0; start < totalThemes; start += urlsPerThread + 1) {
System.out.println("Assigned new task, start: " + start + " end " + (start + urlsPerThread));
futures.add(completionService.submit(new URLsDownloadTask(start, start + urlsPerThread, downloadPath)));
}
while (!futures.isEmpty()) {
try {
Future<List<Theme>> readyFuture = completionService.take();
futures.remove(readyFuture);
themes.addAll(readyFuture.get());
} catch (InterruptedException | ExecutionException e) {
System.err.println("Qualcosa è andato storto " + e.getMessage());
}
}
System.out.printf("Okay, i downloaded %d of %d themes!%n", themes.size(), totalThemes);
System.out.println("Themes downloaded:");
themes.forEach(System.out::println);
}
}
package com.besaba.revonline.themesdownloader;
/**
* Created by marco on 25/11/14.
*/
public class Theme {
private final String name;
private final String url;
private final String toString;
public Theme(final String url, final String name) {
this.url = url;
this.name = name;
toString = name + ": " + url;
}
public String getName() {
return name;
}
public String getUrl() {
return url;
}
@Override
public String toString() {
return toString;
}
}
package com.besaba.revonline.themesdownloader;
import org.jsoup.HttpStatusException;
import org.jsoup.Jsoup;
import org.jsoup.helper.HttpConnection;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
/**
* Created by marco on 25/11/14.
*/
class URLsDownloadTask implements Callable<List<Theme>> {
private final int start;
private final Path downloadPath;
private final int end;
private final int count;
public URLsDownloadTask(final int start, final int end, final Path downloadPath) {
this.end = end;
this.start = start;
this.downloadPath = downloadPath;
count = end - start;
}
@Override
public List<Theme> call() throws Exception {
final List<Theme> links = new ArrayList<>();
for (int i = 0; i < count; ++i) {
final Document document;
final String url = "http://www.ideacolorthemes.org/themes/" + (start + i) + "/";
try {
document = Jsoup.connect(url).get();
} catch (HttpStatusException ex) {
System.err.println("Failed with error code " + ex.getStatusCode() + ", url: " + ex.getUrl());
continue;
} catch (SocketTimeoutException ex) {
System.err.println("Failed with timeout, url: " + url);
continue;
}
final Element downloadNode =
document.select("body > div.container.relative > h1 > a.btn.btn-success.btn-download-theme").first();
final Element nameNode =
document.select("body > div.container.relative > h1").first();
final String themeName = nameNode.textNodes().get(0).text().trim();
final String downloadUrl = downloadNode.attr("href");
System.out.format("Success, url: %s%n", downloadUrl);
links.add(new Theme(downloadUrl, themeName));
final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
final InputStream internetStream = connection.getInputStream();
final Path jarFile = Paths.get(downloadPath.toString(), themeName + ".jar");
Files.deleteIfExists(jarFile);
try {
final FileOutputStream fileStream = new FileOutputStream(jarFile.toFile());
copy(internetStream, fileStream);
fileStream.flush();
} catch (IOException ex) {
System.err.println("Exception mentre scaricavo il file " + themeName + ". " + ex.getMessage());
}
System.out.println("Downloaded theme " + themeName);
}
return links;
}
// a very dummy implementation of a stream copy :)
private static void copy(InputStream input, OutputStream output) throws IOException {
final byte[] buf = new byte[4096];
while (true) {
final int read = input.read(buf);
if (read == -1) {
break;
}
output.write(buf, 0, read);
}
}
}
@marcoacierno
Copy link
Author

pom.xml

<dependencies>
  <dependency>
    <!-- jsoup HTML parser library @ http://jsoup.org/ -->
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.8.1</version>
  </dependency>
</dependencies>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment