PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/model/story_preview.php

https://github.com/NeoRazorX/feedstorm
PHP | 396 lines | 361 code | 16 blank | 19 comment | 50 complexity | d4b99ec8e30db37fa127c27125e66fb9 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /*
  3. * This file is part of FeedStorm
  4. * Copyright (C) 2014 Carlos Garcia Gomez neorazorx@gmail.com
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as
  8. * published by the Free Software Foundation, either version 3 of the
  9. * License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. require_once 'model/topic.php';
  20. class story_preview
  21. {
  22. public $filename;
  23. public $link;
  24. public $type;
  25. private $topic;
  26. private $topic_list;
  27. public function __construct()
  28. {
  29. $this->type = FALSE;
  30. $this->topic = new topic();
  31. $this->topic_list = array();
  32. }
  33. public function load($url, $text='')
  34. {
  35. $this->link = FALSE;
  36. $this->type = FALSE;
  37. $links = array($url);
  38. /// extraemos urls del texto
  39. $aux = array();
  40. if( preg_match_all('@((https?://)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@', $text, $aux) )
  41. {
  42. foreach($aux[0] as $a)
  43. $links[] = $a;
  44. }
  45. foreach($links as $link)
  46. {
  47. if( $this->is_valid_image_url($link) )
  48. {
  49. $this->link = $link;
  50. $this->filename = $link;
  51. $this->type = 'image';
  52. break;
  53. }
  54. else if( mb_substr($link, 0, 19) == 'http://i.imgur.com/' )
  55. {
  56. $parts = explode('/', $link);
  57. if( count($parts) >= 4 )
  58. {
  59. $this->filename = $parts[3];
  60. $this->type = 'imgur';
  61. $this->link = $link;
  62. }
  63. break;
  64. }
  65. else if( mb_substr($link, 0, 29) == 'http://www.youtube.com/embed/' )
  66. {
  67. $parts = explode('/', $link);
  68. if( count($parts) >= 5 )
  69. {
  70. $this->filename = $this->clean_youtube_id($parts[4]);
  71. $this->type = 'youtube';
  72. $this->link = 'http://www.youtube.com/embed/'.$this->filename;
  73. }
  74. break;
  75. }
  76. else if( mb_substr($link, 0, 23) == 'http://www.youtube.com/' OR mb_substr($link, 0, 24) == 'https://www.youtube.com/' )
  77. {
  78. $my_array_of_vars = array();
  79. parse_str( parse_url($link, PHP_URL_QUERY), $my_array_of_vars);
  80. if( isset($my_array_of_vars['v']) )
  81. {
  82. $this->filename = $this->clean_youtube_id($my_array_of_vars['v']);
  83. $this->type = 'youtube';
  84. $this->link = 'http://www.youtube.com/embed/'.$this->filename;
  85. break;
  86. }
  87. }
  88. else if( mb_substr($link, 0, 16) == 'http://youtu.be/' )
  89. {
  90. $parts = explode('/', $link);
  91. if( count($parts) >= 4 )
  92. {
  93. $this->filename = $this->clean_youtube_id($parts[3]);
  94. $this->type = 'youtube';
  95. $this->link = 'http://www.youtube.com/embed/'.$this->filename;
  96. }
  97. break;
  98. }
  99. else if( mb_substr($link, 0, 17) == 'http://vimeo.com/' )
  100. {
  101. if( !file_exists('tmp/vimeo') )
  102. mkdir('tmp/vimeo');
  103. $parts = explode('/', $link);
  104. if( count($parts) >= 4 )
  105. {
  106. $video_id = $this->clean_youtube_id($parts[3]);
  107. $this->filename = 'tmp/vimeo/'.str_replace( '/', '_', str_replace( ':', '_', $link) );
  108. if( is_numeric($video_id) )
  109. {
  110. if( !file_exists($this->filename) )
  111. {
  112. try
  113. {
  114. $html = $this->curl_download('http://vimeo.com/api/v2/video/'.$video_id.'.php', FALSE);
  115. if($html)
  116. {
  117. $hash = unserialize($html);
  118. if( isset($hash[0]['thumbnail_medium']) )
  119. {
  120. $this->curl_save($hash[0]['thumbnail_medium'], 'tmp/vimeo/'.$video_id);
  121. $this->type = 'vimeo';
  122. $this->filename = $video_id;
  123. $this->link = 'http://vimeo.com/'.$video_id;
  124. break;
  125. }
  126. }
  127. }
  128. catch(Exception $e)
  129. {
  130. $this->new_error('Imposible obtener los datos del vĂ­deo de vimeo: '.$link."\n".$e);
  131. }
  132. }
  133. else if( filesize($this->filename) > 0 )
  134. {
  135. $this->type = 'vimeo';
  136. $this->filename = $video_id;
  137. $this->link = 'http://vimeo.com/'.$video_id;
  138. break;
  139. }
  140. }
  141. }
  142. }
  143. else if( strpos($link, 'imgur.com/') !== FALSE )
  144. {
  145. if( !file_exists('tmp/imgur2') )
  146. mkdir('tmp/imgur2');
  147. $filename = 'tmp/imgur2/'.str_replace( '/', '_', str_replace( ':', '_', $link) );
  148. if( !file_exists($filename) )
  149. {
  150. $html = $this->curl_download($link);
  151. $urls = array();
  152. if( preg_match_all('#<meta name="twitter:image" content="http://i.imgur.com/(\w*).(\w*)#', $html, $urls) )
  153. {
  154. $this->filename = 'http://i.imgur.com/'.$urls[1][0].'.'.$urls[2][0];
  155. }
  156. else if( preg_match_all('#<meta name="twitter:image0:src" content="http://i.imgur.com/(\w*).(\w*)#', $html, $urls) )
  157. {
  158. $this->filename = 'http://i.imgur.com/'.$urls[1][0].'.'.$urls[2][0];
  159. }
  160. $file = fopen($filename, 'w');
  161. if($file)
  162. {
  163. fwrite($file, $this->filename);
  164. fclose($file);
  165. }
  166. }
  167. else
  168. {
  169. $this->filename = file_get_contents($filename);
  170. }
  171. $parts = explode('/', $this->filename);
  172. if( count($parts) >= 4 )
  173. {
  174. $this->filename = $parts[3];
  175. $this->type = 'imgur';
  176. $this->link = $link;
  177. }
  178. break;
  179. }
  180. else if( strpos($link, 'twitter.com/') !== FALSE )
  181. {
  182. if( !file_exists('tmp/twitter') )
  183. mkdir('tmp/twitter');
  184. $filename = 'tmp/twitter/'.str_replace( '/', '_', str_replace( ':', '_', $link) );
  185. if( !file_exists($filename) )
  186. {
  187. $html = $this->curl_download($link);
  188. if( strpos($html, '<div class="replies-to') !== FALSE )
  189. {
  190. /// cortamos hasta las respuestas
  191. $html = substr($html, 0, strpos($html, '<div class="replies-to'));
  192. }
  193. $urls = array();
  194. if( preg_match_all('#https://pbs.twimg.com/media/([a-zA-Z0-9\-_]*).(\w*)#', $html, $urls) )
  195. {
  196. $this->filename = 'https://pbs.twimg.com/media/'.$urls[1][0].'.'.$urls[2][0];
  197. $this->link = $this->filename;
  198. $this->type = 'image';
  199. }
  200. else if( preg_match_all('#data-expanded-url="https://www.youtube.com/watch\?v=([a-zA-Z0-9\-_]*)#', $html, $urls) )
  201. {
  202. $this->filename = $urls[1][0];
  203. $this->link = 'http://www.youtube.com/embed/'.$this->filename;
  204. $this->type = 'youtube';
  205. }
  206. else if( preg_match_all('#https://pbs.twimg.com/profile_images/(\w*)/(\w*)_bigger.(\w*)#', $html, $urls) )
  207. {
  208. $this->filename = 'https://pbs.twimg.com/profile_images/'.$urls[1][0].'/'.$urls[2][0].'_bigger.'.$urls[3][0];
  209. $this->link = $this->filename;
  210. $this->type = 'image';
  211. }
  212. $file = fopen($filename, 'w');
  213. if($file)
  214. {
  215. fwrite($file, 'filename = "'.$this->filename."\";\n");
  216. fwrite($file, 'link = "'.$this->link."\";\n");
  217. fwrite($file, 'type = "'.$this->type."\";\n");
  218. fclose($file);
  219. }
  220. }
  221. else
  222. {
  223. $aux2 = parse_ini_file($filename);
  224. $this->filename = $aux2['filename'];
  225. $this->link = $aux2['link'];
  226. $this->type = $aux2['type'];
  227. }
  228. break;
  229. }
  230. }
  231. }
  232. public function load_topics($topics)
  233. {
  234. foreach($topics as $tid)
  235. {
  236. $encontrado = FALSE;
  237. foreach($this->topic_list as $topic)
  238. {
  239. if($topic->get_id() == $tid)
  240. {
  241. if($topic->icon != '')
  242. {
  243. $this->load($topic->icon);
  244. }
  245. $encontrado = TRUE;
  246. break;
  247. }
  248. }
  249. if( !$encontrado )
  250. {
  251. $topic = $this->topic->get($tid);
  252. if($topic)
  253. {
  254. $this->topic_list[] = $topic;
  255. if($topic->icon != '')
  256. {
  257. $this->load($topic->icon);
  258. }
  259. }
  260. }
  261. if($this->type)
  262. {
  263. break;
  264. }
  265. }
  266. }
  267. public function min_height()
  268. {
  269. if($this->type == 'imgur')
  270. return 125;
  271. else if($this->type == 'youtube' OR $this->type == 'vimeo')
  272. return 95;
  273. else
  274. return 0;
  275. }
  276. public function min_width()
  277. {
  278. return 0;
  279. }
  280. public function preview()
  281. {
  282. $thumbnail = FALSE;
  283. switch ($this->type)
  284. {
  285. case 'image':
  286. $thumbnail = $this->filename;
  287. break;
  288. case 'imgur':
  289. $parts2 = explode('.', $this->filename);
  290. $thumbnail = 'http://i.imgur.com/'.$parts2[0].'s.'.$parts2[1];
  291. break;
  292. case 'youtube':
  293. $thumbnail = 'http://img.youtube.com/vi/'.$this->filename.'/0.jpg';
  294. break;
  295. case 'vimeo':
  296. $thumbnail = FS_PATH.'tmp/vimeo/'.$this->filename;
  297. break;
  298. }
  299. return $thumbnail;
  300. }
  301. private function clean_youtube_id($yid)
  302. {
  303. $new_yid = '';
  304. $yid = trim($yid);
  305. for($i = 0; $i < mb_strlen($yid); $i++)
  306. {
  307. $aux = mb_substr($yid, $i, 1);
  308. if( preg_match("#[a-zA-Z0-9\-_]#", $aux) )
  309. $new_yid .= $aux;
  310. else
  311. break;
  312. }
  313. return $new_yid;
  314. }
  315. private function is_valid_image_url($url)
  316. {
  317. $status = TRUE;
  318. $extensions = array('.png', '.jpg', 'jpeg', '.gif', 'webp');
  319. if( mb_substr($url, 0, 4) != 'http' )
  320. $status = FALSE;
  321. else if( mb_strlen($url) > 200 )
  322. $status = FALSE;
  323. else if( !in_array( mb_strtolower( mb_substr($url, -4) ), $extensions) )
  324. $status = FALSE;
  325. return $status;
  326. }
  327. public function curl_download($url, $googlebot=TRUE, $timeout=FS_TIMEOUT)
  328. {
  329. $ch0 = curl_init($url);
  330. curl_setopt($ch0, CURLOPT_TIMEOUT, $timeout);
  331. curl_setopt($ch0, CURLOPT_RETURNTRANSFER, true);
  332. curl_setopt($ch0, CURLOPT_FOLLOWLOCATION, true);
  333. if($googlebot)
  334. curl_setopt($ch0, CURLOPT_USERAGENT, 'Googlebot/2.1 (+http://www.google.com/bot.html)');
  335. $html = curl_exec($ch0);
  336. curl_close($ch0);
  337. return $html;
  338. }
  339. public function curl_save($url, $filename, $googlebot=FALSE, $followlocation=FALSE)
  340. {
  341. $ch = curl_init($url);
  342. $fp = fopen($filename, 'wb');
  343. curl_setopt($ch, CURLOPT_FILE, $fp);
  344. curl_setopt($ch, CURLOPT_HEADER, 0);
  345. curl_setopt($ch, CURLOPT_TIMEOUT, FS_TIMEOUT);
  346. if($followlocation)
  347. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  348. if($googlebot)
  349. curl_setopt($ch, CURLOPT_USERAGENT, 'Googlebot/2.1 (+http://www.google.com/bot.html)');
  350. curl_exec($ch);
  351. curl_close($ch);
  352. fclose($fp);
  353. }
  354. }