1
0
mirror of https://github.com/RipMeApp/ripme.git synced 2025-08-11 16:34:04 +02:00

Support coomer.party

This commit is contained in:
jpoulton
2023-10-29 07:20:20 +00:00
committed by soloturn
parent 194e5fdfb8
commit 391b369692
2 changed files with 190 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
package com.rarchives.ripme.ripper.rippers;
import com.rarchives.ripme.ripper.AbstractJSONRipper;
import com.rarchives.ripme.utils.Http;
import com.rarchives.ripme.utils.Utils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* <a href="https://coomer.su/api/schema">See this link for the API schema</a>.
*/
public class CoomerPartyRipper extends AbstractJSONRipper {
private static final Logger LOGGER = Logger.getLogger(CoomerPartyRipper.class);
private static final String IMG_URL_BASE = "https://c3.coomer.su/data";
private static final String VID_URL_BASE = "https://c1.coomer.su/data";
private static final Pattern IMG_PATTERN = Pattern.compile("^.*\\.(jpg|jpeg|png|gif|apng|webp|tif|tiff)$", Pattern.CASE_INSENSITIVE);
private static final Pattern VID_PATTERN = Pattern.compile("^.*\\.(webm|mp4|m4v)$", Pattern.CASE_INSENSITIVE);
// just so we can return a JSONObject from getFirstPage
private static final String KEY_WRAPPER_JSON_ARRAY = "array";
private static final String KEY_FILE = "file";
private static final String KEY_PATH = "path";
private static final String KEY_ATTACHMENTS = "attachments";
private final String service;
private final String user;
public CoomerPartyRipper(URL url) throws IOException {
super(url);
List<String> pathElements = Arrays.stream(url.getPath().split("/"))
.filter(element -> !element.isBlank())
.collect(Collectors.toList());
service = pathElements.get(0);
user = pathElements.get(2);
if (service == null || user == null || service.isBlank() || user.isBlank()) {
LOGGER.warn("service=" + service + ", user=" + user);
throw new MalformedURLException("Invalid coomer.party URL: " + url);
}
LOGGER.debug("Parsed service=" + service + " and user=" + user + " from " + url);
}
@Override
protected String getDomain() {
return "coomer.party";
}
@Override
public String getHost() {
return "coomer.party";
}
@Override
public boolean canRip(URL url) {
String host = url.getHost();
return host.endsWith("coomer.party") || host.endsWith("coomer.su");
}
@Override
public String getGID(URL url) {
return Utils.filesystemSafe(String.format("%s_%s", service, user));
}
@Override
protected JSONObject getFirstPage() throws IOException {
String apiUrl = String.format("https://coomer.su/api/v1/%s/user/%s", service, user);
String jsonArrayString = Http.url(apiUrl)
.ignoreContentType()
.response()
.body();
JSONArray jsonArray = new JSONArray(jsonArrayString);
// Ideally we'd just return the JSONArray from here, but we have to wrap it in a JSONObject
JSONObject wrapperObject = new JSONObject();
wrapperObject.put(KEY_WRAPPER_JSON_ARRAY, jsonArray);
return wrapperObject;
}
@Override
protected List<String> getURLsFromJSON(JSONObject json) {
// extract the array from our wrapper JSONObject
JSONArray posts = json.getJSONArray(KEY_WRAPPER_JSON_ARRAY);
ArrayList<String> urls = new ArrayList<>();
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.getJSONObject(i);
pullFileUrl(post, urls);
pullAttachmentUrls(post, urls);
}
LOGGER.debug("Pulled " + urls.size() + " URLs from " + posts.length() + " posts");
return urls;
}
@Override
protected void downloadURL(URL url, int index) {
addURLToDownload(url, getPrefix(index));
}
private void pullFileUrl(JSONObject post, ArrayList<String> results) {
try {
JSONObject file = post.getJSONObject(KEY_FILE);
String path = file.getString(KEY_PATH);
if (isImage(path)) {
String url = IMG_URL_BASE + path;
results.add(url);
} else if (isVideo(path)) {
String url = VID_URL_BASE + path;
results.add(url);
} else {
LOGGER.error("Unknown extension for coomer.su path: " + path);
}
} catch (JSONException e) {
/* No-op */
}
}
private void pullAttachmentUrls(JSONObject post, ArrayList<String> results) {
try {
JSONArray attachments = post.getJSONArray(KEY_ATTACHMENTS);
for (int i = 0; i < attachments.length(); i++) {
JSONObject attachment = attachments.getJSONObject(0);
pullFileUrl(attachment, results);
}
} catch (JSONException e) {
/* No-op */
}
}
private boolean isImage(String path) {
Matcher matcher = IMG_PATTERN.matcher(path);
return matcher.matches();
}
private boolean isVideo(String path) {
Matcher matcher = VID_PATTERN.matcher(path);
return matcher.matches();
}
}

View File

@@ -0,0 +1,38 @@
package com.rarchives.ripme.tst.ripper.rippers;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.rarchives.ripme.ripper.rippers.CoomerPartyRipper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URL;
public class CoomerPartyRipperTest extends RippersTest {
@Test
public void testRip() throws IOException {
URL url = new URL("https://coomer.su/onlyfans/user/soogsx");
CoomerPartyRipper ripper = new CoomerPartyRipper(url);
testRipper(ripper);
}
@Test
public void testUrlParsing() throws IOException {
String expectedGid = "onlyfans_soogsx";
String[] urls = new String[]{
"https://coomer.su/onlyfans/user/soogsx", // normal url
"http://coomer.su/onlyfans/user/soogsx", // http, not https
"https://coomer.su/onlyfans/user/soogsx/", // with slash at the end
"https://coomer.su/onlyfans/user/soogsx?whatever=abc", // with url params
"https://coomer.party/onlyfans/user/soogsx", // alternate domain
};
for (String stringUrl : urls) {
URL url = new URL(stringUrl);
CoomerPartyRipper ripper = new CoomerPartyRipper(url);
assertTrue(ripper.canRip(url));
assertEquals(expectedGid, ripper.getGID(url));
}
}
}