From c6ec5c45d154c7df16dc6006ce319e68c5d2a86f Mon Sep 17 00:00:00 2001 From: pauder Date: Tue, 29 Oct 2013 09:26:48 +0100 Subject: [PATCH 1/7] Add Instagram bridge --- bridges/InstagramBridge.php | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 bridges/InstagramBridge.php diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php new file mode 100644 index 0000000..dfe6e85 --- /dev/null +++ b/bridges/InstagramBridge.php @@ -0,0 +1,56 @@ +request = $param['u']; + $text = file_get_contents('http://instagram.com/'.urlencode($this->request)) or $this->returnError('Could not request Instagram.', 404); + } + else { + $this->returnError('You must specify a Instagram username (?u=...).', 400); + } + + + // "standard_resolution":{"url":"http:\/\/distilleryimage6.s3.amazonaws.com\/5ff1829036bc11e3b6c622000a1f92d1_7.jpg","width":612,"height":612} + + if (preg_match_all('/"standard_resolution":\{"url":"(http:[^"]+)","width":(\d+),"height":(\d+)\}/', $text, $matches)) + { + foreach($matches[0] as $key => $dummy) + { + $imageurl = stripslashes($matches[1][$key]); + $width = (int) $matches[2][$key]; + $height = (int) $matches[3][$key]; + + + $item = new \Item(); + $item->uri = $imageurl; + $item->content = ''; + $item->title = basename($imageurl); + $this->items[] = $item; + } + } + } + + public function getName(){ + return (!empty($this->request) ? $this->request .' - ' : '') .'Instagram Bridge'; + } + + public function getURI(){ + return 'http://instagram.com/'; + } + + public function getCacheDuration(){ + return 21600; // 6 hours + } +} From 40f6e51b067bbe1f3761906f2a747e8cc8448de2 Mon Sep 17 00:00:00 2001 From: pauder Date: Tue, 29 Oct 2013 10:40:31 +0100 Subject: [PATCH 2/7] add date --- bridges/InstagramBridge.php | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php index dfe6e85..3adc71b 100644 --- a/bridges/InstagramBridge.php +++ b/bridges/InstagramBridge.php @@ -21,22 +21,36 @@ class InstagramBridge extends BridgeAbstract{ $this->returnError('You must specify a Instagram username (?u=...).', 400); } + + + $image = '"(\w+)":\{"url":"(http:[^"]+)","width":(\d+),"height":(\d+)\}'; - // "standard_resolution":{"url":"http:\/\/distilleryimage6.s3.amazonaws.com\/5ff1829036bc11e3b6c622000a1f92d1_7.jpg","width":612,"height":612} - - if (preg_match_all('/"standard_resolution":\{"url":"(http:[^"]+)","width":(\d+),"height":(\d+)\}/', $text, $matches)) + if (preg_match_all('/"created_time":"(\d+)"\s*,\s*"images":\{'.$image.','.$image.','.$image.'\}/', $text, $matches)) { foreach($matches[0] as $key => $dummy) { - $imageurl = stripslashes($matches[1][$key]); - $width = (int) $matches[2][$key]; - $height = (int) $matches[3][$key]; + $timestamp = (int) $matches[1][$key]; + $images = array(); + + $pos = 2; + for($i = 0; $i < 3; $i++) + { + $imagetype = $matches[$pos++][$key]; + + $images[$imagetype] = array( + 'url' => stripslashes($matches[$pos++][$key]), + 'width' => (int) $matches[$pos++][$key], + 'height' => (int) $matches[$pos++][$key] + ); + + } $item = new \Item(); - $item->uri = $imageurl; - $item->content = ''; - $item->title = basename($imageurl); + $item->uri = $images['standard_resolution']['url']; + $item->content = ''; + $item->title = basename($images['standard_resolution']['url']); + $item->timestamp = $timestamp; $this->items[] = $item; } } From 3822e77561e45c63a86027d606b33e3fc2017b94 Mon Sep 17 00:00:00 2001 From: pauder Date: Tue, 29 Oct 2013 15:59:22 +0100 Subject: [PATCH 3/7] more informations with a json parser --- bridges/InstagramBridge.php | 74 ++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php index 3adc71b..362add9 100644 --- a/bridges/InstagramBridge.php +++ b/bridges/InstagramBridge.php @@ -15,44 +15,57 @@ class InstagramBridge extends BridgeAbstract{ $html = ''; if (isset($param['u'])) { /* user timeline mode */ $this->request = $param['u']; - $text = file_get_contents('http://instagram.com/'.urlencode($this->request)) or $this->returnError('Could not request Instagram.', 404); + $html = file_get_html('http://instagram.com/'.urlencode($this->request)) or $this->returnError('Could not request Instagram.', 404); } else { $this->returnError('You must specify a Instagram username (?u=...).', 400); } - - - $image = '"(\w+)":\{"url":"(http:[^"]+)","width":(\d+),"height":(\d+)\}'; + $innertext = null; - if (preg_match_all('/"created_time":"(\d+)"\s*,\s*"images":\{'.$image.','.$image.','.$image.'\}/', $text, $matches)) + foreach($html->find('script') as $script) { - foreach($matches[0] as $key => $dummy) - { - $timestamp = (int) $matches[1][$key]; - $images = array(); - - $pos = 2; - for($i = 0; $i < 3; $i++) - { - $imagetype = $matches[$pos++][$key]; - - $images[$imagetype] = array( - 'url' => stripslashes($matches[$pos++][$key]), - 'width' => (int) $matches[$pos++][$key], - 'height' => (int) $matches[$pos++][$key] - ); - - } - - - $item = new \Item(); - $item->uri = $images['standard_resolution']['url']; - $item->content = ''; - $item->title = basename($images['standard_resolution']['url']); - $item->timestamp = $timestamp; - $this->items[] = $item; + if ('' === $script->innertext) { + continue; } + + $pos = strpos($script->innertext, 'window._jscalls'); + if (false === $pos) + { + continue; + } + + $innertext = $script->innertext; + + break; + } + + + $json = trim(substr($innertext, $pos+15), ' =;'); + $pos = strpos($json, '}]],'); + $json = substr($json, $pos+4, -4); + $data = json_decode($json); + + $userMedia = $data[2][0]->props->userMedia; + + + foreach($userMedia as $media) + { + $image = $media->images->standard_resolution; + + + $item = new \Item(); + $item->uri = $media->link; + $item->content = ''; + if (isset($media->caption)) + { + $item->title = $media->caption->text; + } else { + $item->title = basename($image->url); + } + $item->timestamp = $media->created_time; + $this->items[] = $item; + } } @@ -65,6 +78,7 @@ class InstagramBridge extends BridgeAbstract{ } public function getCacheDuration(){ + return 0; return 21600; // 6 hours } } From d6693f43465615e244d055f80e9ed3a1e264eec9 Mon Sep 17 00:00:00 2001 From: pauder Date: Thu, 30 Jan 2014 11:55:39 +0100 Subject: [PATCH 4/7] Fix bug because of a modification of instagram source page json content --- bridges/InstagramBridge.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php index 362add9..ce91b0f 100644 --- a/bridges/InstagramBridge.php +++ b/bridges/InstagramBridge.php @@ -29,31 +29,28 @@ class InstagramBridge extends BridgeAbstract{ continue; } - $pos = strpos($script->innertext, 'window._jscalls'); - if (false === $pos) + $pos = strpos(trim($script->innertext), 'window._sharedData'); + if (0 !== $pos) { continue; } $innertext = $script->innertext; - break; } - $json = trim(substr($innertext, $pos+15), ' =;'); - $pos = strpos($json, '}]],'); - $json = substr($json, $pos+4, -4); + + $json = trim(substr($innertext, $pos+18), ' =;'); $data = json_decode($json); - - $userMedia = $data[2][0]->props->userMedia; + + $userMedia = $data->entry_data->UserProfile[0]->userMedia; foreach($userMedia as $media) { $image = $media->images->standard_resolution; - - + $item = new \Item(); $item->uri = $media->link; $item->content = ''; From e3d502768162bf0986455a6a1eff34760865e69b Mon Sep 17 00:00:00 2001 From: pauder Date: Thu, 30 Jan 2014 12:02:56 +0100 Subject: [PATCH 5/7] cache --- bridges/InstagramBridge.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php index ce91b0f..8a5575e 100644 --- a/bridges/InstagramBridge.php +++ b/bridges/InstagramBridge.php @@ -75,7 +75,6 @@ class InstagramBridge extends BridgeAbstract{ } public function getCacheDuration(){ - return 0; - return 21600; // 6 hours + return 3600; } } From 19f806acd5800628c57b5f48eaf4958f25154852 Mon Sep 17 00:00:00 2001 From: pauder Date: Thu, 30 Jan 2014 14:55:35 +0100 Subject: [PATCH 6/7] Add a pinterest bridge --- bridges/PinterestBridge.php | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 bridges/PinterestBridge.php diff --git a/bridges/PinterestBridge.php b/bridges/PinterestBridge.php new file mode 100644 index 0000000..8bb813a --- /dev/null +++ b/bridges/PinterestBridge.php @@ -0,0 +1,61 @@ +username = $param['u']; + $this->board = $param['b']; + $html = file_get_html($this->getURI().'/'.urlencode($this->username).'/'.urlencode($this->board)) or $this->returnError('Could not request Pinterest.', 404); + } + else { + $this->returnError('You must specify a Pinterest username and a board name (?u=...&b=...).', 400); + } + + $innertext = null; + + foreach($html->find('div.pinWrapper') as $div) + { + $a = $div->find('a.pinImageWrapper',0); + + $img = $a->find('img', 0); + + $item = new \Item(); + $item->uri = $this->getURI().$a->getAttribute('href'); + $item->content = ''; + + $credit = $div->find('a.creditItem',0); + + $item->content .= '
'.$credit->innertext; + + $item->title = basename($img->getAttribute('alt')); + + //$item->timestamp = $media->created_time; + $this->items[] = $item; + + } + } + + public function getName(){ + return $this->username .' - '. $this->board; + } + + public function getURI(){ + return 'http://www.pinterest.com'; + } + + public function getCacheDuration(){ + return 0; + } +} From 4a63fed224375e930c9d1745623662b8edfe15ac Mon Sep 17 00:00:00 2001 From: pauder Date: Thu, 30 Jan 2014 15:25:25 +0100 Subject: [PATCH 7/7] search query --- bridges/PinterestBridge.php | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/bridges/PinterestBridge.php b/bridges/PinterestBridge.php index 8bb813a..8c24ecd 100644 --- a/bridges/PinterestBridge.php +++ b/bridges/PinterestBridge.php @@ -6,11 +6,13 @@ * @name Pinterest Bridge * @description Returns the newest images on a board * @use1(u="username",b="board") + * @use2(q="keyword") */ class PinterestBridge extends BridgeAbstract{ private $username; private $board; + private $query; public function collectData(array $param){ $html = ''; @@ -18,12 +20,16 @@ class PinterestBridge extends BridgeAbstract{ $this->username = $param['u']; $this->board = $param['b']; $html = file_get_html($this->getURI().'/'.urlencode($this->username).'/'.urlencode($this->board)) or $this->returnError('Could not request Pinterest.', 404); + } else if (isset($param['q'])) + { + $this->query = $param['q']; + $html = file_get_html($this->getURI().'/search/?q='.urlencode($this->query)) or $this->returnError('Could not request Pinterest.', 404); } + else { $this->returnError('You must specify a Pinterest username and a board name (?u=...&b=...).', 400); } - - $innertext = null; + foreach($html->find('div.pinWrapper') as $div) { @@ -35,9 +41,24 @@ class PinterestBridge extends BridgeAbstract{ $item->uri = $this->getURI().$a->getAttribute('href'); $item->content = ''; - $credit = $div->find('a.creditItem',0); - $item->content .= '
'.$credit->innertext; + if (isset($this->query)) + { + $avatar = $div->find('img.creditImg', 0); + $username = $div->find('span.creditName', 0); + $board = $div->find('span.creditTitle', 0); + + $item->username =$username->innertext; + $item->fullname = $board->innertext; + $item->avatar = $avatar->getAttribute('src'); + + $item->content .= '
'.$item->username.''; + $item->content .= '
'.$item->fullname; + } else { + + $credit = $div->find('a.creditItem',0); + $item->content .= '
'.$credit->innertext; + } $item->title = basename($img->getAttribute('alt')); @@ -48,7 +69,13 @@ class PinterestBridge extends BridgeAbstract{ } public function getName(){ - return $this->username .' - '. $this->board; + + if (isset($this->query)) + { + return $this->query .' - Pinterest'; + } else { + return $this->username .' - '. $this->board.' - Pinterest'; + } } public function getURI(){