2525import java .util .Map ;
2626import java .util .Set ;
2727
28+ import org .appwork .net .protocol .http .HTTPConstants ;
29+ import org .appwork .storage .TypeRef ;
30+ import org .appwork .utils .DebugMode ;
31+ import org .appwork .utils .Files ;
32+ import org .appwork .utils .Regex ;
33+ import org .appwork .utils .StringUtils ;
34+ import org .appwork .utils .parser .UrlQuery ;
35+ import org .jdownloader .controlling .filter .CompiledFiletypeFilter ;
36+ import org .jdownloader .plugins .components .config .KemonoPartyConfig ;
37+ import org .jdownloader .plugins .components .config .KemonoPartyConfig .TextCrawlMode ;
38+ import org .jdownloader .plugins .components .config .KemonoPartyConfigCoomerParty ;
39+ import org .jdownloader .plugins .config .PluginJsonConfig ;
40+ import org .jdownloader .plugins .controller .LazyPlugin ;
41+
2842import jd .PluginWrapper ;
2943import jd .controlling .ProgressController ;
3044import jd .controlling .linkcrawler .CrawledLink ;
4357import jd .plugins .PluginForDecrypt ;
4458import jd .plugins .hoster .KemonoParty ;
4559
46- import org .appwork .net .protocol .http .HTTPConstants ;
47- import org .appwork .storage .TypeRef ;
48- import org .appwork .utils .DebugMode ;
49- import org .appwork .utils .Files ;
50- import org .appwork .utils .Regex ;
51- import org .appwork .utils .StringUtils ;
52- import org .appwork .utils .parser .UrlQuery ;
53- import org .jdownloader .controlling .filter .CompiledFiletypeFilter ;
54- import org .jdownloader .plugins .components .config .KemonoPartyConfig ;
55- import org .jdownloader .plugins .components .config .KemonoPartyConfig .TextCrawlMode ;
56- import org .jdownloader .plugins .components .config .KemonoPartyConfigCoomerParty ;
57- import org .jdownloader .plugins .config .PluginJsonConfig ;
58- import org .jdownloader .plugins .controller .LazyPlugin ;
59-
60- @ DecrypterPlugin (revision = "$Revision: 51471 $" , interfaceVersion = 3 , names = {}, urls = {})
60+ @ DecrypterPlugin (revision = "$Revision: 51615 $" , interfaceVersion = 3 , names = {}, urls = {})
6161public class KemonoPartyCrawler extends PluginForDecrypt {
6262 public KemonoPartyCrawler (PluginWrapper wrapper ) {
6363 super (wrapper );
@@ -107,12 +107,12 @@ public static String[] getAnnotationUrls() {
107107 public static String [] buildAnnotationUrls (final List <String []> pluginDomains ) {
108108 final List <String > ret = new ArrayList <String >();
109109 for (final String [] domains : pluginDomains ) {
110- ret .add ("https?://(?:www\\ .)?" + buildHostsPatternPart (domains ) + "/[^/]+/user/([\\ w\\ -\\ .]+(\\ ?o=( \\ d+) )?)(/post/[a-z0-9]+)?" );
110+ ret .add ("https?://(?:www\\ .)?" + buildHostsPatternPart (domains ) + "/[^/]+/user/([\\ w\\ -\\ .]+(\\ ?.+ )?)(/post/[a-z0-9]+)?" );
111111 }
112112 return ret .toArray (new String [0 ]);
113113 }
114114
115- private final String TYPE_PROFILE = "(?i)(?:https?://[^/]+)?/([^/]+)/user/([\\ w\\ -\\ .]+)(\\ ?o=( \\ d+) )?$" ;
115+ private final String TYPE_PROFILE = "(?i)(?:https?://[^/]+)?/([^/]+)/user/([\\ w\\ -\\ .]+)(\\ ?.+ )?$" ;
116116 private final String TYPE_POST = "(?i)(?:https?://[^/]+)?/([^/]+)/user/([\\ w\\ -\\ .]+)/post/([a-z0-9]+)$" ;
117117 private KemonoParty hostPlugin = null ;
118118 private CryptedLink cl = null ;
@@ -150,19 +150,15 @@ private ArrayList<DownloadLink> crawlProfile(final CryptedLink param) throws Exc
150150 }
151151 final String service = urlinfo .getMatch (0 );
152152 final String userID = urlinfo .getMatch (1 );
153- final String startOffsetStr = urlinfo .getMatch (3 );
154- Integer startOffset = null ;
155- if (startOffsetStr != null ) {
156- startOffset = Integer .parseInt (startOffsetStr );
157- }
158- return crawlProfileAPI (service , userID , startOffset );
153+ final UrlQuery query = UrlQuery .parse (urlinfo .getMatch (2 ));
154+ return crawlProfileAPI (service , userID , query );
159155 }
160156
161157 /**
162158 * @param startOffset
163159 * : If provided, only this offset/page will be crawled.
164160 */
165- private ArrayList <DownloadLink > crawlProfileAPI (final String service , final String usernameOrUserID , final Integer startOffset ) throws Exception {
161+ private ArrayList <DownloadLink > crawlProfileAPI (final String service , final String usernameOrUserID , final UrlQuery query ) throws Exception {
166162 if (service == null || usernameOrUserID == null ) {
167163 /* Developer mistake */
168164 throw new PluginException (LinkStatus .ERROR_PLUGIN_DEFECT );
@@ -173,25 +169,42 @@ private ArrayList<DownloadLink> crawlProfileAPI(final String service, final Stri
173169 final ArrayList <DownloadLink > ret = new ArrayList <DownloadLink >();
174170 final FilePackage profileFilePackage = getFilePackageForProfileCrawler (service , usernameOrUserID );
175171 int offset = 0 ;
176- if (startOffset != null ) {
177- logger .info ("Starting from offset: " + startOffset );
178- offset = startOffset .intValue ();
172+ String offsetString = null ;
173+ String qString = null ;
174+ if (query != null ) {
175+ qString = query .get ("q" );
176+ offsetString = query .getDecoded ("o" );
177+ if (offsetString != null && offsetString .matches ("^\\ d+$" )) {
178+ logger .info ("Starting from offset: " + offsetString );
179+ offset = Integer .parseInt (offsetString );
180+ }
181+ }
182+ if (qString == null ) {
183+ qString = "" ;
184+ } else {
185+ qString = "&q=" + qString ;
179186 }
180187 int page = 1 ;
181188 final int maxItemsPerPage = 50 ;
182189 int numberofContinuousPagesWithoutAnyNewItems = 0 ;
183190 final int maxPagesWithoutNewItems = 15 ;
184191 final Set <String > retryWithSinglePostAPI = new HashSet <String >();
185- do {
186- getPage (br , this .getApiBase () + "/" + service + "/user/" + Encoding .urlEncode (usernameOrUserID ) + "/posts?o=" + offset );
192+ pagination : do {
193+ getPage (br , this .getApiBase () + "/" + service + "/user/" + Encoding .urlEncode (usernameOrUserID ) + "/posts?o=" + offset + qString );
187194 final List <Map <String , Object >> posts = (List <Map <String , Object >>) restoreFromString (br .getRequest ().getHtmlCode (), TypeRef .OBJECT );
188195 if (posts == null || posts .isEmpty ()) {
189196 if (ret .isEmpty () && retryWithSinglePostAPI .isEmpty ()) {
197+ if (!StringUtils .isEmpty (qString )) {
198+ // TODO: Use exception down below once RetryReason.EMPTY_SEARCH_QUERY is live.
199+ // throw new DecrypterRetryException(RetryReason.EMPTY_SEARCH_QUERY);
200+ logger .info ("Stopping because: Search query revealed zero results" );
201+ break pagination ;
202+ }
190203 throw new PluginException (LinkStatus .ERROR_FILE_NOT_FOUND );
191204 } else {
192205 /* This should never happen */
193206 logger .info ("Stopping because: Got empty page" );
194- break ;
207+ break pagination ;
195208 }
196209 }
197210 final int numberofUniqueItemsOld = dupes .size ();
@@ -227,16 +240,16 @@ private ArrayList<DownloadLink> crawlProfileAPI(final String service, final Stri
227240 }
228241 if (this .isAbort ()) {
229242 logger .info ("Stopping because: Aborted by user" );
230- break ;
231- } else if (startOffset != null ) {
232- logger .info ("Stopping because: User provided specific offset to crawl: " + startOffset );
233- break ;
243+ break pagination ;
244+ } else if (StringUtils . isNotEmpty ( offsetString ) ) {
245+ logger .info ("Stopping because: User provided specific offset to crawl: " + offsetString );
246+ break pagination ;
234247 } else if (numberofContinuousPagesWithoutAnyNewItems >= maxPagesWithoutNewItems ) {
235248 logger .info ("Stopping because: Too many pages without any new items: " + maxPagesWithoutNewItems );
236- break ;
249+ break pagination ;
237250 } else if (posts .size () < maxItemsPerPage ) {
238251 logger .info ("Stopping because: Reached last page(?) Page: " + page );
239- break ;
252+ break pagination ;
240253 } else {
241254 /* Continue to next page */
242255 offset += posts .size ();
@@ -483,7 +496,9 @@ protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
483496 };
484497
485498 /**
486- * Returns userID for given username. </br> Uses API to find userID. </br> Throws Exception if it is unable to find userID.
499+ * Returns userID for given username. </br>
500+ * Uses API to find userID. </br>
501+ * Throws Exception if it is unable to find userID.
487502 */
488503 private String findUsername (final String service , final String usernameOrUserID ) throws Exception {
489504 synchronized (ID_TO_USERNAME ) {
0 commit comments