[ 'text' => [ 'name' => 'Text to search', 'title' => 'Search includes title, description and tags.', 'type' => 'text', 'exampleValue' => 'Text (incl. tags)' ], 'tags' => [ 'name' => 'Tags to search', 'title' => 'Space seperated tags to include in search. Prepend with "-" to exclude, "~" for optional.', 'type' => 'text', 'exampleValue' => 'tag1 -tag2 ~tag3' ], 'order' => [ 'name' => 'Sort by', 'type' => 'list', 'values' => [ 'Trending' => '-hotness_score', 'Newest' => '-date_added', 'Oldest' => 'date_added', 'Top' => '-num_likes', 'Bottom' => 'num_likes' ], 'defaultValue' => '-date_added' ], 'range' => [ 'name' => 'Date range', 'type' => 'list', 'values' => [ 'Today' => 'today', 'Yesterday' => 'yesterday', 'Past 3 days' => '3_days', 'Past week' => 'week', 'Past month' => '30_days', 'Past year' => '365_days', 'All time' => '' ], 'defaultValue' => 'All time' ], 'video_only' => [ 'name' => 'Video only?', 'type' => 'checkbox' ], 'rating_s' => [ 'name' => 'Include SFW', 'type' => 'checkbox' ], 'rating_q' => [ 'name' => 'Include Questionable', 'type' => 'checkbox' ], 'rating_e' => [ 'name' => 'Include NSFW', 'type' => 'checkbox' ] ], 'Post Search' => [ 'tags' => [ 'name' => 'Tags to search', 'title' => 'Space seperated tags to include in search. Prepend with "-" to exclude, "~" for optional.', 'type' => 'text', 'exampleValue' => 'tag1 -tag2 ~tag3' ], 'order' => [ 'name' => 'Sort by', 'type' => 'list', 'values' => [ 'Trending' => '-hotness_score', 'Newest' => '-date_added', 'Oldest' => 'date_added', 'Top' => '-num_likes', 'Bottom' => 'num_likes' ], 'defaultValue' => '-date_added' ], 'range' => [ 'name' => 'Date range', 'type' => 'list', 'values' => [ 'Today' => 'today', 'Yesterday' => 'yesterday', 'Past 3 days' => '3_days', 'Past week' => 'week', 'Past month' => '30_days', 'Past year' => '365_days', 'All time' => '' ], 'defaultValue' => 'All time' ], 'text_only' => [ 'name' => 'Only include posts with text?', 'type' => 'checkbox' ], 'rating_s' => [ 'name' => 'Include SFW', 'type' => 'checkbox' ], 'rating_q' => [ 'name' => 'Include Questionable', 'type' => 'checkbox' ], 'rating_e' => [ 'name' => 'Include NSFW', 'type' => 'checkbox' ] ], 'User profile' => [ 'user' => [ 'name' => 'Username', 'type' => 'text', 'required' => true ], 'user_id' => [ 'name' => 'User ID', 'type' => 'number', 'title' => 'User ID, if known.' ], 'reshares' => [ 'name' => 'Include reshares', 'type' => 'checkbox' ], 'rating_s' => [ 'name' => 'Include SFW', 'type' => 'checkbox' ], 'rating_q' => [ 'name' => 'Include Questionable', 'type' => 'checkbox' ], 'rating_e' => [ 'name' => 'Include NSFW', 'type' => 'checkbox' ] ], 'Home feed' => [ 'order' => [ 'name' => 'Sort by', 'type' => 'list', 'values' => [ 'Trending' => '-hotness_score', 'Newest' => '-date_added' ], 'defaultValue' => '-date_added' ], 'range' => [ 'name' => 'Date range', 'type' => 'list', 'values' => [ 'Today' => 'today', 'Yesterday' => 'yesterday', 'Past 3 days' => '3_days', 'Past week' => 'week', 'Past month' => '30_days', 'Past year' => '365_days', 'All time' => '' ], 'defaultValue' => 'All time' ], 'reshares' => [ 'name' => 'Include reshares', 'type' => 'checkbox' ], 'rating_s' => [ 'name' => 'Include SFW', 'type' => 'checkbox' ], 'rating_q' => [ 'name' => 'Include Questionable', 'type' => 'checkbox' ], 'rating_e' => [ 'name' => 'Include NSFW', 'type' => 'checkbox' ] ] ]; public function collectData() { if ($this->queriedContext === 'Image Search') { $opt = [ 'text' => $this->getInput('text'), 'optional_tags' => [], 'negative_tags' => [], 'required_tags' => [], 'order' => $this->getInput('order'), 'range' => $this->getInput('range'), 'video_only' => $this->getInput('video_only'), 'rating_s' => $this->getInput('rating_s'), 'rating_q' => $this->getInput('rating_q'), 'rating_e' => $this->getInput('rating_e') ]; $tag_arr = explode(' ', $this->getInput('tags') ?? ''); foreach ($tag_arr as $str) { switch ($str[0]) { case '-': $opt['negative_tags'][] = substr($str, 1); break; case '~': $opt['optional_tags'][] = substr($str, 1); break; default: $opt['required_tags'][] = substr($str, 1); break; } } $data = $this->getImagesSearch($opt); foreach ($data['results'] as $record) { $item = $this->getImage($record['id']); $this->addItem($item); } } if ($this->queriedContext === 'Post Search') { $opt = [ 'optional_tags' => [], 'negative_tags' => [], 'required_tags' => [], 'order' => $this->getInput('order'), 'range' => $this->getInput('range'), 'text_only' => $this->getInput('text_only'), 'rating_s' => $this->getInput('rating_s'), 'rating_q' => $this->getInput('rating_q'), 'rating_e' => $this->getInput('rating_e') ]; $tag_arr = explode(' ', $this->getInput('tags')); foreach ($tag_arr as $str) { switch ($str[0]) { case '-': $opt['negative_tags'][] = substr($str, 1); break; case '~': $opt['optional_tags'][] = substr($str, 1); break; default: $opt['required_tags'][] = substr($str, 1); break; } } $data = $this->getPostsSearch($opt); foreach ($data['results'] as $record) { $item = $this->getPost($record['id'], $record); $this->addItem($item); } } if ( $this->queriedContext === 'User profile' || $this->queriedContext === 'Home feed' ) { $opt = [ 'reshares' => $this->getInput('reshares'), 'rating_s' => $this->getInput('rating_s'), 'rating_q' => $this->getInput('rating_q'), 'rating_e' => $this->getInput('rating_e') ]; if ($this->queriedContext === 'User profile') { $opt['order'] = '-date_added'; $opt['range'] = ''; $user_id = $this->getInput('user_id') ?? $this->getOwnerID($this->getInput('user')); $data = $this->getFeed( $opt, $user_id ); } if ($this->queriedContext === 'Home feed') { $opt['order'] = $this->getInput('order'); $opt['range'] = $this->getInput('range'); $data = $this->getFeed($opt); } foreach ($data['results'] as $record) { switch ($record['content_type']) { case 'reshare': //get type of reshare and its id $id = $record['content_object']['content_object']['id']; switch ($record['content_object']['content_type']) { case 'galleryimage': $item = $this->getImage($id); $item['title'] = "{$record['owner_username']} shared: {$item['title']}"; break; case 'commission': $item = $this->getCommission($id, $record['content_object']['content_object']); $item['title'] = "{$record['owner_username']} shared: {$item['title']}"; break; case 'post': $item = $this->getPost($id, $record['content_object']['content_object']); $item['title'] = "{$record['owner_username']} shared: {$item['title']}"; break; }; break; case 'galleryimage': $item = $this->getImage($record['content_object']['id']); break; case 'commission': $item = $this->getCommission($record['content_object']['id'], $record['content_object']); break; case 'post': $item = $this->getPost($record['content_object']['id'], $record['content_object']); break; } $this->addItem($item); } } } public function getName() { return self::NAME; } public function getURI() { return self::URI; } private function getImagesSearch(array $opt) { $url = self::URI . "/api/galleries/images/?by_following=false&date_range={$opt['range']}&ordering={$opt['order']}&is_video={$opt['video_only']}"; $url .= "&text={$opt['text']}&visibility=PUBLIC&visibility=PROFILE_ONLY&page=1&page_size=30&format=json"; if (sizeof($opt['optional_tags']) > 0) { foreach ($opt['optional_tags'] as $tag) { $url .= "&optional_tags=$tag"; } } if (sizeof($opt['negative_tags']) > 0) { foreach ($opt['negative_tags'] as $tag) { $url .= "&negative_tags=$tag"; } } if (sizeof($opt['required_tags']) > 0) { foreach ($opt['required_tags'] as $tag) { $url .= "&required_tags=$tag"; } } if ($opt['rating_s']) { $url .= '&maturity_rating=SFW'; } if ($opt['rating_q']) { $url .= '&maturity_rating=Questionable'; } if ($opt['rating_e']) { $url .= '&maturity_rating=NSFW'; } return $this->getData($url, false, true); } private function getPostsSearch(array $opt) { $url = self::URI . "/api/posts/?by_following=false&date_range={$opt['range']}&ordering={$opt['order']}"; $url .= '&visibility=PUBLIC&visibility=PROFILE_ONLY&page=1&page_size=30&format=json'; if (sizeof($opt['optional_tags']) > 0) { foreach ($opt['optional_tags'] as $tag) { $url .= "&optional_tags=$tag"; } } if (sizeof($opt['negative_tags']) > 0) { foreach ($opt['negative_tags'] as $tag) { $url .= "&negative_tags=$tag"; } } if (sizeof($opt['required_tags']) > 0) { foreach ($opt['required_tags'] as $tag) { $url .= "&required_tags=$tag"; } } if ($opt['rating_s']) { $url .= '&maturity_rating=SFW'; } if ($opt['rating_q']) { $url .= '&maturity_rating=Questionable'; } if ($opt['rating_e']) { $url .= '&maturity_rating=NSFW'; } return $this->getData($url, false, true); } private function getFeed(array $opt, $ownerID = null) { $url = self::URI . "/api/feed/?date_range={$opt['range']}&ordering={$opt['order']}&page=1&page_size=30&format=json"; if (is_null($ownerID)) { $url .= '&visibility=PUBLIC&by_following=false'; } else { $url .= "&owner={$ownerID}"; } if (!$opt['reshares']) { $url .= '&hide_reshares=true'; } if ($opt['rating_s']) { $url .= '&maturity_rating=SFW'; } if ($opt['rating_q']) { $url .= '&maturity_rating=Questionable'; } if ($opt['rating_e']) { $url .= '&maturity_rating=NSFW'; } return $this->getData($url, false, true); } private function getOwnerID($username) { $url = self::URI . "/api/user_profiles/{$username}/?format=json"; $data = $this->getData($url, true, true) or returnServerError("Could not load $url"); return $data['owner']; } private function getPost($id, array $metadata = null) { if (isset($metadata) && sizeof($metadata['gallery_images']) < $metadata['num_images']) { $metadata = null; //force re-fetch of metadata } $uri = self::URI . '/posts/' . $id; $url = self::URI . '/api/posts/' . $id . '/?format=json'; $data = $metadata ?? $this->getData($url, true, true) or returnServerError("Could not load $url"); $content_str = nl2br($data['content']); $content = "
{$content_str}
';
$content .= "{$title}
";
if ($media['is_thumbnail_for_video']) {
$url = self::URI . '/api/galleries/images/' . $media['id'] . '/?format=json';
$media_data = $this->getData($url, true, true)
or returnServerError("Could not load $url");
$content .= "
{$content_str}
';
$content .= "{$data['thumbnail_detail']['title']}
";
if ($data['thumbnail_detail']['is_thumbnail_for_video']) {
$url = self::URI . '/api/galleries/images/' . $data['thumbnail_detail']['id'] . '/?format=json';
$media_data = $this->getData($url, true, true)
or returnServerError("Could not load $url");
$content .= "
{$content_str}