diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/TumblrRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/TumblrRipper.java index 53225927..ac99200f 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/TumblrRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/TumblrRipper.java @@ -25,6 +25,8 @@ import org.jsoup.nodes.Element; public class TumblrRipper extends AlbumRipper { + int index = 1; + private static final String DOMAIN = "tumblr.com", HOST = "tumblr", IMAGE_PATTERN = "([^\\s]+(\\.(?i)(jpg|png|gif|bmp))$)"; @@ -32,7 +34,8 @@ public class TumblrRipper extends AlbumRipper { private enum ALBUM_TYPE { SUBDOMAIN, TAG, - POST + POST, + LIKED } private ALBUM_TYPE albumType; private String subdomain, tagName, postNumber; @@ -235,7 +238,11 @@ public class TumblrRipper extends AlbumRipper { URL fileURL; - posts = json.getJSONObject("response").getJSONArray("posts"); + if (albumType == ALBUM_TYPE.LIKED) { + posts = json.getJSONObject("response").getJSONArray("liked_posts"); + } else { + posts = json.getJSONObject("response").getJSONArray("posts"); + } if (posts.length() == 0) { LOGGER.info(" Zero posts returned."); return false; @@ -252,10 +259,10 @@ public class TumblrRipper extends AlbumRipper { m = p.matcher(fileURL.toString()); if (m.matches()) { - addURLToDownload(fileURL); + downloadURL(fileURL); } else { URL redirectedURL = Http.url(fileURL).ignoreContentType().response().url(); - addURLToDownload(redirectedURL); + downloadURL(redirectedURL); } } catch (Exception e) { LOGGER.error("[!] Error while parsing photo in " + photo, e); @@ -264,7 +271,7 @@ public class TumblrRipper extends AlbumRipper { } else if (post.has("video_url")) { try { fileURL = new URL(post.getString("video_url").replaceAll("http:", "https:")); - addURLToDownload(fileURL); + downloadURL(fileURL); } catch (Exception e) { LOGGER.error("[!] Error while parsing video in " + post, e); return true; @@ -273,7 +280,7 @@ public class TumblrRipper extends AlbumRipper { Document d = Jsoup.parse(post.getString("body")); if (!d.select("img").attr("src").isEmpty()) { try { - addURLToDownload(new URL(d.select("img").attr("src"))); + downloadURL(new URL(d.select("img").attr("src"))); } catch (MalformedURLException e) { LOGGER.error("[!] Error while getting embedded image at " + post, e); return true; @@ -289,6 +296,16 @@ public class TumblrRipper extends AlbumRipper { private String getTumblrApiURL(String mediaType, int offset) { StringBuilder sb = new StringBuilder(); + if (albumType == ALBUM_TYPE.LIKED) { + sb.append("http://api.tumblr.com/v2/blog/") + .append(subdomain) + .append("/likes") + .append("?api_key=") + .append(getApiKey()) + .append("&offset=") + .append(offset); + return sb.toString(); + } if (albumType == ALBUM_TYPE.POST) { sb.append("http://api.tumblr.com/v2/blog/") .append(subdomain) @@ -310,6 +327,7 @@ public class TumblrRipper extends AlbumRipper { sb.append("&tag=") .append(tagName); } + return sb.toString(); } @@ -352,7 +370,38 @@ public class TumblrRipper extends AlbumRipper { this.subdomain = m.group(1); return this.subdomain; } + // Likes url + p = Pattern.compile("https?://([a-z0-9_-]+).tumblr.com/likes"); + m = p.matcher(url.toExternalForm()); + if (m.matches()) { + this.albumType = ALBUM_TYPE.LIKED; + this.subdomain = m.group(1); + return this.subdomain + "_liked"; + } + + // Likes url different format + p = Pattern.compile("https://www.tumblr.com/liked/by/([a-z0-9_-]+)"); + m = p.matcher(url.toExternalForm()); + if (m.matches()) { + this.albumType = ALBUM_TYPE.LIKED; + this.subdomain = m.group(1); + return this.subdomain + "_liked"; + } + throw new MalformedURLException("Expected format: http://subdomain[.tumblr.com][/tagged/tag|/post/postno]"); } + private String getPrefix(int i) { + String prefix = ""; + if (Utils.getConfigBoolean("download.save_order", true)) { + prefix = String.format("%03d_", i); + } + return prefix; + } + + public void downloadURL(URL url) { + addURLToDownload(url, getPrefix(index)); + index++; + } + }