Fix/remove rippers, remove unstable unit tests.

1. Gonewild ripper - archive website down for good.
2. i.rarchives.com ripper - also down for good.
3. Seenive - down for good.
4. Beeg - Changed their encryption scheme to something fierce.
5. Fixed PornHub ripper -- works for videos and albums.
6. Fixed ShesFreaky ripper.
7. Removed *Chan rippers from unit tests, they keep failing hard.
This commit is contained in:
4pr0n 2015-12-19 17:49:47 -08:00
parent 407a19a483
commit 7aefba9d46
10 changed files with 25 additions and 473 deletions

View File

@ -1,109 +0,0 @@
package com.rarchives.ripme.ripper.rippers;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONObject;
import com.rarchives.ripme.ripper.AbstractJSONRipper;
import com.rarchives.ripme.utils.Http;
import com.rarchives.ripme.utils.Utils;
public class GonewildRipper extends AbstractJSONRipper {
private static final int count = 50;
private int startIndex = 0;
private static String API_DOMAIN;
private String username;
public GonewildRipper(URL url) throws IOException {
super(url);
API_DOMAIN = Utils.getConfigString("gw.api", "gonewild");
}
@Override
public String getHost() {
return "gonewild";
}
@Override
public String getDomain() {
return "gonewild.com";
}
@Override
public boolean canRip(URL url) {
return getUsernameMatcher(url).matches();
}
private Matcher getUsernameMatcher(URL url) {
Pattern p = Pattern.compile("^.*gonewild(\\.com?/|:)(user/)?([a-zA-Z0-9\\-_]{3,})[/?]?.*$");
return p.matcher(url.toExternalForm());
}
@Override
public String getGID(URL url) throws MalformedURLException {
Matcher m = getUsernameMatcher(url);
if (m.matches()) {
this.username = m.group(m.groupCount());
}
else {
throw new MalformedURLException("Expected format: gonewild.com/<user>");
}
return username;
}
@Override
public JSONObject getFirstPage() throws IOException {
String gwURL = "http://" + API_DOMAIN + ".rarchives.com/api.cgi"
+ "?method=get_user"
+ "&user=" + username
+ "&count=" + count
+ "&start=" + startIndex;
JSONObject nextJSON = Http.url(gwURL).getJSON();
if (nextJSON.has("error")) {
throw new IOException(nextJSON.getString("error"));
}
if (nextJSON.getJSONArray("posts").length() == 0) {
throw new IOException("No posts found");
}
return nextJSON;
}
@Override
public JSONObject getNextPage(JSONObject json) throws IOException {
startIndex += count;
sleep(1000);
return getFirstPage();
}
@Override
public List<String> getURLsFromJSON(JSONObject json) {
List<String> imageURLs = new ArrayList<String>();
JSONArray posts = json.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.getJSONObject(i);
JSONArray images = post.getJSONArray("images");
for (int j = 0; j < images.length(); j++) {
JSONObject image = images.getJSONObject(j);
String imagePath = image.getString("path");
if (imagePath.startsWith("..")) {
imagePath = imagePath.substring(2);
}
imagePath = "http://" + API_DOMAIN + ".rarchives.com" + imagePath;
imageURLs.add(imagePath);
}
}
return imageURLs;
}
@Override
public void downloadURL(URL url, int index) {
addURLToDownload(url, getPrefix(index));
}
}

View File

@ -1,92 +0,0 @@
package com.rarchives.ripme.ripper.rippers;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import com.rarchives.ripme.ripper.AbstractJSONRipper;
import com.rarchives.ripme.ripper.rippers.ImgurRipper.ImgurAlbum;
import com.rarchives.ripme.ripper.rippers.ImgurRipper.ImgurImage;
import com.rarchives.ripme.ui.RipStatusMessage.STATUS;
import com.rarchives.ripme.utils.Http;
import com.rarchives.ripme.utils.Utils;
public class IrarchivesRipper extends AbstractJSONRipper {
public IrarchivesRipper(URL url) throws IOException {
super(url);
}
@Override
public String getHost() {
return "irarchives";
}
@Override
public String getDomain() {
return "i.rarchives.com";
}
@Override
public URL sanitizeURL(URL url) throws MalformedURLException {
String u = url.toExternalForm();
String searchTerm = u.substring(u.indexOf("?") + 1);
searchTerm = searchTerm.replace("%3A", "=");
if (searchTerm.startsWith("url=")) {
if (!searchTerm.contains("http")
&& !searchTerm.contains(":")) {
searchTerm = searchTerm.replace("url=", "user=");
}
}
searchTerm = searchTerm.replace("user=user=", "user=");
return new URL("http://i.rarchives.com/search.cgi?" + searchTerm);
}
@Override
public String getGID(URL url) throws MalformedURLException {
String u = url.toExternalForm();
String searchTerm = u.substring(u.indexOf("?") + 1);
return Utils.filesystemSafe(searchTerm);
}
@Override
public JSONObject getFirstPage() throws IOException {
return Http.url(url)
.timeout(60 * 1000)
.getJSON();
}
@Override
public List<String> getURLsFromJSON(JSONObject json) {
List<String> imageURLs = new ArrayList<String>();
JSONArray posts = json.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = (JSONObject) posts.get(i);
String theUrl = post.getString("url");
if (theUrl.contains("imgur.com/a/")) {
ImgurAlbum album = null;
try {
album = ImgurRipper.getImgurAlbum(new URL(theUrl));
} catch (IOException e) {
logger.error("Error loading imgur album " + theUrl, e);
sendUpdate(STATUS.DOWNLOAD_ERRORED, "Can't download " + theUrl + " : " + e.getMessage());
continue;
}
for (ImgurImage image : album.images) {
imageURLs.add(image.url.toExternalForm());
}
}
else {
imageURLs.add(post.getString("imageurl"));
}
}
return imageURLs;
}
@Override
public void downloadURL(URL url, int index) {
addURLToDownload(url, getPrefix(index));
}
}

View File

@ -122,7 +122,7 @@ public class PornhubRipper extends AlbumRipper {
}
public boolean canRip(URL url) {
return url.getHost().endsWith(DOMAIN);
return url.getHost().endsWith(DOMAIN) && url.getPath().startsWith("/album");
}
/**

View File

@ -1,137 +0,0 @@
package com.rarchives.ripme.ripper.rippers;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import com.rarchives.ripme.ripper.AlbumRipper;
import com.rarchives.ripme.ripper.DownloadThreadPool;
import com.rarchives.ripme.ui.RipStatusMessage.STATUS;
import com.rarchives.ripme.utils.Http;
public class SeeniveRipper extends AlbumRipper {
private static final String DOMAIN = "seenive.com",
HOST = "seenive";
private DownloadThreadPool seeniveThreadPool;
public SeeniveRipper(URL url) throws IOException {
super(url);
seeniveThreadPool = new DownloadThreadPool();
}
@Override
public boolean canRip(URL url) {
return url.getHost().endsWith(DOMAIN);
}
@Override
public URL sanitizeURL(URL url) throws MalformedURLException {
return url;
}
@Override
public void rip() throws IOException {
String baseURL = this.url.toExternalForm();
logger.info(" Retrieving " + baseURL);
Document doc = Http.url(baseURL)
.referrer(baseURL)
.get();
while (true) {
if (isStopped()) {
break;
}
String lastID = null;
for (Element element : doc.select("a.facebox")) {
String card = element.attr("href"); // "/v/<video_id>"
URL videoURL = new URL("http://seenive.com" + card);
SeeniveImageThread vit = new SeeniveImageThread(videoURL);
seeniveThreadPool.addThread(vit);
lastID = card.substring(card.lastIndexOf('/') + 1);
if (isStopped() || isThisATest()) {
break;
}
}
if (lastID == null || isStopped() || isThisATest()) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
logger.error("[!] Interrupted while waiting to load next page", e);
break;
}
logger.info("[ ] Retrieving " + baseURL + "/next/" + lastID);
JSONObject json = Http.url(baseURL + "/next/" + lastID)
.referrer(baseURL)
.getJSON();
String html = json.getString("Html");
if (html.equals("")) {
break;
}
doc = Jsoup.parse(html);
}
seeniveThreadPool.waitForThreads();
waitForThreads();
}
@Override
public String getHost() {
return HOST;
}
@Override
public String getGID(URL url) throws MalformedURLException {
Pattern p = Pattern.compile("^https?://(www\\.)?seenive\\.com/u/([a-zA-Z0-9]{1,}).*$");
Matcher m = p.matcher(url.toExternalForm());
if (!m.matches()) {
throw new MalformedURLException("Expected format: http://seenive.com/u/USERID");
}
return m.group(m.groupCount());
}
/**
* Helper class to find and download images found on "image" pages
*/
private class SeeniveImageThread extends Thread {
private URL url;
public SeeniveImageThread(URL url) {
super();
this.url = url;
}
@Override
public void run() {
try {
Document doc = Http.url(this.url).get();
logger.info("[ ] Retrieving video page " + this.url);
sendUpdate(STATUS.LOADING_RESOURCE, this.url.toExternalForm());
for (Element element : doc.select("source")) {
String video = element.attr("src");
if (video.contains("redirect?url=")) {
video = video.substring("redirect?url=".length() + 1);
video = URLDecoder.decode(video, "UTF-8");
}
synchronized (threadPool) {
addURLToDownload(new URL(video));
}
break;
}
} catch (IOException e) {
logger.error("[!] Exception while loading/parsing " + this.url, e);
}
}
}
}

View File

@ -49,7 +49,7 @@ public class ShesFreakyRipper extends AbstractHTMLRipper {
@Override
public List<String> getURLsFromPage(Document doc) {
List<String> imageURLs = new ArrayList<String>();
for (Element thumb : doc.select("a.highslide")) {
for (Element thumb : doc.select("a[data-lightbox=\"gallery\"]")) {
String image = thumb.attr("href");
imageURLs.add(image);
}

View File

@ -1,84 +0,0 @@
package com.rarchives.ripme.ripper.rippers.video;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.nodes.Document;
import com.rarchives.ripme.ripper.VideoRipper;
import com.rarchives.ripme.utils.Http;
public class BeegRipper extends VideoRipper {
private static final String HOST = "beeg";
public BeegRipper(URL url) throws IOException {
super(url);
}
@Override
public String getHost() {
return HOST;
}
@Override
public boolean canRip(URL url) {
Pattern p = Pattern.compile("^https?://[wm.]*beeg\\.com/[0-9]+.*$");
Matcher m = p.matcher(url.toExternalForm());
return m.matches();
}
@Override
public URL sanitizeURL(URL url) throws MalformedURLException {
return url;
}
@Override
public String getGID(URL url) throws MalformedURLException {
Pattern p = Pattern.compile("^https?://[wm.]*beeg\\.com/([0-9]+).*$");
Matcher m = p.matcher(url.toExternalForm());
if (m.matches()) {
return m.group(1);
}
throw new MalformedURLException(
"Expected beeg format:"
+ "beeg.com/####"
+ " Got: " + url);
}
@Override
public void rip() throws IOException {
logger.info(" Retrieving " + this.url);
Document doc = Http.url(this.url).get();
Pattern p = Pattern.compile("^.*var qualityArr = (.*});.*$", Pattern.DOTALL);
Matcher m = p.matcher(doc.html());
if (m.matches()) {
try {
JSONObject json = new JSONObject(m.group(1));
String vidUrl = null;
for (String quality : new String[] {"1080p", "720p", "480p", "240p"}) {
if (json.has(quality)) {
vidUrl = json.getString(quality);
break;
}
}
if (vidUrl == null) {
throw new IOException("Unable to find video URL at " + this.url);
}
addURLToDownload(new URL(vidUrl), HOST + "_" + getGID(this.url));
waitForThreads();
return;
} catch (JSONException e) {
logger.error("Error while parsing JSON at " + url, e);
throw e;
}
}
throw new IOException("Failed to rip video at " + this.url);
}
}

View File

@ -3,7 +3,6 @@ package com.rarchives.ripme.ripper.rippers.video;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -12,7 +11,6 @@ import org.json.JSONObject;
import org.jsoup.nodes.Document;
import com.rarchives.ripme.ripper.VideoRipper;
import com.rarchives.ripme.utils.AES;
import com.rarchives.ripme.utils.Http;
public class PornhubRipper extends VideoRipper {
@ -58,29 +56,29 @@ public class PornhubRipper extends VideoRipper {
public void rip() throws IOException {
logger.info(" Retrieving " + this.url.toExternalForm());
Document doc = Http.url(this.url).get();
Pattern p = Pattern.compile("^.*'flashvars' : (.*});.*$", Pattern.DOTALL);
Matcher m = p.matcher(doc.body().html());
String html = doc.body().html();
Pattern p = Pattern.compile("^.*flashvars_[0-9]+ = (.+});.*$", Pattern.DOTALL);
Matcher m = p.matcher(html);
if (m.matches()) {
String title = null,
encryptedUrl = null;
String title = null, vidUrl = null;
try {
JSONObject json = new JSONObject(m.group(1));
title = json.getString("video_title");
title = title.replaceAll("\\+", " ");
encryptedUrl = null;
vidUrl = null;
for (String quality : new String[] {"quality_1080p", "quality_720p", "quality_480p", "quality_240p"}) {
if (json.has(quality)) {
encryptedUrl = json.getString(quality);
Pattern pv = Pattern.compile("^.*var player_" + quality + " = '([^']*)'.*$", Pattern.DOTALL);
Matcher mv = pv.matcher(html);
if (mv.matches()) {
vidUrl = mv.group(1);
break;
}
}
if (encryptedUrl == null) {
if (vidUrl == null) {
throw new IOException("Unable to find encrypted video URL at " + this.url);
}
encryptedUrl = URLDecoder.decode(encryptedUrl, "UTF-8");
String vidUrl = AES.decrypt(encryptedUrl, title, 256);
addURLToDownload(new URL(vidUrl), HOST + "_" + getGID(this.url));
} catch (JSONException e) {
logger.error("Error while parsing JSON at " + url, e);

View File

@ -8,20 +8,15 @@ import com.rarchives.ripme.ripper.rippers.DeviantartRipper;
import com.rarchives.ripme.ripper.rippers.EightmusesRipper;
import com.rarchives.ripme.ripper.rippers.FineboxRipper;
import com.rarchives.ripme.ripper.rippers.FivehundredpxRipper;
import com.rarchives.ripme.ripper.rippers.FlickrRipper;
import com.rarchives.ripme.ripper.rippers.FuraffinityRipper;
import com.rarchives.ripme.ripper.rippers.FuskatorRipper;
import com.rarchives.ripme.ripper.rippers.GifyoRipper;
import com.rarchives.ripme.ripper.rippers.GirlsOfDesireRipper;
import com.rarchives.ripme.ripper.rippers.GonewildRipper;
import com.rarchives.ripme.ripper.rippers.HentaifoundryRipper;
import com.rarchives.ripme.ripper.rippers.ImagearnRipper;
import com.rarchives.ripme.ripper.rippers.ImagebamRipper;
import com.rarchives.ripme.ripper.rippers.ImagestashRipper;
import com.rarchives.ripme.ripper.rippers.ImagevenueRipper;
import com.rarchives.ripme.ripper.rippers.ImgboxRipper;
import com.rarchives.ripme.ripper.rippers.IrarchivesRipper;
import com.rarchives.ripme.ripper.rippers.MinusRipper;
import com.rarchives.ripme.ripper.rippers.ModelmayhemRipper;
import com.rarchives.ripme.ripper.rippers.MotherlessRipper;
import com.rarchives.ripme.ripper.rippers.NfsfwRipper;
@ -29,7 +24,6 @@ import com.rarchives.ripme.ripper.rippers.PhotobucketRipper;
import com.rarchives.ripme.ripper.rippers.PornhubRipper;
import com.rarchives.ripme.ripper.rippers.RedditRipper;
import com.rarchives.ripme.ripper.rippers.SankakuComplexRipper;
import com.rarchives.ripme.ripper.rippers.SeeniveRipper;
import com.rarchives.ripme.ripper.rippers.ShesFreakyRipper;
import com.rarchives.ripme.ripper.rippers.TapasticRipper;
import com.rarchives.ripme.ripper.rippers.TeenplanetRipper;
@ -86,11 +80,6 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
public void testSeeniveAlbum() throws IOException {
SeeniveRipper ripper = new SeeniveRipper(new URL("http://seenive.com/u/946491170220040192"));
testRipper(ripper);
}
public void testTumblrFullRip() throws IOException {
TumblrRipper ripper = new TumblrRipper(new URL("http://wrouinr.tumblr.com/archive"));
testRipper(ripper);
@ -100,7 +89,7 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
public void testTumblrPostRip() throws IOException {
TumblrRipper ripper = new TumblrRipper(new URL("http://genekellyclarkson.tumblr.com/post/86100752527/lucyannebrooks-rachaelboden-friends-goodtimes-bed-boobs"));
TumblrRipper ripper = new TumblrRipper(new URL("http://sadbaffoon.tumblr.com/post/132045920789/what-a-hoe"));
testRipper(ripper);
}
@ -109,7 +98,7 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
public void testTwitterSearchRip() throws IOException {
TwitterRipper ripper = new TwitterRipper(new URL("https://twitter.com/search?q=from%3Apurrbunny%20filter%3Aimages&src=typd"));
TwitterRipper ripper = new TwitterRipper(new URL("https://twitter.com/search?q=from%3ADaisyfairymfc%20filter%3Aimages&src=typd"));
testRipper(ripper);
}
@ -118,10 +107,12 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
/*
public void testFlickrAlbum() throws IOException {
FlickrRipper ripper = new FlickrRipper(new URL("https://www.flickr.com/photos/leavingallbehind/sets/72157621895942720/"));
testRipper(ripper);
}
*/
public void testFuraffinityAlbum() throws IOException {
FuraffinityRipper ripper = new FuraffinityRipper(new URL("https://www.furaffinity.net/gallery/mustardgas/"));
@ -143,11 +134,6 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
public void testGonewildAlbums() throws IOException {
GonewildRipper ripper = new GonewildRipper(new URL("http://gonewild.com/user/amle69"));
testRipper(ripper);
}
public void testHentaifoundryRip() throws IOException {
HentaifoundryRipper ripper = new HentaifoundryRipper(new URL("http://www.hentai-foundry.com/pictures/user/personalami"));
testRipper(ripper);
@ -163,10 +149,12 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
/*
public void testImagestashRip() throws IOException {
AbstractRipper ripper = new ImagestashRipper(new URL("https://imagestash.org/tag/everydayuncensor"));
testRipper(ripper);
}
*/
public void testImagevenueRip() throws IOException {
AbstractRipper ripper = new ImagevenueRipper(new URL("http://img120.imagevenue.com/galshow.php?gal=gallery_1373818527696_191lo"));
@ -178,11 +166,7 @@ public class BasicRippersTest extends RippersTest {
testRipper(ripper);
}
public void testIrarchivesRip() throws IOException {
AbstractRipper ripper = new IrarchivesRipper(new URL("http://i.rarchives.com/?url=user%3Agingerpuss"));
testRipper(ripper);
}
/*
public void testMinusUserRip() throws IOException {
AbstractRipper ripper = new MinusRipper(new URL("http://vampyr3.minus.com/"));
testRipper(ripper);
@ -201,6 +185,7 @@ public class BasicRippersTest extends RippersTest {
AbstractRipper ripper = new MinusRipper(new URL("http://minus.com/mw7ztQ6xzP7ae"));
testRipper(ripper);
}
*/
public void testModelmayhemRip() throws IOException {
AbstractRipper ripper = new ModelmayhemRipper(new URL("http://www.modelmayhem.com/portfolio/520206/viewall"));
@ -230,7 +215,7 @@ public class BasicRippersTest extends RippersTest {
}
public void testSankakuChanRip() throws IOException {
AbstractRipper ripper = new SankakuComplexRipper(new URL("https://chan.sankakucomplex.com/?tags=1girl"));
AbstractRipper ripper = new SankakuComplexRipper(new URL("https://chan.sankakucomplex.com/?tags=cleavage"));
testRipper(ripper);
}
public void testSankakuIdolRip() throws IOException {

View File

@ -48,10 +48,10 @@ public class ChanRipperTest extends RippersTest {
public void testChanRipper() throws IOException {
List<URL> contentURLs = new ArrayList<URL>();
// URLs that should return more than 1 image
contentURLs.add(new URL("http://desuchan.net/v/res/7034.html"));
contentURLs.add(new URL("http://boards.420chan.org/ana/res/75984.php"));
contentURLs.add(new URL("http://archive.4plebs.org/s4s/thread/3005257/"));
contentURLs.add(new URL("http://drawchan.net/dc/dw/res/114910.html"));
//contentURLs.add(new URL("http://desuchan.net/v/res/7034.html"));
//contentURLs.add(new URL("http://boards.420chan.org/ana/res/75984.php"));
//contentURLs.add(new URL("http://archive.4plebs.org/s4s/thread/3005257/"));
//contentURLs.add(new URL("http://drawchan.net/dc/dw/res/114910.html"));
// Most *chans have volatile threads & can't be trusted for integration testing.

View File

@ -6,7 +6,6 @@ import java.util.ArrayList;
import java.util.List;
import com.rarchives.ripme.ripper.VideoRipper;
import com.rarchives.ripme.ripper.rippers.video.BeegRipper;
import com.rarchives.ripme.ripper.rippers.video.PornhubRipper;
import com.rarchives.ripme.ripper.rippers.video.VineRipper;
import com.rarchives.ripme.ripper.rippers.video.XvideosRipper;
@ -73,12 +72,4 @@ public class VideoRippersTest extends RippersTest {
}
}
public void testBeegRipper() throws IOException {
List<URL> contentURLs = new ArrayList<URL>();
contentURLs.add(new URL("http://beeg.com/4554321"));
for (URL url : contentURLs) {
BeegRipper ripper = new BeegRipper(url);
videoTestHelper(ripper);
}
}
}