diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/video/PornhubRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/video/PornhubRipper.java index 60cdf3c0..678435af 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/video/PornhubRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/video/PornhubRipper.java @@ -3,12 +3,14 @@ package com.rarchives.ripme.ripper.rippers.video; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONArray; +import org.apache.commons.lang.StringEscapeUtils; import org.jsoup.nodes.Document; import com.rarchives.ripme.ripper.VideoRipper; @@ -55,43 +57,97 @@ public class PornhubRipper extends VideoRipper { @Override public void rip() throws IOException { + String vidUrl = ""; LOGGER.info(" Retrieving " + this.url.toExternalForm()); Document doc = Http.url(this.url).get(); String html = doc.body().html(); - Pattern p = Pattern.compile("^.*flashvars_[0-9]+ = (.+});.*$", Pattern.DOTALL); - Matcher m = p.matcher(html); - if (m.matches()) { - String vidUrl = null; - try { - JSONObject json = new JSONObject(m.group(1)); + html = StringEscapeUtils.unescapeJavaScript(html); + html = html.substring(html.indexOf("var ra")); + html = html.substring(0, html.indexOf('\n')); + html = html.replaceAll("\\/\\*([\\S\\s]+?)\\*\\/", ""); // Delete JS comments from the String - JSONArray mediaDef = (JSONArray) json.get("mediaDefinitions"); - int bestQual = 0; - for (int i = 0; i < mediaDef.length(); i++) { - JSONObject e = (JSONObject) mediaDef.get(i); - if (!"upsell".equals(e.getString("format"))) { - int quality = Integer.parseInt((String)e.get("quality")); - if (quality > bestQual) { - bestQual = quality; - vidUrl = (String)e.get("videoUrl"); - } + String varName; + String varValue; + int nextEqual; + int nextSemicolonSpace; + HashMap vars = new HashMap<>(); + HashMap qualityMap = new HashMap<>(); + ArrayList urlArray = new ArrayList<>(); + + for (int i = 0; i < 4; i++) { // Max. 4 loops for 240p, 480p, 720p, 1080p + + // Put every of the (unsorted) variables with their corresponding values in a HashMap + while (html.startsWith("var ra")) { + nextEqual = html.indexOf('='); + nextSemicolonSpace = html.indexOf(';'); + varName = html.substring(4,nextEqual); + varValue = html.substring(nextEqual + 1, nextSemicolonSpace); + // Remove """ and " + " from varValue + varValue = varValue.replaceAll("\"", ""); + varValue = varValue.replaceAll(" \\+ ", ""); + vars.put(varName, varValue); + html = html.substring(nextSemicolonSpace + 1); + } + + // put every variable's name in an ArrayList + if (html.startsWith("var quality")) { + int next = 3; + nextEqual = html.indexOf('='); + urlArray.add(html.substring(12, nextEqual - 1)); // Get numeric value of the video's resolution to compare it later + html = html.substring(nextEqual + 1); + while (html.startsWith("ra")) { + nextSemicolonSpace = html.indexOf(' '); + if (nextSemicolonSpace > html.indexOf(';')) { + nextSemicolonSpace = html.indexOf(';'); + next = 1; + } + varName = html.substring(0, nextSemicolonSpace); + urlArray.add(varName); + html = html.substring(nextSemicolonSpace + next); + } + } + + // Put together vidURL by matching the variable's names with the corresponding value from the vars-Map + for (int k = 1; k < urlArray.size(); k++) { + varName = urlArray.get(k); + Iterator> iterator = vars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (varName.equals(entry.getKey())) { + vidUrl = vidUrl + entry.getValue(); + iterator.remove(); + break; } } - if (vidUrl == null) { - throw new IOException("Unable to find encrypted video URL at " + this.url); - } - addURLToDownload(new URL(vidUrl), HOST + "_" + bestQual + "p_" + getGID(this.url)); - } catch (JSONException e) { - LOGGER.error("Error while parsing JSON at " + url, e); - throw e; - } catch (Exception e) { - LOGGER.error("Error while retrieving video URL at " + url, e); - throw new IOException(e); + } + + qualityMap.put(urlArray.get(0), vidUrl); + vidUrl = ""; // Delete content of vidURL + urlArray.clear(); + + // Delete "flashvars" because it's not needed + if (html.startsWith("flashvars")) { + nextSemicolonSpace = html.indexOf(';'); + html = html.substring(nextSemicolonSpace + 1); } } - else { - throw new IOException("Failed to download " + this.url + " : could not find 'flashvars'"); + + // Get URL of highest quality version + int bestQuality = 0; + int currentQuality; + for (Map.Entry entry : qualityMap.entrySet()) { + currentQuality = Integer.parseInt(entry.getKey()); + if (currentQuality > bestQuality) { + bestQuality = currentQuality; + vidUrl = entry.getValue(); + } } + + if (vidUrl.equals("")) { + throw new IOException("Unable to find encrypted video URL at " + this.url); + } + addURLToDownload(new URL(vidUrl), HOST + "_" + bestQuality + "p_" + getGID(this.url)); + waitForThreads(); } }