Completed
Push — master ( 677095...769410 )
by C
04:46
created

Youtubecom::getStreamData()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 40
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 40
ccs 19
cts 19
cp 1
rs 8.8571
cc 2
eloc 24
nc 2
nop 1
crap 2
1
<?php
2
namespace Tartana\Host;
3
use GuzzleHttp\Psr7\Request;
4
use Tartana\Entity\Download;
5
use Tartana\Host\Common\Http;
6
use GuzzleHttp\RequestOptions;
7
8
class Youtubecom extends Http
9
{
10
11 4
	public function fetchDownloadInfo (array $downloads)
12
	{
13 4
		foreach ($downloads as $download)
14
		{
15
			// Connection check
16
			try
17
			{
18 4
				$data = $this->getStreamData($download);
19 3
				if (! empty($data['title']) && empty($download->getFileName()))
20
				{
21 1
					$download->setFileName($this->makeSafe($data['title'] . '.mp4'));
22
				}
23
24 3
				if (key_exists('errorcode', $data) && $data['errorcode'] > 0 && key_exists('reason', $data))
25
				{
26 1
					$download->setMessage($data['reason']);
27 3
					$download->setState(Download::STATE_DOWNLOADING_ERROR);
28
				}
29
			}
30 1
			catch (\Exception $e)
31
			{
32 1
				$this->log('Exception fetching head for connection test: ' . $e->getMessage());
33 1
				$download->setMessage('TARTANA_DOWNLOAD_MESSAGE_INVALID_URL');
34 4
				$download->setState(Download::STATE_DOWNLOADING_ERROR);
35
			}
36
		}
37 4
	}
38
39 3
	protected function getUrlToDownload (Download $download)
40
	{
41 3
		$data = $this->getStreamData($download);
42
43 3
		if (! key_exists('url_encoded_fmt_stream_map', $data))
44
		{
45 1
			return null;
46
		}
47
48 2
		foreach (explode(',', $data['url_encoded_fmt_stream_map']) as $streamData)
49
		{
50 2
			parse_str($streamData, $streamData);
51
52 2
			if (key_exists('url', $streamData))
53
			{
54 1
				$url = urldecode($streamData['url']);
55 1
				$this->log('Youtube real url: ' . $url);
56 2
				return $url;
57
			}
58
		}
59 1
		return null;
60
	}
61
62 7
	private function getStreamData (Download $download)
63
	{
64 7
		if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $download->getLink(),
65
				$match))
66
		{
67
			$headers = [
68
					RequestOptions::HEADERS => [
69 6
							'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20150101 Firefox/44.0 (Chrome)',
70 6
							'Referer' => $download->getLink(),
71 6
							'Accept-Language' => 'en-us,en;q=0.5',
72 6
							'Accept-Encoding' => 'gzip, deflate',
73 6
							'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
74 6
							'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
75 6
							'Connection' => 'close',
76 6
							'Origin' => 'https://www.youtube.com',
77 6
							'Host' => 'www.youtube.com'
78
					]
79
			];
80
			// Getting the link information initializing the cookie
81 6
			$this->getClient()->request('get', $download->getLink() . '&gl=US&hl=en&has_verified=1&bpctr=9999999999',
82
					[
83 6
							RequestOptions::HEADERS => $headers
84
					]);
85
86
			// Fetching the video information
87 6
			$res = $this->getClient()->request('get',
88 6
					'http://www.youtube.com/get_video_info?video_id=' . $match[1] . '&el=info&ps=default&eurl=&gl=US&hl=en',
89
					[
90 6
							RequestOptions::HEADERS => $headers
91
					]);
92
93 5
			parse_str($res->getBody()->getContents(), $videoData);
94 5
			return $videoData;
95
		}
96
97
		return [
98 1
				'title' => '',
99
				'url_encoded_fmt_stream_map' => ''
100
		];
101
	}
102
103
	/**
104
	 *
105
	 * @param string $file
106
	 * @return string
107
	 * @see http://stackoverflow.com/questions/2668854/sanitizing-strings-to-make-them-url-and-filename-safe
108
	 * @see http://stackoverflow.com/a/24812812/356375
109
	 */
110 1
	private function makeSafe ($file)
111
	{
112
		// Remove any trailing dots, as those aren't ever valid file names.
113 1
		$file = rtrim($file, '.');
114
115
		$regex = array(
116 1
				'#(\.){2,}#',
117
				'#[^A-Za-z0-9\.\_\- ]#',
118
				'#^\.#'
119
		);
120
121 1
		return trim(preg_replace($regex, '', $file));
122
	}
123
}
124