Skip to content

Commit aac00f2

Browse files
committed
add a cli file download tool class from inhere/console
1 parent 6e43289 commit aac00f2

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed

src/Download.php

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: inhere
5+
* Date: 2017-03-31
6+
* Time: 19:08
7+
*/
8+
9+
namespace Toolkit\Cli;
10+
11+
/**
12+
* Class Download
13+
* @package Toolkit\Cli
14+
*/
15+
final class Download
16+
{
17+
const PROGRESS_TEXT = 'text';
18+
const PROGRESS_BAR = 'bar';
19+
20+
/** @var int */
21+
private $fileSize;
22+
23+
/** @var int */
24+
private $showType;
25+
26+
/** @var string */
27+
public $url;
28+
29+
/** @var string */
30+
private $saveAs;
31+
32+
/**
33+
* eg: php down.php <http://example.com/file> <localFile>
34+
* @param string $url
35+
* @param string $saveAs
36+
* @param string $type
37+
* @return Download
38+
* @throws \RuntimeException
39+
*/
40+
public static function file(string $url, string $saveAs, string $type = self::PROGRESS_TEXT): Download
41+
{
42+
$d = new self($url, $saveAs, $type);
43+
44+
return $d->start();
45+
}
46+
47+
/**
48+
* Download constructor.
49+
* @param string $url
50+
* @param string $saveAs
51+
* @param string $type
52+
*/
53+
public function __construct(string $url, string $saveAs, $type = self::PROGRESS_TEXT)
54+
{
55+
$this->url = $url;
56+
$this->saveAs = $saveAs;
57+
$this->showType = $type === self::PROGRESS_BAR ? self::PROGRESS_BAR : self::PROGRESS_TEXT;
58+
}
59+
60+
/**
61+
* start download
62+
* @return $this
63+
* @throws \RuntimeException
64+
*/
65+
public function start(): self
66+
{
67+
if (!$this->url || !$this->saveAs) {
68+
throw new \RuntimeException("Please the property 'url' and 'saveAs'.", - 1);
69+
}
70+
71+
$ctx = stream_context_create();
72+
73+
// register stream notification callback
74+
stream_context_set_params($ctx, [
75+
'notification' => [$this, 'progressShow']
76+
]);
77+
78+
Cli::write("Download: {$this->url}\nSave As: {$this->saveAs}\n");
79+
80+
$fp = fopen($this->url, 'rb', false, $ctx);
81+
82+
if (\is_resource($fp) && file_put_contents($this->saveAs, $fp)) {
83+
Cli::write("\nDone!");
84+
} else {
85+
$err = \error_get_last();
86+
Cli::stderr("\nErr.rrr..orr...\n {$err['message']}\n", true, -1);
87+
}
88+
89+
$this->fileSize = null;
90+
91+
return $this;
92+
}
93+
94+
/**
95+
* @param int $notifyCode stream notify code
96+
* @param int $severity severity code
97+
* @param string $message Message text
98+
* @param int $messageCode Message code
99+
* @param int $transferredBytes Have been transferred bytes
100+
* @param int $maxBytes Target max length bytes
101+
*/
102+
public function progressShow($notifyCode, $severity, $message, $messageCode, $transferredBytes, $maxBytes)
103+
{
104+
$msg = '';
105+
106+
switch ($notifyCode) {
107+
case STREAM_NOTIFY_RESOLVE:
108+
case STREAM_NOTIFY_AUTH_REQUIRED:
109+
case STREAM_NOTIFY_COMPLETED:
110+
case STREAM_NOTIFY_FAILURE:
111+
case STREAM_NOTIFY_AUTH_RESULT:
112+
$msg = "NOTIFY: $message(NO: $messageCode, Severity: $severity)";
113+
/* Ignore */
114+
break;
115+
116+
case STREAM_NOTIFY_REDIRECTED:
117+
$msg = "Being redirected to: $message";
118+
break;
119+
120+
case STREAM_NOTIFY_CONNECT:
121+
$msg = 'Connected ...';
122+
break;
123+
124+
case STREAM_NOTIFY_FILE_SIZE_IS:
125+
$this->fileSize = $maxBytes;
126+
$fileSize = sprintf('%2d', $maxBytes / 1024);
127+
$msg = "Got the file size: <info>$fileSize</info> kb";
128+
break;
129+
130+
case STREAM_NOTIFY_MIME_TYPE_IS:
131+
$msg = "Found the mime-type: <info>$message</info>";
132+
break;
133+
134+
case STREAM_NOTIFY_PROGRESS:
135+
if ($transferredBytes > 0) {
136+
$this->showProgressByType($transferredBytes);
137+
}
138+
139+
break;
140+
}
141+
142+
$msg && Cli::write($msg);
143+
}
144+
145+
/**
146+
* @param $transferredBytes
147+
* @return string
148+
*/
149+
public function showProgressByType($transferredBytes): string
150+
{
151+
if ($transferredBytes <= 0) {
152+
return '';
153+
}
154+
155+
$tfKb = $transferredBytes / 1024;
156+
157+
if ($this->showType === self::PROGRESS_BAR) {
158+
$size = $this->fileSize;
159+
160+
if ($size === null) {
161+
printf("\rUnknown file size... %2d kb done..", $tfKb);
162+
} else {
163+
$length = ceil(($transferredBytes / $size) * 100); // ■ =
164+
printf("\r[%-100s] %d%% (%2d/%2d kb)", str_repeat('=', $length) . '>', $length, $tfKb, $size / 1024);
165+
}
166+
} else {
167+
printf("\r\rMade some progress, downloaded %2d kb so far", $tfKb);
168+
//$msg = "Made some progress, downloaded <info>$transferredBytes</info> so far";
169+
}
170+
171+
return '';
172+
}
173+
174+
/**
175+
* @return int
176+
*/
177+
public function getShowType(): int
178+
{
179+
return $this->showType;
180+
}
181+
182+
/**
183+
* @param int $showType
184+
*/
185+
public function setShowType(int $showType)
186+
{
187+
$this->showType = $showType;
188+
}
189+
190+
/**
191+
* @return string
192+
*/
193+
public function getUrl(): string
194+
{
195+
return $this->url;
196+
}
197+
198+
/**
199+
* @param string $url
200+
*/
201+
public function setUrl(string $url)
202+
{
203+
$this->url = $url;
204+
}
205+
206+
/**
207+
* @return string
208+
*/
209+
public function getSaveAs(): string
210+
{
211+
return $this->saveAs;
212+
}
213+
214+
/**
215+
* @param string $saveAs
216+
*/
217+
public function setSaveAs(string $saveAs)
218+
{
219+
$this->saveAs = $saveAs;
220+
}
221+
222+
/*
223+
progressBar() OUT:
224+
Connected...
225+
Mime-type: text/html; charset=utf-8
226+
Being redirected to: http://no2.php.net/distributions/php-5.2.5.tar.bz2
227+
Connected...
228+
FileSize: 7773024
229+
Mime-type: application/octet-stream
230+
[========================================> ] 40% (3076/7590 kb)
231+
232+
progress Text OUT:
233+
Connected...
234+
Found the mime-type: text/html; charset=utf-8
235+
Being redirected to: http://no.php.net/contact
236+
Connected...
237+
Got the fileSize: 0
238+
Found the mime-type: text/html; charset=utf-8
239+
Being redirected to: http://no.php.net/contact.php
240+
Connected...
241+
Got the fileSize: 4589
242+
Found the mime-type: text/html;charset=utf-8
243+
Made some progress, downloaded 0 so far
244+
Made some progress, downloaded 0 so far
245+
Made some progress, downloaded 0 so far
246+
Made some progress, downloaded 1440 so far
247+
... ...
248+
*/
249+
250+
251+
}

0 commit comments

Comments
 (0)