/unsplash-dl.php

https://bitbucket.org/mcdado/unsplashfetch · PHP · 171 lines · 148 code · 22 blank · 1 comment · 18 complexity · 77b7510c1a010cd6128e236c424d4696 MD5 · raw file

  1. #!/usr/local/bin/php
  2. <?php
  3. class UnsplashFetch {
  4. private $version,
  5. $user_agent,
  6. $location,
  7. $feed,
  8. $logging,
  9. $log_file,
  10. $log_handle,
  11. $client,
  12. $downloads;
  13. function __construct($url, $picture_path, $log = false, $log_path = null) {
  14. $this->version = '0.2';
  15. $this->user_agent = 'UnsplashFetch/' . $this->version . ' (https://github.com/mcdado/unsplash-dl)';
  16. $this->client = new http\Client;
  17. $this->feed = $url;
  18. $this->logging = $log;
  19. $this->location = $picture_path;
  20. if (!file_exists($picture_path)) {
  21. mkdir($picture_path, 0777, true);
  22. }
  23. if ($log_path == null) {
  24. $this->log_file = null;
  25. } else {
  26. $this->log_file = $log_path;
  27. $this->log_handle = fopen($this->log_file, 'a') or die("Cannot open log file");
  28. }
  29. }
  30. function terminate() {
  31. $this->sendLog("Unsplashed.");
  32. if ($this->log_handle) {
  33. fclose($this->log_handle);
  34. }
  35. }
  36. private function sendLog($message) {
  37. if ($this->logging === true) {
  38. if ($this->log_file == null) {
  39. echo $message . PHP_EOL;
  40. } else {
  41. fwrite($this->log_handle, '[' . date('Y-m-d H:i:s') . ']' . ' ' . $message . PHP_EOL);
  42. }
  43. }
  44. }
  45. public function init() {
  46. $this->sendLog("Unsplash-dl started.");
  47. $request = new http\Client\Request('GET', $this->feed, array('User-Agent' => $this->user_agent));
  48. $request->addQuery(new http\QueryString("type=photo"));
  49. if ( file_exists($this->location . '/unsplash.rss') ) {
  50. $mod_date = filemtime($this->location . '/unsplash.rss');
  51. $request->setHeader('If-Modified-Since', gmdate('D, d M Y H:i:s \G\M\T', $mod_date)); // RFC 2616 formatted date
  52. }
  53. try {
  54. $this->client->enqueue($request)->send();
  55. $response = $this->client->getResponse($request);
  56. if ($response->getResponseCode() == 200) {
  57. $body = $response->getBody();
  58. file_put_contents($this->location . '/unsplash.rss', $body);
  59. $parsed_body = simplexml_load_string($body);
  60. unset($body);
  61. foreach ($parsed_body->posts->post as $entry) {
  62. $extracted_link = "";
  63. $extracted_link = (string)$entry->{'photo-link-url'};
  64. if ($extracted_link != "") {
  65. $redirection = $this->getRedirectUrl($extracted_link);
  66. $clean_link = $redirection ? $redirection : $extracted_link;
  67. $this->downloads[] = $clean_link;
  68. }
  69. }
  70. unset($parsed_body);
  71. } else {
  72. $this->sendLog("Feed Response Code: " . $response->getResponseCode());
  73. return;
  74. }
  75. } catch (http\Exception $ex) {
  76. $this->sendLog("Feed Raised Exception: " . $ex->message);
  77. return;
  78. }
  79. $this->sendLog("Beginning to fetch links.");
  80. $this->fetchLinks();
  81. }
  82. private function getRedirectUrl($url) {
  83. $this->sendLog("Getting redirected for " . $url);
  84. stream_context_set_default(array(
  85. 'http' => array(
  86. 'method' => 'HEAD'
  87. )
  88. ));
  89. try {
  90. $headers = get_headers($url, 1);
  91. if ($headers !== false && isset($headers['Location'])) {
  92. $this->sendLog("`-> Redirected to " . $headers['Location']);
  93. return $headers['Location'];
  94. }
  95. } catch (Exception $ex) {
  96. $this->sendLog("Couldn't get redirected URL: " . $url);
  97. return false;
  98. }
  99. $this->sendLog("`-> No redirection.");
  100. return false;
  101. }
  102. private function fetchLinks() {
  103. foreach ($this->downloads as $k => $link) {
  104. // Normalizing the URL, updating it in place.
  105. $link = str_replace(' ', '%20', $link);
  106. $this->downloads[$k] = $link;
  107. $parsed_link = parse_url($link);
  108. if ($parsed_link == false) {
  109. unset($this->downloads[$k]);
  110. break;
  111. }
  112. // Check if the file already exists
  113. $file_name = basename($parsed_link['path']);
  114. if (file_exists($this->location . DIRECTORY_SEPARATOR . $file_name)) {
  115. unset($this->downloads[$k]);
  116. }
  117. }
  118. foreach ($this->downloads as $d_link) {
  119. $d_request = new http\Client\Request('GET', $d_link, array('User-Agent' => $this->user_agent));
  120. try {
  121. $this->client->enqueue($d_request)->send();
  122. $d_name = basename($d_request->getRequestUrl());
  123. $d_response = $this->client->getResponse();
  124. if ($d_response->getResponseCode() == 200) {
  125. file_put_contents($this->location . DIRECTORY_SEPARATOR . $d_name, $d_response->getBody());
  126. $this->sendLog("Succesfully downloaded " . $d_name);
  127. } else {
  128. $this->sendLog($file_name . " reported a status code: " . $d_response->getResponseCode());
  129. }
  130. } catch (http\Exception $ex) {
  131. $this->sendLog("Raised Exception: " . $ex->message);
  132. }
  133. }
  134. }
  135. }
  136. $unsplash = new UnsplashFetch( 'http://unsplash.com/api/read',
  137. getenv("HOME") . '/Pictures/Unsplash',
  138. true,
  139. getenv("HOME") . '/Library/Logs/com.mcdado.unsplash.log');
  140. $unsplash->init();
  141. $unsplash->terminate();