diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/CfakeRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/CfakeRipper.java index 4372883e..f1d8c8a2 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/CfakeRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/CfakeRipper.java @@ -10,80 +10,89 @@ import java.util.regex.Pattern; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; import com.rarchives.ripme.ripper.AbstractHTMLRipper; import com.rarchives.ripme.utils.Http; public class CfakeRipper extends AbstractHTMLRipper { - public CfakeRipper(URL url) throws IOException { - super(url); + super(url); } - @Override - public String getHost() { - return "cfake"; + @Override + public String getHost() { + return "cfake"; + } + + @Override + public String getDomain() { + return "cfake.com"; + } + + @Override + public String getGID(URL url) throws MalformedURLException { + Pattern p = Pattern.compile("https?://cfake\\.com/images/celebrity/([a-zA-Z1-9_-]*)/\\d+/?$"); + Matcher m = p.matcher(url.toExternalForm()); + if (m.matches()) { + return m.group(1); + } + throw new MalformedURLException("Expected cfake URL format: " + + "cfake.com/images/celebrity/MODEL/ID - got " + url + " instead"); + } + + @Override + public Document getFirstPage() throws IOException { + // "url" is an instance field of the superclass + return Http.url(url).get(); + } + + @Override + public Document getNextPage(Document doc) throws IOException { + Element elem = doc.select("div#wrapper_path div#content_path div#num_page").last(); + if (elem == null) { + throw new IOException("No more pages (cannot find nav)"); } - @Override - public String getDomain() { - return "cfake.com"; + Element nextAnchor = elem.select("a").first(); + if (nextAnchor == null) { + throw new IOException("No more pages (cannot find anchor)"); } - @Override - public String getGID(URL url) throws MalformedURLException { - Pattern p = Pattern.compile("https?://cfake\\.com/picture/([a-zA-Z1-9_-]*)/\\d+/?$"); - Matcher m = p.matcher(url.toExternalForm()); - if (m.matches()) { - return m.group(1); - } - throw new MalformedURLException("Expected cfake URL format: " + - "cfake.com/picture/MODEL/ID - got " + url + " instead"); + Elements nextSpans = nextAnchor.select("span"); + if (nextSpans.isEmpty()) { + // This is the expected case that we're done iterating. + throw new IOException("No more pages (last page)"); } - @Override - public Document getFirstPage() throws IOException { - // "url" is an instance field of the superclass - return Http.url(url).get(); - } + // Use the nextAnchor (parent of the span) for the URL + String nextPage = nextAnchor.attr("href"); - @Override - public Document getNextPage(Document doc) throws IOException { - // We use comic-nav-next to the find the next page - Element elem = doc.select("td > div.next > a").first(); - if (elem == null) { - throw new IOException("No more pages"); - } - String nextPage = elem.attr("href"); - // Some times this returns a empty string - // This for stops that - if (nextPage.equals("")) { - return null; - } - else { - return Http.url("http://cfake.com" + nextPage).get(); - } - } - - @Override - public List getURLsFromPage(Document doc) { - List result = new ArrayList<>(); - for (Element el : doc.select("table.display > tbody > tr > td > table > tbody > tr > td > a")) { - if (el.attr("href").contains("upload")) { - return result; - } else { - String imageSource = el.select("img").attr("src"); - // We remove the .md from images so we download the full size image - // not the thumbnail ones - imageSource = imageSource.replace("thumbs", "photos"); - result.add("http://cfake.com" + imageSource); - } - } - return result; - } - - @Override - public void downloadURL(URL url, int index) { - addURLToDownload(url, getPrefix(index)); + // Sometimes this returns an empty string; this stops that + if (nextPage.equals("")) { + return null; + } else { + return Http.url("https://cfake.com" + nextPage).get(); } } + + @Override + public List getURLsFromPage(Document doc) { + List result = new ArrayList<>(); + for (Element el : doc.select("div#media_content .responsive .gallery > a img")) { + // Convert found src value e.g. /medias/thumbs/2025/17358722979850276d_cfake.jpg + // to photo src value e.g. + // https://cfake.com/medias/photos/2025/17358722979850276d_cfake.jpg + String imageSource = el.attr("src"); + imageSource = imageSource.replace("thumbs", "photos"); + result.add("https://cfake.com" + imageSource); + } + + return result; + } + + @Override + public void downloadURL(URL url, int index) { + addURLToDownload(url, getPrefix(index)); + } +} diff --git a/src/test/java/com/rarchives/ripme/tst/ripper/rippers/CfakeRipperTest.java b/src/test/java/com/rarchives/ripme/tst/ripper/rippers/CfakeRipperTest.java index 95f7ec2e..b36401b4 100644 --- a/src/test/java/com/rarchives/ripme/tst/ripper/rippers/CfakeRipperTest.java +++ b/src/test/java/com/rarchives/ripme/tst/ripper/rippers/CfakeRipperTest.java @@ -4,11 +4,15 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import org.junit.jupiter.api.Test; + import com.rarchives.ripme.ripper.rippers.CfakeRipper; public class CfakeRipperTest extends RippersTest { + @Test public void testRip() throws IOException, URISyntaxException { - CfakeRipper ripper = new CfakeRipper(new URI("http://cfake.com/picture/Zooey_Deschanel/1264").toURL()); + CfakeRipper ripper = new CfakeRipper( + new URI("https://cfake.com/images/celebrity/Zooey_Deschanel/1264").toURL()); testRipper(ripper); } }