From 2b0bc159ed28d750bfa0da3466b5b7a75574b890 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Dec 2018 09:58:04 +0100 Subject: [PATCH 01/10] [FurAffinityBridge] Add new bridge --- bridges/FurAffinityBridge.php | 853 ++++++++++++++++++++++++++++++++++ 1 file changed, 853 insertions(+) create mode 100644 bridges/FurAffinityBridge.php diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php new file mode 100644 index 00000000000..c0c29aced44 --- /dev/null +++ b/bridges/FurAffinityBridge.php @@ -0,0 +1,853 @@ + array( + 'q' => array( + 'name' => 'Query', + 'required' => true + ), + 'rating-general' => array( + 'name' => 'General', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'rating-mature' => array( + 'name' => 'Mature', + 'type' => 'checkbox', + ), + 'rating-adult' => array( + 'name' => 'Adult', + 'type' => 'checkbox', + ), + 'range' => array( + 'name' => 'Time range', + 'type' => 'list', + 'required' => true, + 'values' => array( + 'A Day' => 'day', + '3 Days' => '3days', + 'A Week' => 'week', + 'A Month' => 'month', + 'All time' => 'all' + ), + 'defaultValue' => 'all' + ), + 'type-art' => array( + 'name' => 'Art', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'type-flash' => array( + 'name' => 'Flash', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'type-photo' => array( + 'name' => 'Photography', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'type-music' => array( + 'name' => 'Music', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'type-story' => array( + 'name' => 'Story', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'type-poetry' => array( + 'name' => 'Poetry', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'mode' => array( + 'name' => 'Match Mode', + 'type' => 'list', + 'required' => true, + 'values' => array( + 'All of the words' => 'all', + 'Any of the words' => 'any', + 'Extended' => 'extended' + ), + 'defaultValue' => 'extended' + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => 10, + 'title' => 'Limit number of submissions to return. -1 for unlimited.' + ), + 'full' => array( + 'name' => 'Full View', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ) + + ), + 'Browse' => array( + 'cat' => array( + 'name' => 'Category', + 'type' => 'list', + 'required' => true, + 'values' => array( + 'Visual Art' => array( + 'All' => 1, + 'Artwork (Digital)' => 2, + 'Artwork (Traditional)' => 3, + 'Cellshading' => 4, + 'Crafting' => 5, + 'Designs' => 6, + 'Flash' => 7, + 'Fursuiting' => 8, + 'Icons' => 9, + 'Mosaics' => 10, + 'Photography' => 11, + 'Sculpting' => 12 + ), + 'Readable Art' => array( + 'Story' => 13, + 'Poetry' => 14, + 'Prose' => 15 + ), + 'Audio Art' => array( + 'Music' => 16, + 'Podcasts' => 17 + ), + 'Downloadable' => array( + 'Skins' => 18, + 'Handhelds' => 19, + 'Resources' => 20 + ), + 'Other Stuff' => array( + 'Adoptables' => 21, + 'Auctions' => 22, + 'Contests' => 23, + 'Current Events' => 24, + 'Desktops' => 25, + 'Stockart' => 26, + 'Screenshots' => 27, + 'Scraps' => 28, + 'Wallpaper' => 29, + 'YCH / Sale' => 30, + 'Other' => 31 + ) + ), + 'defaultValue' => 1 + ), + 'atype' => array( + 'name' => 'Type', + 'type' => 'list', + 'required' => true, + 'values' => array( + 'General Things' => array( + 'All' => 1, + 'Abstract' => 2, + 'Animal related (non-anthro)' => 3, + 'Anime' => 4, + 'Comics' => 5, + 'Doodle' => 6, + 'Fanart' => 7, + 'Fantasy' => 8, + 'Human' => 9, + 'Portraits' => 10, + 'Scenery' => 11, + 'Still Life' => 12, + 'Tutorials' => 13, + 'Miscellaneous' => 14 + ), + 'Fetish / Furry specialty' => array( + 'Baby fur' => 101, + 'Bondage' => 102, + 'Digimon' => 103, + 'Fat Furs' => 104, + 'Fetish Other' => 105, + 'Fursuit' => 106, + 'Gore / Macabre Art' => 119, + 'Hyper' => 107, + 'Inflation' => 108, + 'Macro / Micro' => 109, + 'Muscle' => 110, + 'My Little Pony / Brony' => 111, + 'Paw' => 112, + 'Pokemon' => 113, + 'Pregnancy' => 114, + 'Sonic' => 115, + 'Transformation' => 116, + 'Vore' => 117, + 'Water Sports' => 118, + 'General Furry Art' => 100 + ), + 'Music' => array( + 'Techno' => 201, + 'Trance' => 202, + 'House' => 203, + '90s' => 204, + '80s' => 205, + '70s' => 206, + '60s' => 207, + 'Pre-60s' => 208, + 'Classical' => 209, + 'Game Music' => 210, + 'Rock' => 211, + 'Pop' => 212, + 'Rap' => 213, + 'Industrial' => 214, + 'Other Music' => 200 + ) + ), + 'defaultValue' => 1 + ), + 'species' => array( + 'name' => 'Species', + 'type' => 'list', + 'required' => true, + 'values' => array( + 'Unspecified / Any' => 1, + 'Amphibian' => array( + 'Frog' => 1001, + 'Newt' => 1002, + 'Salamander' => 1003, + 'Amphibian (Other)' => 1000 + ), + 'Aquatic' => array( + 'Cephalopod' => 2001, + 'Dolphin' => 2002, + 'Fish' => 2005, + 'Porpoise' => 2004, + 'Seal' => 6068, + 'Shark' => 2006, + 'Whale' => 2003, + 'Aquatic (Other)' => 2000 + ), + 'Avian' => array( + 'Corvid' => 3001, + 'Crow' => 3002, + 'Duck' => 3003, + 'Eagle' => 3004, + 'Falcon' => 3005, + 'Goose' => 3006, + 'Gryphon' => 3007, + 'Hawk' => 3008, + 'Owl' => 3009, + 'Phoenix' => 3010, + 'Swan' => 3011, + 'Avian (Other)' => 3000 + ), + 'Bears & Ursines' => array( + 'Bear' => 6002 + ), + 'Camelids' => array( + 'Camel' => 6074, + 'Llama' => 6036 + ), + 'Canines & Lupines' => array( + 'Coyote' => 6008, + 'Doberman' => 6009, + 'Dog' => 6010, + 'Dingo' => 6011, + 'German Shepherd' => 6012, + 'Jackal' => 6013, + 'Husky' => 6014, + 'Wolf' => 6016, + 'Canine (Other)' => 6017 + ), + 'Cervines' => array( + 'Cervine (Other)' => 6018 + ), + 'Cows & Bovines' => array( + 'Antelope' => 6004, + 'Cows' => 6003, + 'Gazelle' => 6005, + 'Goat' => 6006, + 'Bovines (General)' => 6007 + ), + 'Dragons' => array( + 'Eastern Dragon' => 4001, + 'Hydra' => 4002, + 'Serpent' => 4003, + 'Western Dragon' => 4004, + 'Wyvern' => 4005, + 'Dragon (Other)' => 4000 + ), + 'Equestrians' => array( + 'Donkey' => 6019, + 'Horse' => 6034, + 'Pony' => 6073, + 'Zebra' => 6071 + ), + 'Exotic & Mythicals' => array( + 'Argonian' => 5002, + 'Chakat' => 5003, + 'Chocobo' => 5004, + 'Citra' => 5005, + 'Crux' => 5006, + 'Daemon' => 5007, + 'Digimon' => 5008, + 'Dracat' => 5009, + 'Draenei' => 5010, + 'Elf' => 5011, + 'Gargoyle' => 5012, + 'Iksar' => 5013, + 'Kaiju/Monster' => 5015, + 'Langurhali' => 5014, + 'Moogle' => 5017, + 'Naga' => 5016, + 'Orc' => 5018, + 'Pokemon' => 5019, + 'Satyr' => 5020, + 'Sergal' => 5021, + 'Tanuki' => 5022, + 'Unicorn' => 5023, + 'Xenomorph' => 5024, + 'Alien (Other)' => 5001, + 'Exotic (Other)' => 5000 + ), + 'Felines' => array( + 'Domestic Cat' => 6020, + 'Cheetah' => 6021, + 'Cougar' => 6022, + 'Jaguar' => 6023, + 'Leopard' => 6024, + 'Lion' => 6025, + 'Lynx' => 6026, + 'Ocelot' => 6027, + 'Panther' => 6028, + 'Tiger' => 6029, + 'Feline (Other)' => 6030 + ), + 'Insects' => array( + 'Arachnid' => 8000, + 'Mantid' => 8004, + 'Scorpion' => 8005, + 'Insect (Other)' => 8003 + ), + 'Mammals (Other)' => array( + 'Bat' => 6001, + 'Giraffe' => 6031, + 'Hedgehog' => 6032, + 'Hippopotamus' => 6033, + 'Hyena' => 6035, + 'Panda' => 6052, + 'Pig/Swine' => 6053, + 'Rabbit/Hare' => 6059, + 'Raccoon' => 6060, + 'Red Panda' => 6062, + 'Meerkat' => 6043, + 'Mongoose' => 6044, + 'Rhinoceros' => 6063, + 'Mammals (Other)' => 6000 + ), + 'Marsupials' => array( + 'Opossum' => 6037, + 'Kangaroo' => 6038, + 'Koala' => 6039, + 'Quoll' => 6040, + 'Wallaby' => 6041, + 'Marsupial (Other)' => 6042 + ), + 'Mustelids' => array( + 'Badger' => 6045, + 'Ferret' => 6046, + 'Mink' => 6048, + 'Otter' => 6047, + 'Skunk' => 6069, + 'Weasel' => 6049, + 'Mustelid (Other)' => 6051 + ), + 'Primates' => array( + 'Gorilla' => 6054, + 'Human' => 6055, + 'Lemur' => 6056, + 'Monkey' => 6057, + 'Primate (Other)' => 6058 + ), + 'Reptillian' => array( + 'Alligator & Crocodile' => 7001, + 'Gecko' => 7003, + 'Iguana' => 7004, + 'Lizard' => 7005, + 'Snakes & Serpents' => 7006, + 'Turtle' => 7007, + 'Reptilian (Other)' => 7000 + ), + 'Rodents' => array( + 'Beaver' => 6064, + 'Mouse' => 6065, + 'Rat' => 6061, + 'Squirrel' => 6070, + 'Rodent (Other)' => 6067 + ), + 'Vulpines' => array( + 'Fennec' => 6072, + 'Fox' => 6075, + 'Vulpine (Other)' => 6015 + ), + 'Other' => array( + 'Dinosaur' => 8001, + 'Wolverine' => 6050 + ) + ), + 'defaultValue' => 1 + ), + 'gender' => array( + 'name' => 'Gender', + 'type' => 'list', + 'required' => false, + 'values' => array( + 'Any' => 0, + 'Male' => 2, + 'Female' => 3, + 'Herm' => 4, + 'Transgender' => 5, + 'Multiple characters' => 6, + 'Other / Not Specified' => 7 + ), + 'defaultValue' => 0 + ), + 'rating_general' => array( + 'name' => 'General', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'rating_mature' => array( + 'name' => 'Mature', + 'type' => 'checkbox', + ), + 'rating_adult' => array( + 'name' => 'Adult', + 'type' => 'checkbox', + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => 10, + 'title' => 'Limit number of submissions to return. -1 for unlimited.' + ), + 'full' => array( + 'name' => 'Full View', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ) + + ), + 'Journals' => array( + 'username-journals' => array( + 'name' => 'Username', + 'required' => true, + 'title' => 'Lowercase username as seen in URLs' + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => -1, + 'title' => 'Limit number of journals to return. -1 for unlimited.' + ) + + ), + 'Single Journal' => array( + 'journal-id' => array( + 'name' => 'Journal ID', + 'required' => true, + 'type' => 'number', + 'title' => 'Number seen in journal URL' + ) + ), + 'Gallery' => array( + 'username-gallery' => array( + 'name' => 'Username', + 'required' => true, + 'title' => 'Lowercase username as seen in URLs' + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => 10, + 'title' => 'Limit number of submissions to return. -1 for unlimited.' + ), + 'full' => array( + 'name' => 'Full View', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ) + ), + 'Scraps' => array( + 'username-scraps' => array( + 'name' => 'Username', + 'required' => true, + 'title' => 'Lowercase username as seen in URLs' + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => 10, + 'title' => 'Limit number of submissions to return. -1 for unlimited.' + ), + 'full' => array( + 'name' => 'Full View', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ) + ), + 'Favorites' => array( + 'username-favorites' => array( + 'name' => 'Username', + 'required' => true, + 'title' => 'Lowercase username as seen in URLs' + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => 10, + 'title' => 'Limit number of submissions to return. -1 for unlimited.' + ), + 'full' => array( + 'name' => 'Full View', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ) + ), + 'Gallery Folder' => array( + 'username-folder' => array( + 'name' => 'Username', + 'required' => true, + 'title' => 'Lowercase username as seen in URLs' + ), + 'folder-id' => array( + 'name' => 'Folder ID', + 'required' => true, + 'type' => 'number', + 'title' => 'Number seen in folder URL' + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'defaultValue' => 10, + 'title' => 'Limit number of submissions to return. -1 for unlimited.' + ), + 'full' => array( + 'name' => 'Full View', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ) + + + ) + ); + + /* + * This was aquired by creating a new user on FA then + * extracting the cookie from the browsers dev console. + */ + const FA_AUTH_COOKIE = 'b=4ce65691-b50f-4742-a990-bf28d6de16ee; a=ca6e4566-9d81-4263-9444-653b142e35f8'; + + public function detectParameters($url) { + $params = array(); + + // Single journal + $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/journal\/(\d+)/'; + if(preg_match($regex, $url, $matches) > 0) { + $params['journal-id'] = urldecode($matches[3]); + return $params; + } + + // Journals + $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/journals\/([^\/&?\n]+)/'; + if(preg_match($regex, $url, $matches) > 0) { + $params['username-journals'] = urldecode($matches[3]); + return $params; + } + + // Gallery folder + $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/gallery\/([^\/&?\n]+)\/folder\/(\d+)/'; + if(preg_match($regex, $url, $matches) > 0) { + $params['username-folder'] = urldecode($matches[3]); + $params['folder-id'] = urldecode($matches[4]); + $params['full'] = 'on'; + return $params; + } + + // Gallery (must be after gallery folder) + $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/(gallery|scraps|favorites)\/([^\/&?\n]+)/'; + if(preg_match($regex, $url, $matches) > 0) { + $params['username-' . $matches[3]] = urldecode($matches[4]); + $params['full'] = 'on'; + return $params; + } + + return null; + } + + public function getName() { + switch($this->queriedContext) { + case 'Search': + return 'Search For ' + . $this->getInput('q'); + case 'Browse': + return 'Browse'; + case 'Journals': return $this->getInput('username-journals'); + case 'Single Journal': + return 'Journal ' + . $this->getInput('journal-id'); + case 'Gallery': return $this->getInput('username-gallery'); + case 'Scraps': return $this->getInput('username-scraps'); + case 'Favorites': return $this->getInput('username-favorites'); + case 'Gallery Folder': + return $this->getInput('username-folder') + . '\'s Folder ' + . $this->getInput('folder-id'); + default: return parent::getName(); + } + } + + public function getDescription() { + switch($this->queriedContext) { + case 'Search': + return 'FurAffinity Search For ' + . $this->getInput('q'); + case 'Browse': + return 'FurAffinity Browse'; + case 'Journals': + return 'FurAffinity Journals By ' + . $this->getInput('username-journals'); + case 'Single Journal': + return 'FurAffinity Journal ' + . $this->getInput('journal-id'); + case 'Gallery': + return 'FurAffinity Gallery By ' + . $this->getInput('username-gallery'); + case 'Scraps': + return 'FurAffinity Scraps By ' + . $this->getInput('username-scraps'); + case 'Favorites': + return 'FurAffinity Favorites By ' + . $this->getInput('username-favorites'); + case 'Gallery Folder': + return 'FurAffinity Gallery Folder ' + . $this->getInput('folder-id') + . ' By ' + . $this->getInput('username-folder'); + default: return parent::getDescription(); + } + } + + public function getURI() { + switch($this->queriedContext) { + case 'Search': + return SELF::URI + . '/search'; + case 'Browse': + return SELF::URI + . '/browse'; + case 'Journals': + return SELF::URI + . '/journals/' + . $this->getInput('username-journals'); + case 'Single Journal': + return SELF::URI + . '/journal/' + . $this->getInput('journal-id'); + case 'Gallery': + return SELF::URI + . '/gallery/' + . $this->getInput('username-gallery'); + case 'Scraps': + return SELF::URI + . '/scraps/' + . $this->getInput('username-scraps'); + case 'Favorites': + return SELF::URI + . '/favorites/' + . $this->getInput('username-favorites'); + case 'Gallery Folder': + return SELF::URI + . '/gallery/' + . $this->getInput('username-folder') + . '/folder/' + . $this->getInput('folder-id'); + default: return parent::getURI(); + } + } + + public function collectData() { + switch($this->queriedContext) { + case 'Search': + $data = array( + 'q' => $this->getInput('q'), + 'perpage' => 72, + 'rating-general' => ($this->getInput('rating-general') === true ? 'on' : 0), + 'rating-mature' => ($this->getInput('rating-mature') === true ? 'on' : 0), + 'rating-adult' => ($this->getInput('rating-adult') === true ? 'on' : 0), + 'range' => $this->getInput('range'), + 'type-art' => ($this->getInput('type-art') === true ? 'on' : 0), + 'type-flash' => ($this->getInput('type-flash') === true ? 'on' : 0), + 'type-photo' => ($this->getInput('type-photo') === true ? 'on' : 0), + 'type-music' => ($this->getInput('type-music') === true ? 'on' : 0), + 'type-story' => ($this->getInput('type-story') === true ? 'on' : 0), + 'type-poetry' => ($this->getInput('type-poetry') === true ? 'on' : 0), + 'mode' => $this->getInput('mode') + ); + $html = $this->postFASimpleHTMLDOM($data); + $this->itemsFromSubmissionList($html); + break; + case 'Browse': + $data = array( + 'cat' => $this->getInput('cat'), + 'atype' => $this->getInput('atype'), + 'species' => $this->getInput('species'), + 'gender' => $this->getInput('gender'), + 'perpage' => 72, + 'rating_general' => ($this->getInput('rating_general') === true ? 'on' : 0), + 'rating_mature' => ($this->getInput('rating_mature') === true ? 'on' : 0), + 'rating_adult' => ($this->getInput('rating_adult') === true ? 'on' : 0) + ); + $html = $this->postFASimpleHTMLDOM($data); + $this->itemsFromSubmissionList($html); + break; + case 'Journals': + $html = $this->getFASimpleHTMLDOM($this->getURI()); + $this->itemsFromJournalList($html); + break; + case 'Single Journal': + $html = $this->getFASimpleHTMLDOM($this->getURI()); + $this->itemsFromJournal($html); + break; + case 'Gallery': + case 'Scraps': + case 'Favorites': + case 'Gallery Folder': + $html = $this->getFASimpleHTMLDOM($this->getURI()); + $this->itemsFromSubmissionList($html); + break; + } + } + + private function postFASimpleHTMLDOM($data) { + $opts = array( + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => http_build_query($data) + ); + $header = array( + 'Host: ' . parse_url(self::URI, PHP_URL_HOST), + 'Content-Type: application/x-www-form-urlencoded', + 'Cookie: ' . self::FA_AUTH_COOKIE + ); + return getSimpleHTMLDOM($this->getURI(), $header, $opts); + } + + private function getFASimpleHTMLDOM($url) { + $header = array( + 'Cookie: ' . self::FA_AUTH_COOKIE + ); + return getSimpleHTMLDOM($url, $header); + } + + private function itemsFromJournalList($html) { + $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); + + foreach($html->find('table[id^=jid:]') as $journal) { + if($limit-- === 0) break; + + $item = array(); + + $this->makeLinksAbsolute($journal); + + $item['uri'] = $journal->find('a', 0)->href; + $item['title'] = $journal->find('a', 0)->plaintext; + $item['author'] = $this->getInput('username-journals'); + $item['timestamp'] = strtotime( + $journal->find('span.popup_date', 0)->plaintext); + $item['content'] = $journal + ->find('.alt1 table div.no_overflow', 0) + ->innertext; + + $this->items[] = $item; + } + } + + private function itemsFromJournal($html) { + $this->makeLinksAbsolute($html); + $item = array(); + + $item['uri'] = $this->getURI(); + $item['title'] = $html->find('.journal-title-box .no_overflow', 0)->plaintext; + $item['author'] = $html->find('.journal-title-box a', 0)->plaintext; + $item['timestamp'] = strtotime( + $html->find('.journal-title-box span.popup_date', 0)->plaintext); + $item['content'] = $html->find('.journal-body', 0)->innertext; + + $this->items[] = $item; + } + + private function itemsFromSubmissionList($html) { + $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); + + foreach($html->find('section.gallery figure') as $figure) { + if($limit-- === 0) break; + + $item = array(); + + $submissionURL = self::URI . $figure->find('b u a', 0)->href; + $imgURL = 'https:' . $figure->find('b u a img', 0)->src; + + $item['uri'] = $submissionURL; + $item['title'] = $figure->find('figcaption p a[href^=/view]', 0)->title; + $item['author'] = $figure->find('figcaption p a[href^=/user]', 0)->title; + + if($this->getInput('full') === true) { + $submissionHTML = $this->getFASimpleHTMLDOM($submissionURL); + + $stats = $submissionHTML->find('.stats-container', 0); + $item['timestamp'] = strtotime($stats->find('.popup_date', 0)->plaintext); + $item['enclosures'] = array( + $submissionHTML->find('.actions a[href^=//d.facdn]', 0)->href + ); + foreach($stats->find('#keywords a') as $keyword) { + $item['categories'][] = $keyword->plaintext; + } + + $previewSrc = $submissionHTML->find('#submissionImg', 0) + ->{'data-preview-src'}; + if($previewSrc) { + $imgURL = 'https:' . $previewSrc; + } + + $description = $submissionHTML + ->find('.maintable .maintable tbody tr td.alt1', -1); + $this->makeLinksAbsolute($description); + $description = $description->innertext; + + $item['content'] = << + + +

+{$description} +

+EOD; + } else { + $item['content'] = << + + +EOD; + } + + $this->items[] = $item; + } + } + + private function makeLinksAbsolute(&$html) { + foreach($html->find('*[href]') as $link) { + if(preg_match('/^\/[^\/]/', $link->href)) { + $link->href = self::URI . $link->href; + } + } + } +} From d1205c3398bc922dc5a1f3dc75659c70f0231794 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Dec 2018 12:04:48 +0100 Subject: [PATCH 02/10] [FurAffinityBridge] Set referrerpolicy for images --- bridges/FurAffinityBridge.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index c0c29aced44..7a37568b0bc 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -806,7 +806,7 @@ private function itemsFromSubmissionList($html) { $stats = $submissionHTML->find('.stats-container', 0); $item['timestamp'] = strtotime($stats->find('.popup_date', 0)->plaintext); $item['enclosures'] = array( - $submissionHTML->find('.actions a[href^=//d.facdn]', 0)->href + 'https:' . $submissionHTML->find('.actions a[href^=//d.facdn]', 0)->href ); foreach($stats->find('#keywords a') as $keyword) { $item['categories'][] = $keyword->plaintext; @@ -823,9 +823,15 @@ private function itemsFromSubmissionList($html) { $this->makeLinksAbsolute($description); $description = $description->innertext; + /* + * Note: Without the no-referrer policy their CDN sometimes denies requests. + * We can't control this for enclosures sadly. + * At least tt-rss adds the referrerpolicy on its own. + * Alternatively we could not use https for images, but that's not ideal. + */ $item['content'] = << - +

{$description} @@ -834,7 +840,7 @@ private function itemsFromSubmissionList($html) { } else { $item['content'] = << - + EOD; } From 2a70562a8ef98562fd28b63a14e346e05eddd4d1 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Dec 2018 12:58:51 +0100 Subject: [PATCH 03/10] [FurAffinityBridge] Add no-referrer for journals --- bridges/FurAffinityBridge.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index 7a37568b0bc..1ce0ebf5ffd 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -821,6 +821,7 @@ private function itemsFromSubmissionList($html) { $description = $submissionHTML ->find('.maintable .maintable tbody tr td.alt1', -1); $this->makeLinksAbsolute($description); + $this->setImgReferrerPolicy($description); $description = $description->innertext; /* @@ -849,6 +850,12 @@ private function itemsFromSubmissionList($html) { } } + private function setImgReferrerPolicy(&$html) { + foreach($html->find('img') as $img) { + $img->referrerpolicy = 'no-referrer'; + } + } + private function makeLinksAbsolute(&$html) { foreach($html->find('*[href]') as $link) { if(preg_match('/^\/[^\/]/', $link->href)) { From 519afd839f115c4bba074e543a0d6975ef1cdd4a Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Dec 2018 13:19:27 +0100 Subject: [PATCH 04/10] [FurAffinityBridge] Make img srcs https --- bridges/FurAffinityBridge.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index 1ce0ebf5ffd..abed3e96885 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -756,7 +756,7 @@ private function itemsFromJournalList($html) { $item = array(); - $this->makeLinksAbsolute($journal); + $this->cleanupHTMLDOM($journal); $item['uri'] = $journal->find('a', 0)->href; $item['title'] = $journal->find('a', 0)->plaintext; @@ -772,7 +772,7 @@ private function itemsFromJournalList($html) { } private function itemsFromJournal($html) { - $this->makeLinksAbsolute($html); + $this->cleanupHTMLDOM($html); $item = array(); $item['uri'] = $this->getURI(); @@ -820,16 +820,9 @@ private function itemsFromSubmissionList($html) { $description = $submissionHTML ->find('.maintable .maintable tbody tr td.alt1', -1); - $this->makeLinksAbsolute($description); - $this->setImgReferrerPolicy($description); + $this->cleanupHTMLDOM($description); $description = $description->innertext; - /* - * Note: Without the no-referrer policy their CDN sometimes denies requests. - * We can't control this for enclosures sadly. - * At least tt-rss adds the referrerpolicy on its own. - * Alternatively we could not use https for images, but that's not ideal. - */ $item['content'] = << @@ -850,13 +843,20 @@ private function itemsFromSubmissionList($html) { } } - private function setImgReferrerPolicy(&$html) { + private function cleanupHTMLDOM(&$html) { foreach($html->find('img') as $img) { + /* + * Note: Without the no-referrer policy their CDN sometimes denies requests. + * We can't control this for enclosures sadly. + * At least tt-rss adds the referrerpolicy on its own. + * Alternatively we could not use https for images, but that's not ideal. + */ $img->referrerpolicy = 'no-referrer'; + if(preg_match('/^\/\//', $img->src)) { + $img->src = 'https:' . $img->src; + } } - } - - private function makeLinksAbsolute(&$html) { + // Make hrefs absolute foreach($html->find('*[href]') as $link) { if(preg_match('/^\/[^\/]/', $link->href)) { $link->href = self::URI . $link->href; From aa40d2ff173a0972c1aea0c6d3e3c2fdca858902 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 14 Jan 2019 00:30:38 +0100 Subject: [PATCH 05/10] [FurAffinityBridge] Add submission page caching --- bridges/FurAffinityBridge.php | 68 +++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index abed3e96885..176b65f4da3 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -68,7 +68,7 @@ class FurAffinityBridge extends BridgeAbstract { 'defaultValue' => 'checked' ), 'mode' => array( - 'name' => 'Match Mode', + 'name' => 'Match mode', 'type' => 'list', 'required' => true, 'values' => array( @@ -85,11 +85,17 @@ class FurAffinityBridge extends BridgeAbstract { 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), 'full' => array( - 'name' => 'Full View', + 'name' => 'Full view', + 'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'cache' => array( + 'name' => 'Cache submission pages', + 'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.', 'type' => 'checkbox', 'defaultValue' => 'checked' ) - ), 'Browse' => array( 'cat' => array( @@ -431,7 +437,14 @@ class FurAffinityBridge extends BridgeAbstract { 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), 'full' => array( - 'name' => 'Full View', + 'name' => 'Full view', + 'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'cache' => array( + 'name' => 'Cache submission pages', + 'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.', 'type' => 'checkbox', 'defaultValue' => 'checked' ) @@ -472,7 +485,14 @@ class FurAffinityBridge extends BridgeAbstract { 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), 'full' => array( - 'name' => 'Full View', + 'name' => 'Full view', + 'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'cache' => array( + 'name' => 'Cache submission pages', + 'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.', 'type' => 'checkbox', 'defaultValue' => 'checked' ) @@ -490,7 +510,14 @@ class FurAffinityBridge extends BridgeAbstract { 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), 'full' => array( - 'name' => 'Full View', + 'name' => 'Full view', + 'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'cache' => array( + 'name' => 'Cache submission pages', + 'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.', 'type' => 'checkbox', 'defaultValue' => 'checked' ) @@ -508,7 +535,14 @@ class FurAffinityBridge extends BridgeAbstract { 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), 'full' => array( - 'name' => 'Full View', + 'name' => 'Full view', + 'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'cache' => array( + 'name' => 'Cache submission pages', + 'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.', 'type' => 'checkbox', 'defaultValue' => 'checked' ) @@ -532,7 +566,14 @@ class FurAffinityBridge extends BridgeAbstract { 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), 'full' => array( - 'name' => 'Full View', + 'name' => 'Full view', + 'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.', + 'type' => 'checkbox', + 'defaultValue' => 'checked' + ), + 'cache' => array( + 'name' => 'Cache submission pages', + 'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.', 'type' => 'checkbox', 'defaultValue' => 'checked' ) @@ -741,11 +782,15 @@ private function postFASimpleHTMLDOM($data) { return getSimpleHTMLDOM($this->getURI(), $header, $opts); } - private function getFASimpleHTMLDOM($url) { + private function getFASimpleHTMLDOM($url, $cache = false) { $header = array( 'Cookie: ' . self::FA_AUTH_COOKIE ); - return getSimpleHTMLDOM($url, $header); + if($cache) { + return getSimpleHTMLDOMCached($url, 86400, $header); // 24 hours + } else { + return getSimpleHTMLDOM($url, $header); + } } private function itemsFromJournalList($html) { @@ -787,6 +832,7 @@ private function itemsFromJournal($html) { private function itemsFromSubmissionList($html) { $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); + $cache = ($this->getInput('cache') === true); foreach($html->find('section.gallery figure') as $figure) { if($limit-- === 0) break; @@ -801,7 +847,7 @@ private function itemsFromSubmissionList($html) { $item['author'] = $figure->find('figcaption p a[href^=/user]', 0)->title; if($this->getInput('full') === true) { - $submissionHTML = $this->getFASimpleHTMLDOM($submissionURL); + $submissionHTML = $this->getFASimpleHTMLDOM($submissionURL, $cache); $stats = $submissionHTML->find('.stats-container', 0); $item['timestamp'] = strtotime($stats->find('.popup_date', 0)->plaintext); From 39c0da8c6eeac556c947c3f7a67e939ae01fca10 Mon Sep 17 00:00:00 2001 From: Roliga Date: Wed, 6 Mar 2019 14:28:29 +0100 Subject: [PATCH 06/10] [FurAffinityBridge] Fix lists not deciding context --- bridges/FurAffinityBridge.php | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index 176b65f4da3..b1b8c687b1f 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -27,7 +27,6 @@ class FurAffinityBridge extends BridgeAbstract { 'range' => array( 'name' => 'Time range', 'type' => 'list', - 'required' => true, 'values' => array( 'A Day' => 'day', '3 Days' => '3days', @@ -70,7 +69,6 @@ class FurAffinityBridge extends BridgeAbstract { 'mode' => array( 'name' => 'Match mode', 'type' => 'list', - 'required' => true, 'values' => array( 'All of the words' => 'all', 'Any of the words' => 'any', @@ -101,7 +99,6 @@ class FurAffinityBridge extends BridgeAbstract { 'cat' => array( 'name' => 'Category', 'type' => 'list', - 'required' => true, 'values' => array( 'Visual Art' => array( 'All' => 1, @@ -150,7 +147,6 @@ class FurAffinityBridge extends BridgeAbstract { 'atype' => array( 'name' => 'Type', 'type' => 'list', - 'required' => true, 'values' => array( 'General Things' => array( 'All' => 1, @@ -213,7 +209,6 @@ class FurAffinityBridge extends BridgeAbstract { 'species' => array( 'name' => 'Species', 'type' => 'list', - 'required' => true, 'values' => array( 'Unspecified / Any' => 1, 'Amphibian' => array( @@ -405,7 +400,6 @@ class FurAffinityBridge extends BridgeAbstract { 'gender' => array( 'name' => 'Gender', 'type' => 'list', - 'required' => false, 'values' => array( 'Any' => 0, 'Male' => 2, @@ -430,9 +424,10 @@ class FurAffinityBridge extends BridgeAbstract { 'name' => 'Adult', 'type' => 'checkbox', ), - 'limit' => array( + 'limit-browse' => array( 'name' => 'Limit', 'type' => 'number', + 'required' => true, 'defaultValue' => 10, 'title' => 'Limit number of submissions to return. -1 for unlimited.' ), @@ -735,7 +730,8 @@ public function collectData() { 'mode' => $this->getInput('mode') ); $html = $this->postFASimpleHTMLDOM($data); - $this->itemsFromSubmissionList($html); + $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); + $this->itemsFromSubmissionList($html, $limit); break; case 'Browse': $data = array( @@ -749,11 +745,13 @@ public function collectData() { 'rating_adult' => ($this->getInput('rating_adult') === true ? 'on' : 0) ); $html = $this->postFASimpleHTMLDOM($data); - $this->itemsFromSubmissionList($html); + $limit = (is_int($this->getInput('limit-browse')) ? $this->getInput('limit-browse') : 10); + $this->itemsFromSubmissionList($html, $limit); break; case 'Journals': $html = $this->getFASimpleHTMLDOM($this->getURI()); - $this->itemsFromJournalList($html); + $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : -1); + $this->itemsFromJournalList($html, $limit); break; case 'Single Journal': $html = $this->getFASimpleHTMLDOM($this->getURI()); @@ -764,7 +762,8 @@ public function collectData() { case 'Favorites': case 'Gallery Folder': $html = $this->getFASimpleHTMLDOM($this->getURI()); - $this->itemsFromSubmissionList($html); + $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); + $this->itemsFromSubmissionList($html, $limit); break; } } @@ -793,9 +792,7 @@ private function getFASimpleHTMLDOM($url, $cache = false) { } } - private function itemsFromJournalList($html) { - $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); - + private function itemsFromJournalList($html, $limit) { foreach($html->find('table[id^=jid:]') as $journal) { if($limit-- === 0) break; @@ -830,8 +827,7 @@ private function itemsFromJournal($html) { $this->items[] = $item; } - private function itemsFromSubmissionList($html) { - $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10); + private function itemsFromSubmissionList($html, $limit) { $cache = ($this->getInput('cache') === true); foreach($html->find('section.gallery figure') as $figure) { @@ -865,7 +861,7 @@ private function itemsFromSubmissionList($html) { } $description = $submissionHTML - ->find('.maintable .maintable tbody tr td.alt1', -1); + ->find('.maintable .maintable tr td.alt1', -1); $this->cleanupHTMLDOM($description); $description = $description->innertext; From 5ae91b6aec684a80200dc7ff7b45811b3d89a258 Mon Sep 17 00:00:00 2001 From: Roliga Date: Fri, 12 Apr 2019 14:35:23 +0200 Subject: [PATCH 07/10] [FurAffinityBridge] Handle html entities in titles --- bridges/FurAffinityBridge.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index b1b8c687b1f..9c96f5cf659 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -801,7 +801,7 @@ private function itemsFromJournalList($html, $limit) { $this->cleanupHTMLDOM($journal); $item['uri'] = $journal->find('a', 0)->href; - $item['title'] = $journal->find('a', 0)->plaintext; + $item['title'] = html_entity_decode($journal->find('a', 0)->plaintext); $item['author'] = $this->getInput('username-journals'); $item['timestamp'] = strtotime( $journal->find('span.popup_date', 0)->plaintext); @@ -818,7 +818,12 @@ private function itemsFromJournal($html) { $item = array(); $item['uri'] = $this->getURI(); - $item['title'] = $html->find('.journal-title-box .no_overflow', 0)->plaintext; + + $title = $html->find('.journal-title-box .no_overflow', 0)->plaintext; + $title = html_entity_decode($title); + $title = trim($title, " \t\n\r\0\x0B" . chr(0xC2) . chr(0xA0)); + $item['title'] = $title; + $item['author'] = $html->find('.journal-title-box a', 0)->plaintext; $item['timestamp'] = strtotime( $html->find('.journal-title-box span.popup_date', 0)->plaintext); @@ -839,7 +844,8 @@ private function itemsFromSubmissionList($html, $limit) { $imgURL = 'https:' . $figure->find('b u a img', 0)->src; $item['uri'] = $submissionURL; - $item['title'] = $figure->find('figcaption p a[href^=/view]', 0)->title; + $item['title'] = html_entity_decode( + $figure->find('figcaption p a[href^=/view]', 0)->title); $item['author'] = $figure->find('figcaption p a[href^=/user]', 0)->title; if($this->getInput('full') === true) { From 335d9fe4125cd4a7e8dbf45920742ee7401ba6a0 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Jun 2019 13:38:01 +0200 Subject: [PATCH 08/10] [FurAffinityBridge] Use defaultLinkTo --- bridges/FurAffinityBridge.php | 44 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index 9c96f5cf659..681ec914acd 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -572,8 +572,6 @@ class FurAffinityBridge extends BridgeAbstract { 'type' => 'checkbox', 'defaultValue' => 'checked' ) - - ) ); @@ -778,18 +776,27 @@ private function postFASimpleHTMLDOM($data) { 'Content-Type: application/x-www-form-urlencoded', 'Cookie: ' . self::FA_AUTH_COOKIE ); - return getSimpleHTMLDOM($this->getURI(), $header, $opts); + + $html = getSimpleHTMLDOM($this->getURI(), $header, $opts); + $html = defaultLinkTo($html, $this->getURI()); + + return $html; } private function getFASimpleHTMLDOM($url, $cache = false) { $header = array( 'Cookie: ' . self::FA_AUTH_COOKIE ); + if($cache) { - return getSimpleHTMLDOMCached($url, 86400, $header); // 24 hours + $html = getSimpleHTMLDOMCached($url, 86400, $header); // 24 hours } else { - return getSimpleHTMLDOM($url, $header); + $html = getSimpleHTMLDOM($url, $header); } + + $html = defaultLinkTo($html, $url); + + return $html; } private function itemsFromJournalList($html, $limit) { @@ -798,7 +805,7 @@ private function itemsFromJournalList($html, $limit) { $item = array(); - $this->cleanupHTMLDOM($journal); + $this->setReferrerPolicy($journal); $item['uri'] = $journal->find('a', 0)->href; $item['title'] = html_entity_decode($journal->find('a', 0)->plaintext); @@ -814,7 +821,7 @@ private function itemsFromJournalList($html, $limit) { } private function itemsFromJournal($html) { - $this->cleanupHTMLDOM($html); + $this->setReferrerPolicy($html); $item = array(); $item['uri'] = $this->getURI(); @@ -840,21 +847,21 @@ private function itemsFromSubmissionList($html, $limit) { $item = array(); - $submissionURL = self::URI . $figure->find('b u a', 0)->href; + $submissionURL = $figure->find('b u a', 0)->href; $imgURL = 'https:' . $figure->find('b u a img', 0)->src; $item['uri'] = $submissionURL; $item['title'] = html_entity_decode( - $figure->find('figcaption p a[href^=/view]', 0)->title); - $item['author'] = $figure->find('figcaption p a[href^=/user]', 0)->title; + $figure->find('figcaption p a[href*=/view/]', 0)->title); + $item['author'] = $figure->find('figcaption p a[href*=/user/]', 0)->title; if($this->getInput('full') === true) { $submissionHTML = $this->getFASimpleHTMLDOM($submissionURL, $cache); $stats = $submissionHTML->find('.stats-container', 0); - $item['timestamp'] = strtotime($stats->find('.popup_date', 0)->plaintext); + $item['timestamp'] = strtotime($stats->find('.popup_date', 0)->title); $item['enclosures'] = array( - 'https:' . $submissionHTML->find('.actions a[href^=//d.facdn]', 0)->href + $submissionHTML->find('.actions a[href^=https://d.facdn]', 0)->href ); foreach($stats->find('#keywords a') as $keyword) { $item['categories'][] = $keyword->plaintext; @@ -868,7 +875,7 @@ private function itemsFromSubmissionList($html, $limit) { $description = $submissionHTML ->find('.maintable .maintable tr td.alt1', -1); - $this->cleanupHTMLDOM($description); + $this->setReferrerPolicy($description); $description = $description->innertext; $item['content'] = <<find('img') as $img) { /* * Note: Without the no-referrer policy their CDN sometimes denies requests. @@ -900,15 +907,6 @@ private function cleanupHTMLDOM(&$html) { * Alternatively we could not use https for images, but that's not ideal. */ $img->referrerpolicy = 'no-referrer'; - if(preg_match('/^\/\//', $img->src)) { - $img->src = 'https:' . $img->src; - } - } - // Make hrefs absolute - foreach($html->find('*[href]') as $link) { - if(preg_match('/^\/[^\/]/', $link->href)) { - $link->href = self::URI . $link->href; - } } } } From dfba7a863f288bfd3beb4c9d003a5c9337db35a0 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Jun 2019 15:32:06 +0200 Subject: [PATCH 09/10] [FurAffinityBridge] Apply suggested style changes --- bridges/FurAffinityBridge.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index 681ec914acd..c6da9c27ba8 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -625,13 +625,17 @@ public function getName() { . $this->getInput('q'); case 'Browse': return 'Browse'; - case 'Journals': return $this->getInput('username-journals'); + case 'Journals': + return $this->getInput('username-journals'); case 'Single Journal': return 'Journal ' . $this->getInput('journal-id'); - case 'Gallery': return $this->getInput('username-gallery'); - case 'Scraps': return $this->getInput('username-scraps'); - case 'Favorites': return $this->getInput('username-favorites'); + case 'Gallery': + return $this->getInput('username-gallery'); + case 'Scraps': + return $this->getInput('username-scraps'); + case 'Favorites': + return $this->getInput('username-favorites'); case 'Gallery Folder': return $this->getInput('username-folder') . '\'s Folder ' From 256301939ea4b035f07de80be4e40c46546a3954 Mon Sep 17 00:00:00 2001 From: Roliga Date: Mon, 24 Jun 2019 15:35:41 +0200 Subject: [PATCH 10/10] [FurAffinityBridge] Add note about limit = -1 --- bridges/FurAffinityBridge.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bridges/FurAffinityBridge.php b/bridges/FurAffinityBridge.php index c6da9c27ba8..2f78ee4f84c 100644 --- a/bridges/FurAffinityBridge.php +++ b/bridges/FurAffinityBridge.php @@ -805,6 +805,7 @@ private function getFASimpleHTMLDOM($url, $cache = false) { private function itemsFromJournalList($html, $limit) { foreach($html->find('table[id^=jid:]') as $journal) { + # allows limit = -1 to mean 'unlimited' if($limit-- === 0) break; $item = array(); @@ -847,6 +848,7 @@ private function itemsFromSubmissionList($html, $limit) { $cache = ($this->getInput('cache') === true); foreach($html->find('section.gallery figure') as $figure) { + # allows limit = -1 to mean 'unlimited' if($limit-- === 0) break; $item = array();