├── .gitignore
├── Readme.md
├── backend
├── __init__.py
├── ffmpeg.py
├── test.py
├── xxx.txt
└── zhihu.py
├── dist
├── index.html
└── static
│ ├── css
│ ├── app.309ab8fba68d313f651c75bc7d633112.css
│ └── app.309ab8fba68d313f651c75bc7d633112.css.map
│ └── js
│ ├── 0.689b9a587c6153676efc.js
│ ├── 0.689b9a587c6153676efc.js.map
│ ├── 1.3cb2992300207dee1ecc.js
│ ├── 1.3cb2992300207dee1ecc.js.map
│ ├── 2.83ac2feabc358f1e7df7.js
│ ├── 2.83ac2feabc358f1e7df7.js.map
│ ├── 3.1e1621ff1dbe6bca1bb4.js
│ ├── 3.1e1621ff1dbe6bca1bb4.js.map
│ ├── app.cde59b67f82f386b8ea5.js
│ ├── app.cde59b67f82f386b8ea5.js.map
│ ├── manifest.7a65f38077c246a526c7.js
│ ├── manifest.7a65f38077c246a526c7.js.map
│ ├── vendor.710eb2f37d735bead177.js
│ └── vendor.710eb2f37d735bead177.js.map
├── frontend
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
│ ├── build.js
│ ├── check-versions.js
│ ├── logo.png
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ └── webpack.prod.conf.js
├── config
│ ├── dev.env.js
│ ├── index.js
│ └── prod.env.js
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── logo.png
│ │ └── qrcode.png
│ ├── components
│ │ ├── About.vue
│ │ ├── HelloWorld.vue
│ │ ├── Home.vue
│ │ └── NotFound.vue
│ ├── main.js
│ └── router
│ │ └── index.js
└── static
│ └── .gitkeep
├── npm-debug.log
├── run.py
└── test.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.mp4
3 | .idea
4 | .vscode
5 | __pycache__
6 | node_modules
7 | package-lock.json
8 | frontend/node_modules
9 | backend/venv
10 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | https://codeburst.io/full-stack-single-page-application-with-vue-js-and-flask-b1e036315532
2 |
--------------------------------------------------------------------------------
/backend/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youfulife/downloader/72963c68ed95dee5f2a754eb7d7360ae57e23de4/backend/__init__.py
--------------------------------------------------------------------------------
/backend/ffmpeg.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import json
3 |
4 |
5 | def exec_output(command):
6 | """
7 | 执行ffmpeg命令并返回所有输出,如果执行失败,抛出FfmpegException
8 | :param command: ffmpeg命令
9 | :return: ffmpeg标准输出
10 | """
11 | try:
12 | process = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
13 | return process
14 | except subprocess.CalledProcessError as err:
15 | raise FfmpegException(err.returncode, err.cmd, err.output)
16 |
17 |
18 | class FfmpegException(Exception):
19 | """
20 | 使用ffmpeg报错时抛出
21 | """
22 |
23 | def __init__(self, returncode, cmd, output=None):
24 | self.returncode = returncode
25 | self.cmd = cmd
26 | self.output = output
27 |
28 | def __str__(self):
29 | return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
30 |
31 |
32 | def duration_seconds(url):
33 | result = exec_output("ffprobe -v quiet -print_format json -show_format {}".format(url))
34 | video_info = json.loads(str(result.decode('utf8')))
35 | duration_seconds = video_info['format'].get("duration", None)
36 | if duration_seconds is not None:
37 | return round(float(duration_seconds))
38 | else:
39 | return 0
40 |
41 |
42 | if __name__ == '__main__':
43 | url = "https://vdn.vzuu.com/Act-ss-m3u8-ld/48abe817b57f459f8644cadb2f8c8ee7/917d8956-59b4-11e8-888f-0242ac112a17None.m3u8?auth_key=1528856898-0-0-6b355374a747cf586f9829125a79ae0f&expiration=1528856898&disable_local_cache=0"
44 | duration_seconds(url)
45 |
46 |
--------------------------------------------------------------------------------
/backend/test.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import time
3 | import sys
4 | import os
5 | import redis
6 | import uuid
7 |
8 | r = redis.Redis(host='localhost', port=6379, decode_responses=True)
9 |
10 | basedir = os.path.abspath(os.path.dirname(__file__))
11 | # ret_code = subprocess.check_call(['ffmpeg', '-v', 'quiet', '-progress', '/dev/stdout', '-i', m3u8_url, prefix+filename])
12 | url = "https://vdn.vzuu.com/Act-ss-m3u8-ld/48abe817b57f459f8644cadb2f8c8ee7/917d8956-59b4-11e8-888f-0242ac112a17None.m3u8?auth_key=1528903286-0-0-c147fde519b86eddef4502b98c22a373&expiration=1528903286&disable_local_cache=0"
13 | # output = basedir + "/test.mp4"
14 | output="{}.mp4".format(uuid.uuid4())
15 | print(output)
16 | cmd = "ffmpeg -v quiet -progress /dev/stdout -i '{input}' {output}".format(input=url, output=output)
17 |
18 | # cmd = "cat xxx.txt"
19 | print(cmd)
20 | child1 = subprocess.Popen(cmd, cwd=basedir, shell=True, stdout=subprocess.PIPE)
21 |
22 | cmd2 = "grep --line-buffered -e out_time_ms -e progress"
23 | print(cmd2)
24 | child2 = subprocess.Popen(cmd2, shell=True, stdin=child1.stdout, stdout=subprocess.PIPE)
25 | for line in iter(child2.stdout.readline, b''):
26 | tmp = line.decode('utf-8').strip().split('=')
27 |
28 | if tmp[0] == 'out_time_ms':
29 | out_time_ms = tmp[1]
30 | print(out_time_ms)
31 | r.set("x", out_time_ms)
32 | else:
33 | if tmp[1] == 'end':
34 | r.delete("x")
35 | print("download complete")
36 | # time.sleep(1)
--------------------------------------------------------------------------------
/backend/xxx.txt:
--------------------------------------------------------------------------------
1 | frame=52
2 | fps=0.0
3 | stream_0_0_q=28.0
4 | bitrate= 0.2kbits/s
5 | total_size=48
6 | out_time_ms=1973696
7 | out_time=00:00:01.973696
8 | dup_frames=1
9 | drop_frames=0
10 | speed=2.71x
11 | progress=continue
12 | frame=95
13 | fps=53.2
14 | stream_0_0_q=28.0
15 | bitrate= 0.1kbits/s
16 | total_size=48
17 | out_time_ms=3924172
18 | out_time=00:00:03.924172
19 | dup_frames=1
20 | drop_frames=0
21 | speed= 2.2x
22 | progress=continue
23 | frame=168
24 | fps=73.4
25 | stream_0_0_q=28.0
26 | bitrate= 0.1kbits/s
27 | total_size=48
28 | out_time_ms=6617687
29 | out_time=00:00:06.617687
30 | dup_frames=1
31 | drop_frames=0
32 | speed=2.89x
33 | progress=continue
34 | frame=196
35 | fps=68.6
36 | stream_0_0_q=28.0
37 | bitrate= 0.0kbits/s
38 | total_size=48
39 | out_time_ms=7941224
40 | out_time=00:00:07.941224
41 | dup_frames=1
42 | drop_frames=0
43 | speed=2.78x
44 | progress=continue
45 | frame=245
46 | fps=71.6
47 | stream_0_0_q=28.0
48 | bitrate= 211.1kbits/s
49 | total_size=262192
50 | out_time_ms=9938141
51 | out_time=00:00:09.938141
52 | dup_frames=1
53 | drop_frames=0
54 | speed=2.91x
55 | progress=continue
56 | frame=295
57 | fps=73.3
58 | stream_0_0_q=28.0
59 | bitrate= 175.7kbits/s
60 | total_size=262192
61 | out_time_ms=11935057
62 | out_time=00:00:11.935057
63 | dup_frames=1
64 | drop_frames=0
65 | speed=2.96x
66 | progress=continue
67 | frame=345
68 | fps=74.3
69 | stream_0_0_q=28.0
70 | bitrate= 150.6kbits/s
71 | total_size=262192
72 | out_time_ms=13931973
73 | out_time=00:00:13.931973
74 | dup_frames=1
75 | drop_frames=0
76 | speed= 3x
77 | progress=continue
78 | frame=395
79 | fps=75.7
80 | stream_0_0_q=28.0
81 | bitrate= 263.3kbits/s
82 | total_size=524336
83 | out_time_ms=15928889
84 | out_time=00:00:15.928889
85 | dup_frames=1
86 | drop_frames=0
87 | speed=3.05x
88 | progress=continue
89 | frame=445
90 | fps=77.4
91 | stream_0_0_q=28.0
92 | bitrate= 234.0kbits/s
93 | total_size=524336
94 | out_time_ms=17925805
95 | out_time=00:00:17.925805
96 | dup_frames=1
97 | drop_frames=0
98 | speed=3.12x
99 | progress=continue
100 | frame=497
101 | fps=79.4
102 | stream_0_0_q=28.0
103 | bitrate= 315.8kbits/s
104 | total_size=786480
105 | out_time_ms=19922721
106 | out_time=00:00:19.922721
107 | dup_frames=1
108 | drop_frames=0
109 | speed=3.18x
110 | progress=continue
111 | frame=577
112 | fps=84.9
113 | stream_0_0_q=28.0
114 | bitrate= 273.7kbits/s
115 | total_size=786480
116 | out_time_ms=22987755
117 | out_time=00:00:22.987755
118 | dup_frames=1
119 | drop_frames=0
120 | speed=3.38x
121 | progress=continue
122 | frame=629
123 | fps=86.2
124 | stream_0_0_q=28.0
125 | bitrate= 251.8kbits/s
126 | total_size=786480
127 | out_time_ms=24984671
128 | out_time=00:00:24.984671
129 | dup_frames=1
130 | drop_frames=0
131 | speed=3.43x
132 | progress=continue
133 | frame=695
134 | fps=86.9
135 | stream_0_0_q=28.0
136 | bitrate= 300.3kbits/s
137 | total_size=1048624
138 | out_time_ms=27933605
139 | out_time=00:00:27.933605
140 | dup_frames=1
141 | drop_frames=0
142 | speed=3.49x
143 | progress=continue
144 | frame=745
145 | fps=87.5
146 | stream_0_0_q=28.0
147 | bitrate= 280.3kbits/s
148 | total_size=1048624
149 | out_time_ms=29930522
150 | out_time=00:00:29.930522
151 | dup_frames=1
152 | drop_frames=0
153 | speed=3.51x
154 | progress=continue
155 | frame=797
156 | fps=88.0
157 | stream_0_0_q=28.0
158 | bitrate= 328.4kbits/s
159 | total_size=1310768
160 | out_time_ms=31927438
161 | out_time=00:00:31.927438
162 | dup_frames=1
163 | drop_frames=0
164 | speed=3.52x
165 | progress=continue
166 | frame=847
167 | fps=87.9
168 | stream_0_0_q=28.0
169 | bitrate= 309.1kbits/s
170 | total_size=1310768
171 | out_time_ms=33924354
172 | out_time=00:00:33.924354
173 | dup_frames=1
174 | drop_frames=0
175 | speed=3.52x
176 | progress=continue
177 | frame=895
178 | fps=87.3
179 | stream_0_0_q=28.0
180 | bitrate= 350.3kbits/s
181 | total_size=1572912
182 | out_time_ms=35921270
183 | out_time=00:00:35.921270
184 | dup_frames=1
185 | drop_frames=0
186 | speed= 3.5x
187 | progress=continue
188 | frame=945
189 | fps=85.0
190 | stream_0_0_q=28.0
191 | bitrate= 331.7kbits/s
192 | total_size=1572912
193 | out_time_ms=37941406
194 | out_time=00:00:37.941406
195 | dup_frames=1
196 | drop_frames=0
197 | speed=3.41x
198 | progress=continue
199 | frame=998
200 | fps=85.8
201 | stream_0_0_q=28.0
202 | bitrate= 315.1kbits/s
203 | total_size=1572912
204 | out_time_ms=39938322
205 | out_time=00:00:39.938322
206 | dup_frames=1
207 | drop_frames=0
208 | speed=3.43x
209 | progress=continue
210 | frame=1046
211 | fps=85.9
212 | stream_0_0_q=28.0
213 | bitrate= 350.1kbits/s
214 | total_size=1835056
215 | out_time_ms=41935238
216 | out_time=00:00:41.935238
217 | dup_frames=1
218 | drop_frames=0
219 | speed=3.44x
220 | progress=continue
221 | frame=1095
222 | fps=84.6
223 | stream_0_0_q=28.0
224 | bitrate= 334.2kbits/s
225 | total_size=1835056
226 | out_time_ms=43932154
227 | out_time=00:00:43.932154
228 | dup_frames=1
229 | drop_frames=0
230 | speed= 3.4x
231 | progress=continue
232 | frame=1145
233 | fps=81.8
234 | stream_0_0_q=28.0
235 | bitrate= 365.3kbits/s
236 | total_size=2097200
237 | out_time_ms=45929070
238 | out_time=00:00:45.929070
239 | dup_frames=1
240 | drop_frames=0
241 | speed=3.28x
242 | progress=continue
243 | frame=1195
244 | fps=82.2
245 | stream_0_0_q=28.0
246 | bitrate= 350.1kbits/s
247 | total_size=2097200
248 | out_time_ms=47925986
249 | out_time=00:00:47.925986
250 | dup_frames=1
251 | drop_frames=0
252 | speed= 3.3x
253 | progress=continue
254 | frame=1245
255 | fps=81.8
256 | stream_0_0_q=28.0
257 | bitrate= 336.1kbits/s
258 | total_size=2097200
259 | out_time_ms=49922902
260 | out_time=00:00:49.922902
261 | dup_frames=1
262 | drop_frames=0
263 | speed=3.28x
264 | progress=continue
265 | frame=1295
266 | fps=82.3
267 | stream_0_0_q=28.0
268 | bitrate= 363.4kbits/s
269 | total_size=2359344
270 | out_time_ms=51943039
271 | out_time=00:00:51.943039
272 | dup_frames=1
273 | drop_frames=0
274 | speed= 3.3x
275 | progress=continue
276 | frame=1345
277 | fps=82.7
278 | stream_0_0_q=28.0
279 | bitrate= 349.9kbits/s
280 | total_size=2359344
281 | out_time_ms=53939955
282 | out_time=00:00:53.939955
283 | dup_frames=1
284 | drop_frames=0
285 | speed=3.32x
286 | progress=continue
287 | frame=1395
288 | fps=82.7
289 | stream_0_0_q=28.0
290 | bitrate= 374.9kbits/s
291 | total_size=2621488
292 | out_time_ms=55936871
293 | out_time=00:00:55.936871
294 | dup_frames=1
295 | drop_frames=0
296 | speed=3.32x
297 | progress=continue
298 | frame=1445
299 | fps=82.7
300 | stream_0_0_q=28.0
301 | bitrate= 362.0kbits/s
302 | total_size=2621488
303 | out_time_ms=57933787
304 | out_time=00:00:57.933787
305 | dup_frames=1
306 | drop_frames=0
307 | speed=3.31x
308 | progress=continue
309 | frame=1502
310 | fps=83.3
311 | stream_0_0_q=28.0
312 | bitrate= 384.6kbits/s
313 | total_size=2883632
314 | out_time_ms=59977143
315 | out_time=00:00:59.977143
316 | dup_frames=1
317 | drop_frames=0
318 | speed=3.33x
319 | progress=continue
320 | frame=1551
321 | fps=83.5
322 | stream_0_0_q=28.0
323 | bitrate= 372.5kbits/s
324 | total_size=2883632
325 | out_time_ms=61927619
326 | out_time=00:01:01.927619
327 | dup_frames=1
328 | drop_frames=0
329 | speed=3.33x
330 | progress=continue
331 | frame=1595
332 | fps=83.6
333 | stream_0_0_q=28.0
334 | bitrate= 360.9kbits/s
335 | total_size=2883632
336 | out_time_ms=63924535
337 | out_time=00:01:03.924535
338 | dup_frames=1
339 | drop_frames=0
340 | speed=3.35x
341 | progress=continue
342 | frame=1648
343 | fps=84.2
344 | stream_0_0_q=28.0
345 | bitrate= 381.8kbits/s
346 | total_size=3145776
347 | out_time_ms=65921451
348 | out_time=00:01:05.921451
349 | dup_frames=1
350 | drop_frames=0
351 | speed=3.37x
352 | progress=continue
353 | frame=1720
354 | fps=85.6
355 | stream_0_0_q=28.0
356 | bitrate= 366.5kbits/s
357 | total_size=3145776
358 | out_time_ms=68661406
359 | out_time=00:01:08.661406
360 | dup_frames=1
361 | drop_frames=0
362 | speed=3.42x
363 | progress=continue
364 | frame=1769
365 | fps=85.9
366 | stream_0_0_q=28.0
367 | bitrate= 386.0kbits/s
368 | total_size=3407920
369 | out_time_ms=70635102
370 | out_time=00:01:10.635102
371 | dup_frames=1
372 | drop_frames=0
373 | speed=3.43x
374 | progress=continue
375 | frame=1845
376 | fps=86.6
377 | stream_0_0_q=28.0
378 | bitrate= 368.8kbits/s
379 | total_size=3407920
380 | out_time_ms=73932336
381 | out_time=00:01:13.932336
382 | dup_frames=1
383 | drop_frames=0
384 | speed=3.47x
385 | progress=continue
386 | frame=1903
387 | fps=87.3
388 | stream_0_0_q=28.0
389 | bitrate= 385.9kbits/s
390 | total_size=3670064
391 | out_time_ms=76091791
392 | out_time=00:01:16.091791
393 | dup_frames=1
394 | drop_frames=0
395 | speed=3.49x
396 | progress=continue
397 | frame=1973
398 | fps=88.4
399 | stream_0_0_q=28.0
400 | bitrate= 371.8kbits/s
401 | total_size=3670064
402 | out_time_ms=78971066
403 | out_time=00:01:18.971066
404 | dup_frames=1
405 | drop_frames=0
406 | speed=3.54x
407 | progress=continue
408 | frame=2023
409 | fps=88.6
410 | stream_0_0_q=28.0
411 | bitrate= 388.4kbits/s
412 | total_size=3932208
413 | out_time_ms=80991202
414 | out_time=00:01:20.991202
415 | dup_frames=1
416 | drop_frames=0
417 | speed=3.55x
418 | progress=continue
419 | frame=2079
420 | fps=89.0
421 | stream_0_0_q=28.0
422 | bitrate= 378.7kbits/s
423 | total_size=3932208
424 | out_time_ms=83057778
425 | out_time=00:01:23.057778
426 | dup_frames=1
427 | drop_frames=0
428 | speed=3.56x
429 | progress=continue
430 | frame=2111
431 | fps=88.5
432 | stream_0_0_q=28.0
433 | bitrate= 373.1kbits/s
434 | total_size=3932208
435 | out_time_ms=84311655
436 | out_time=00:01:24.311655
437 | dup_frames=1
438 | drop_frames=0
439 | speed=3.53x
440 | progress=continue
441 | frame=2169
442 | fps=89.1
443 | stream_0_0_q=28.0
444 | bitrate= 387.3kbits/s
445 | total_size=4194352
446 | out_time_ms=86633651
447 | out_time=00:01:26.633651
448 | dup_frames=1
449 | drop_frames=0
450 | speed=3.56x
451 | progress=continue
452 | frame=2195
453 | fps=87.0
454 | stream_0_0_q=28.0
455 | bitrate= 381.6kbits/s
456 | total_size=4194352
457 | out_time_ms=87933968
458 | out_time=00:01:27.933968
459 | dup_frames=1
460 | drop_frames=0
461 | speed=3.49x
462 | progress=continue
463 | frame=2245
464 | fps=85.9
465 | stream_0_0_q=28.0
466 | bitrate= 373.1kbits/s
467 | total_size=4194352
468 | out_time_ms=89930884
469 | out_time=00:01:29.930884
470 | dup_frames=1
471 | drop_frames=0
472 | speed=3.44x
473 | progress=continue
474 | frame=2304
475 | fps=86.5
476 | stream_0_0_q=28.0
477 | bitrate= 386.4kbits/s
478 | total_size=4456496
479 | out_time_ms=92276100
480 | out_time=00:01:32.276100
481 | dup_frames=1
482 | drop_frames=0
483 | speed=3.47x
484 | progress=continue
485 | frame=2358
486 | fps=86.9
487 | stream_0_0_q=28.0
488 | bitrate= 378.2kbits/s
489 | total_size=4456496
490 | out_time_ms=94273016
491 | out_time=00:01:34.273016
492 | dup_frames=1
493 | drop_frames=0
494 | speed=3.48x
495 | progress=continue
496 | frame=2411
497 | fps=87.3
498 | stream_0_0_q=28.0
499 | bitrate= 370.3kbits/s
500 | total_size=4456496
501 | out_time_ms=96269932
502 | out_time=00:01:36.269932
503 | dup_frames=1
504 | drop_frames=0
505 | speed=3.49x
506 | progress=continue
507 | frame=2479
508 | fps=88.1
509 | stream_0_0_q=28.0
510 | bitrate= 380.7kbits/s
511 | total_size=4718640
512 | out_time_ms=99149206
513 | out_time=00:01:39.149206
514 | dup_frames=1
515 | drop_frames=0
516 | speed=3.53x
517 | progress=continue
518 | frame=2512
519 | fps=87.7
520 | stream_0_0_q=28.0
521 | bitrate= 376.2kbits/s
522 | total_size=4718640
523 | out_time_ms=100333424
524 | out_time=00:01:40.333424
525 | dup_frames=1
526 | drop_frames=0
527 | speed= 3.5x
528 | progress=continue
529 | frame=2559
530 | fps=87.6
531 | stream_0_0_q=25.0
532 | bitrate= 389.6kbits/s
533 | total_size=4980784
534 | out_time_ms=102283900
535 | out_time=00:01:42.283900
536 | dup_frames=1
537 | drop_frames=0
538 | speed= 3.5x
539 | progress=continue
540 | frame=2602
541 | fps=87.6
542 | stream_0_0_q=28.0
543 | bitrate= 383.4kbits/s
544 | total_size=4980784
545 | out_time_ms=103932517
546 | out_time=00:01:43.932517
547 | dup_frames=1
548 | drop_frames=0
549 | speed= 3.5x
550 | progress=continue
551 | frame=2670
552 | fps=88.1
553 | stream_0_0_q=28.0
554 | bitrate= 373.5kbits/s
555 | total_size=4980784
556 | out_time_ms=106695692
557 | out_time=00:01:46.695692
558 | dup_frames=1
559 | drop_frames=0
560 | speed=3.52x
561 | progress=continue
562 | frame=2736
563 | fps=88.8
564 | stream_0_0_q=28.0
565 | bitrate= 383.5kbits/s
566 | total_size=5242928
567 | out_time_ms=109365986
568 | out_time=00:01:49.365986
569 | dup_frames=1
570 | drop_frames=0
571 | speed=3.55x
572 | progress=continue
573 | frame=2791
574 | fps=89.0
575 | stream_0_0_q=28.0
576 | bitrate= 375.6kbits/s
577 | total_size=5242928
578 | out_time_ms=111664762
579 | out_time=00:01:51.664762
580 | dup_frames=1
581 | drop_frames=0
582 | speed=3.56x
583 | progress=continue
584 | frame=2795
585 | fps=87.7
586 | stream_0_0_q=28.0
587 | bitrate= 374.8kbits/s
588 | total_size=5242928
589 | out_time_ms=111920181
590 | out_time=00:01:51.920181
591 | dup_frames=1
592 | drop_frames=0
593 | speed=3.51x
594 | progress=continue
595 | frame=2824
596 | fps=87.1
597 | stream_0_0_q=28.0
598 | bitrate= 371.1kbits/s
599 | total_size=5242928
600 | out_time_ms=113011519
601 | out_time=00:01:53.011519
602 | dup_frames=1
603 | drop_frames=0
604 | speed=3.49x
605 | progress=continue
606 | frame=2895
607 | fps=87.4
608 | stream_0_0_q=28.0
609 | bitrate= 379.9kbits/s
610 | total_size=5505072
611 | out_time_ms=115937234
612 | out_time=00:01:55.937234
613 | dup_frames=1
614 | drop_frames=0
615 | speed= 3.5x
616 | progress=continue
617 | frame=2962
618 | fps=88.1
619 | stream_0_0_q=28.0
620 | bitrate= 372.1kbits/s
621 | total_size=5505072
622 | out_time_ms=118352109
623 | out_time=00:01:58.352109
624 | dup_frames=1
625 | drop_frames=0
626 | speed=3.52x
627 | progress=continue
628 | frame=3029
629 | fps=88.7
630 | stream_0_0_q=28.0
631 | bitrate= 381.4kbits/s
632 | total_size=5767216
633 | out_time_ms=120975964
634 | out_time=00:02:00.975964
635 | dup_frames=1
636 | drop_frames=0
637 | speed=3.54x
638 | progress=continue
639 | frame=3080
640 | fps=88.9
641 | stream_0_0_q=28.0
642 | bitrate= 374.8kbits/s
643 | total_size=5767216
644 | out_time_ms=123088980
645 | out_time=00:02:03.088980
646 | dup_frames=1
647 | drop_frames=0
648 | speed=3.55x
649 | progress=continue
650 | frame=3145
651 | fps=89.0
652 | stream_0_0_q=28.0
653 | bitrate= 383.1kbits/s
654 | total_size=6029360
655 | out_time_ms=125921814
656 | out_time=00:02:05.921814
657 | dup_frames=1
658 | drop_frames=0
659 | speed=3.56x
660 | progress=continue
661 | frame=3196
662 | fps=89.1
663 | stream_0_0_q=28.0
664 | bitrate= 377.0kbits/s
665 | total_size=6029360
666 | out_time_ms=127941950
667 | out_time=00:02:07.941950
668 | dup_frames=1
669 | drop_frames=0
670 | speed=3.57x
671 | progress=continue
672 | frame=3259
673 | fps=89.6
674 | stream_0_0_q=28.0
675 | bitrate= 370.2kbits/s
676 | total_size=6029360
677 | out_time_ms=130287166
678 | out_time=00:02:10.287166
679 | dup_frames=1
680 | drop_frames=0
681 | speed=3.58x
682 | progress=continue
683 | frame=3345
684 | fps=90.0
685 | stream_0_0_q=28.0
686 | bitrate= 375.8kbits/s
687 | total_size=6291504
688 | out_time_ms=133932698
689 | out_time=00:02:13.932698
690 | dup_frames=1
691 | drop_frames=0
692 | speed= 3.6x
693 | progress=continue
694 | frame=3402
695 | fps=90.2
696 | stream_0_0_q=28.0
697 | bitrate= 370.3kbits/s
698 | total_size=6291504
699 | out_time_ms=135929615
700 | out_time=00:02:15.929615
701 | dup_frames=1
702 | drop_frames=0
703 | speed= 3.6x
704 | progress=continue
705 | frame=3460
706 | fps=90.3
707 | stream_0_0_q=28.0
708 | bitrate= 379.2kbits/s
709 | total_size=6553648
710 | out_time_ms=138274830
711 | out_time=00:02:18.274830
712 | dup_frames=1
713 | drop_frames=0
714 | speed=3.61x
715 | progress=continue
716 | frame=3526
717 | fps=90.8
718 | stream_0_0_q=28.0
719 | bitrate= 371.9kbits/s
720 | total_size=6553648
721 | out_time_ms=140991565
722 | out_time=00:02:20.991565
723 | dup_frames=1
724 | drop_frames=0
725 | speed=3.63x
726 | progress=continue
727 | frame=3587
728 | fps=91.2
729 | stream_0_0_q=28.0
730 | bitrate= 380.4kbits/s
731 | total_size=6815792
732 | out_time_ms=143336780
733 | out_time=00:02:23.336780
734 | dup_frames=1
735 | drop_frames=0
736 | speed=3.65x
737 | progress=continue
738 | frame=3612
739 | fps=90.7
740 | stream_0_0_q=28.0
741 | bitrate= 377.8kbits/s
742 | total_size=6815792
743 | out_time_ms=144312018
744 | out_time=00:02:24.312018
745 | dup_frames=1
746 | drop_frames=0
747 | speed=3.62x
748 | progress=continue
749 | frame=3650
750 | fps=90.5
751 | stream_0_0_q=28.0
752 | bitrate= 373.6kbits/s
753 | total_size=6815792
754 | out_time_ms=145937415
755 | out_time=00:02:25.937415
756 | dup_frames=1
757 | drop_frames=0
758 | speed=3.62x
759 | progress=continue
760 | frame=3696
761 | fps=90.4
762 | stream_0_0_q=28.0
763 | bitrate= 368.6kbits/s
764 | total_size=6815792
765 | out_time_ms=147934331
766 | out_time=00:02:27.934331
767 | dup_frames=1
768 | drop_frames=0
769 | speed=3.62x
770 | progress=continue
771 | frame=3745
772 | fps=90.1
773 | stream_0_0_q=28.0
774 | bitrate= 377.7kbits/s
775 | total_size=7077936
776 | out_time_ms=149931247
777 | out_time=00:02:29.931247
778 | dup_frames=1
779 | drop_frames=0
780 | speed=3.61x
781 | progress=continue
782 | frame=3795
783 | fps=90.1
784 | stream_0_0_q=28.0
785 | bitrate= 372.7kbits/s
786 | total_size=7077936
787 | out_time_ms=151928163
788 | out_time=00:02:31.928163
789 | dup_frames=1
790 | drop_frames=0
791 | speed=3.61x
792 | progress=continue
793 | frame=3845
794 | fps=90.2
795 | stream_0_0_q=28.0
796 | bitrate= 367.9kbits/s
797 | total_size=7077936
798 | out_time_ms=153925079
799 | out_time=00:02:33.925079
800 | dup_frames=1
801 | drop_frames=0
802 | speed=3.61x
803 | progress=continue
804 | frame=3895
805 | fps=90.3
806 | stream_0_0_q=28.0
807 | bitrate= 363.2kbits/s
808 | total_size=7077936
809 | out_time_ms=155921995
810 | out_time=00:02:35.921995
811 | dup_frames=1
812 | drop_frames=0
813 | speed=3.61x
814 | progress=continue
815 | frame=3946
816 | fps=90.3
817 | stream_0_0_q=28.0
818 | bitrate= 371.8kbits/s
819 | total_size=7340080
820 | out_time_ms=157942132
821 | out_time=00:02:37.942132
822 | dup_frames=1
823 | drop_frames=0
824 | speed=3.61x
825 | progress=continue
826 | frame=3995
827 | fps=90.3
828 | stream_0_0_q=28.0
829 | bitrate= 367.1kbits/s
830 | total_size=7340080
831 | out_time_ms=159939048
832 | out_time=00:02:39.939048
833 | dup_frames=1
834 | drop_frames=0
835 | speed=3.61x
836 | progress=continue
837 | frame=4045
838 | fps=90.3
839 | stream_0_0_q=28.0
840 | bitrate= 362.6kbits/s
841 | total_size=7340080
842 | out_time_ms=161935964
843 | out_time=00:02:41.935964
844 | dup_frames=1
845 | drop_frames=0
846 | speed=3.62x
847 | progress=continue
848 | frame=4097
849 | fps=90.4
850 | stream_0_0_q=28.0
851 | bitrate= 371.0kbits/s
852 | total_size=7602224
853 | out_time_ms=163932880
854 | out_time=00:02:43.932880
855 | dup_frames=1
856 | drop_frames=0
857 | speed=3.62x
858 | progress=continue
859 | frame=4185
860 | fps=91.4
861 | stream_0_0_q=28.0
862 | bitrate= 376.0kbits/s
863 | total_size=7864368
864 | out_time_ms=167322993
865 | out_time=00:02:47.322993
866 | dup_frames=1
867 | drop_frames=0
868 | speed=3.65x
869 | progress=continue
870 | frame=4245
871 | fps=90.5
872 | stream_0_0_q=28.0
873 | bitrate= 370.3kbits/s
874 | total_size=7864368
875 | out_time_ms=169923628
876 | out_time=00:02:49.923628
877 | dup_frames=1
878 | drop_frames=0
879 | speed=3.62x
880 | progress=continue
881 | frame=4295
882 | fps=89.7
883 | stream_0_0_q=28.0
884 | bitrate= 378.2kbits/s
885 | total_size=8126512
886 | out_time_ms=171920544
887 | out_time=00:02:51.920544
888 | dup_frames=1
889 | drop_frames=0
890 | speed=3.59x
891 | progress=continue
892 | frame=4395
893 | fps=90.8
894 | stream_0_0_q=28.0
895 | bitrate= 369.5kbits/s
896 | total_size=8126512
897 | out_time_ms=175937619
898 | out_time=00:02:55.937619
899 | dup_frames=1
900 | drop_frames=0
901 | speed=3.63x
902 | progress=continue
903 | frame=4416
904 | fps=91.1
905 | stream_0_0_q=-1.0
906 | bitrate= 383.2kbits/s
907 | total_size=8459400
908 | out_time_ms=176610975
909 | out_time=00:02:56.610975
910 | dup_frames=1
911 | drop_frames=0
912 | speed=3.64x
913 | progress=end
914 | ['980499386203275264']
915 | download https://vdn.vzuu.com/Act-ss-m3u8-ld/48abe817b57f459f8644cadb2f8c8ee7/917d8956-59b4-11e8-888f-0242ac112a17None.m3u8?auth_key=1528778023-0-0-6768d80b7f1ce40b7e64343490cca015&expiration=1528778023&disable_local_cache=0
916 |
--------------------------------------------------------------------------------
/backend/zhihu.py:
--------------------------------------------------------------------------------
1 | import re
2 | import uuid
3 | import subprocess
4 | import json
5 | import redis
6 | import threading
7 | import requests
8 | import os
9 | import sys
10 | import hashlib
11 |
12 | file_dir = os.path.dirname(__file__)
13 | sys.path.append(file_dir)
14 | import ffmpeg
15 |
16 | r = redis.Redis(host='localhost', port=6379, decode_responses=True)
17 |
18 | basedir = os.path.abspath(os.path.dirname(__file__))
19 |
20 |
21 | HEADERS = {
22 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
23 | }
24 | # 支持是 'ld' 'sd' 'hd' 分别是低清、中清、高清
25 | QUALITY = 'ld'
26 |
27 |
28 | def get_video_ids_from_url(url):
29 | """
30 | 回答或者文章的 url
31 | """
32 | r = requests.get(url, headers=HEADERS)
33 | r.encoding='utf-8'
34 | html = r.text
35 | # print(html)
36 | video_ids = re.findall(r'data-lens-id="(\d+)"', html)
37 | print("video_ids: ", video_ids)
38 | if video_ids:
39 | return set([int(video_id) for video_id in video_ids])
40 | return []
41 |
42 |
43 | def yield_video_m3u8_url_from_video_ids(video_ids):
44 | for video_id in video_ids:
45 | headers = {}
46 | headers['Referer'] = 'https://v.vzuu.com/video/{}'.format(video_id)
47 | headers['Origin'] = 'https://v.vzuu.com'
48 | headers['Host'] = 'lens.zhihu.com'
49 | headers['Content-Type'] = 'application/json'
50 | headers['Authorization'] = 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20'
51 |
52 | api_video_url = 'https://lens.zhihu.com/api/videos/{}'.format(int(video_id))
53 |
54 | r = requests.get(api_video_url, headers={**HEADERS, **headers})
55 | # print(json.dumps(dict(r.request.headers), indent=2, ensure_ascii=False))
56 | # print(r.text.encode('utf-8').decode('unicode_escape'))
57 | playlist = r.json()['playlist']
58 | m3u8_url = playlist[QUALITY]['play_url']
59 | yield video_id, m3u8_url
60 |
61 |
62 | def progress(m3u8_url, directory, filename):
63 | # '/path/to/dist/static/video/zhihu/xxx-yyy.mp4'
64 | prefix = directory + '/dist/'
65 | key = hashlib.md5(filename.encode('utf-8')).hexdigest()
66 | cmd = "ffmpeg -v quiet -progress /dev/stdout -i '{input}' {output}".format(input=m3u8_url, output=prefix+filename)
67 | # cmd = "cat xxx.txt"
68 | print(cmd)
69 | child1 = subprocess.Popen(cmd, cwd=basedir, shell=True, stdout=subprocess.PIPE)
70 | # https://stackoverflow.com/questions/7161821/how-to-grep-a-continuous-stream
71 | cmd2 = "grep --line-buffered -e out_time_ms -e progress"
72 | child2 = subprocess.Popen(cmd2, shell=True, stdin=child1.stdout, stdout=subprocess.PIPE)
73 | for line in iter(child2.stdout.readline, b''):
74 | tmp = line.decode('utf-8').strip().split('=')
75 |
76 | if tmp[0] == 'out_time_ms':
77 | out_time_ms = tmp[1]
78 | # print(out_time_ms)
79 | r.set(key, out_time_ms)
80 | else:
81 | if tmp[1] == 'end':
82 | r.delete(key)
83 | print("download complete")
84 |
85 |
86 | def download(url, directory):
87 | video_ids = get_video_ids_from_url(url)
88 | m3u8_tuples = list(yield_video_m3u8_url_from_video_ids(video_ids))
89 | rets = []
90 |
91 | for idx, m3u8_url in m3u8_tuples:
92 | filename = 'static/video/zhihu/{}.mp4'.format(uuid.uuid4())
93 | print('download {}'.format(m3u8_url))
94 | duration = ffmpeg.duration_seconds(m3u8_url)
95 | threading.Thread(target=progress, args=(m3u8_url, directory, filename,)).start()
96 | # ret_code = subprocess.check_call(['ffmpeg', '-v', 'quiet', '-progress', '/dev/stdout', '-i', m3u8_url, prefix+filename])
97 | if duration != 0:
98 | ret = {
99 | 'status': 'success',
100 | 'video': filename,
101 | 'duration': duration,
102 | "message": "正在下载"
103 | }
104 | else:
105 | ret = {
106 | 'status': 'error',
107 | 'duration': 0,
108 | "message": "下载失败,请稍后再试"
109 | }
110 | rets.append(ret.copy())
111 | else:
112 | return rets
113 |
114 |
115 | if __name__ == '__main__':
116 | # 贴上你需要下载的 回答或者文章的链接
117 | seed = 'https://www.zhihu.com/question/277411517/answer/394112534'
118 | download(seed, '..')
119 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
极客生活-知乎视频下载
--------------------------------------------------------------------------------
/dist/static/js/0.689b9a587c6153676efc.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([0],{"/bQp":function(t,e){t.exports={}},"21It":function(t,e,n){"use strict";var r=n("FtD3");t.exports=function(t,e,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?e(r("Request failed with status code "+n.status,n.config,null,n.request,n)):t(n)}},"3fs2":function(t,e,n){var r=n("RY/4"),o=n("dSzd")("iterator"),i=n("/bQp");t.exports=n("FeBl").getIteratorMethod=function(t){if(void 0!=t)return t[o]||t["@@iterator"]||i[r(t)]}},"5VQ+":function(t,e,n){"use strict";var r=n("cGG2");t.exports=function(t,e){r.forEach(t,function(n,r){r!==e&&r.toUpperCase()===e.toUpperCase()&&(t[e]=n,delete t[r])})}},"5zde":function(t,e,n){n("zQR9"),n("qyJz"),t.exports=n("FeBl").Array.from},"7GwW":function(t,e,n){"use strict";var r=n("cGG2"),o=n("21It"),i=n("DQCr"),s=n("oJlt"),u=n("GHBc"),a=n("FtD3"),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n("thJu");t.exports=function(t){return new Promise(function(e,f){var l=t.data,d=t.headers;r.isFormData(l)&&delete d["Content-Type"];var p=new XMLHttpRequest,h="onreadystatechange",v=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in p||u(t.url)||(p=new window.XDomainRequest,h="onload",v=!0,p.onprogress=function(){},p.ontimeout=function(){}),t.auth){var m=t.auth.username||"",y=t.auth.password||"";d.Authorization="Basic "+c(m+":"+y)}if(p.open(t.method.toUpperCase(),i(t.url,t.params,t.paramsSerializer),!0),p.timeout=t.timeout,p[h]=function(){if(p&&(4===p.readyState||v)&&(0!==p.status||p.responseURL&&0===p.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in p?s(p.getAllResponseHeaders()):null,r={data:t.responseType&&"text"!==t.responseType?p.response:p.responseText,status:1223===p.status?204:p.status,statusText:1223===p.status?"No Content":p.statusText,headers:n,config:t,request:p};o(e,f,r),p=null}},p.onerror=function(){f(a("Network Error",t,null,p)),p=null},p.ontimeout=function(){f(a("timeout of "+t.timeout+"ms exceeded",t,"ECONNABORTED",p)),p=null},r.isStandardBrowserEnv()){var g=n("p1b6"),w=(t.withCredentials||u(t.url))&&t.xsrfCookieName?g.read(t.xsrfCookieName):void 0;w&&(d[t.xsrfHeaderName]=w)}if("setRequestHeader"in p&&r.forEach(d,function(t,e){void 0===l&&"content-type"===e.toLowerCase()?delete d[e]:p.setRequestHeader(e,t)}),t.withCredentials&&(p.withCredentials=!0),t.responseType)try{p.responseType=t.responseType}catch(e){if("json"!==t.responseType)throw e}"function"==typeof t.onDownloadProgress&&p.addEventListener("progress",t.onDownloadProgress),"function"==typeof t.onUploadProgress&&p.upload&&p.upload.addEventListener("progress",t.onUploadProgress),t.cancelToken&&t.cancelToken.promise.then(function(t){p&&(p.abort(),f(t),p=null)}),void 0===l&&(l=null),p.send(l)})}},"880/":function(t,e,n){t.exports=n("hJx8")},"94VQ":function(t,e,n){"use strict";var r=n("Yobk"),o=n("X8DO"),i=n("e6n0"),s={};n("hJx8")(s,n("dSzd")("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(s,{next:o(1,n)}),i(t,e+" Iterator")}},DQCr:function(t,e,n){"use strict";var r=n("cGG2");function o(t){return encodeURIComponent(t).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}t.exports=function(t,e,n){if(!e)return t;var i;if(n)i=n(e);else if(r.isURLSearchParams(e))i=e.toString();else{var s=[];r.forEach(e,function(t,e){null!==t&&void 0!==t&&(r.isArray(t)?e+="[]":t=[t],r.forEach(t,function(t){r.isDate(t)?t=t.toISOString():r.isObject(t)&&(t=JSON.stringify(t)),s.push(o(e)+"="+o(t))}))}),i=s.join("&")}return i&&(t+=(-1===t.indexOf("?")?"?":"&")+i),t}},FtD3:function(t,e,n){"use strict";var r=n("t8qj");t.exports=function(t,e,n,o,i){var s=new Error(t);return r(s,e,n,o,i)}},GHBc:function(t,e,n){"use strict";var r=n("cGG2");t.exports=r.isStandardBrowserEnv()?function(){var t,e=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function o(t){var r=t;return e&&(n.setAttribute("href",r),r=n.href),n.setAttribute("href",r),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return t=o(window.location.href),function(e){var n=r.isString(e)?o(e):e;return n.protocol===t.protocol&&n.host===t.host}}():function(){return!0}},Gu7T:function(t,e,n){"use strict";e.__esModule=!0;var r,o=n("c/Tr"),i=(r=o)&&r.__esModule?r:{default:r};e.default=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e=200&&t<300}};a.headers={common:{Accept:"application/json, text/plain, */*"}},r.forEach(["delete","get","head"],function(t){a.headers[t]={}}),r.forEach(["post","put","patch"],function(t){a.headers[t]=r.merge(i)}),t.exports=a}).call(e,n("W2nU"))},Mhyx:function(t,e,n){var r=n("/bQp"),o=n("dSzd")("iterator"),i=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||i[o]===t)}},PzxK:function(t,e,n){var r=n("D2L2"),o=n("sB3e"),i=n("ax3d")("IE_PROTO"),s=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=o(t),r(t,i)?t[i]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?s:null}},RPLV:function(t,e,n){var r=n("7KvD").document;t.exports=r&&r.documentElement},"RY/4":function(t,e,n){var r=n("R9M2"),o=n("dSzd")("toStringTag"),i="Arguments"==r(function(){return arguments}());t.exports=function(t){var e,n,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=Object(t),o))?n:i?r(e):"Object"==(s=r(e))&&"function"==typeof e.callee?"Arguments":s}},Re3r:function(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}
2 | /*!
3 | * Determine if an object is a Buffer
4 | *
5 | * @author Feross Aboukhadijeh
6 | * @license MIT
7 | */
8 | t.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}},TNV1:function(t,e,n){"use strict";var r=n("cGG2");t.exports=function(t,e,n){return r.forEach(n,function(n){t=n(t,e)}),t}},W2nU:function(t,e){var n,r,o=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function u(t){if(n===setTimeout)return setTimeout(t,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(t){n=i}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(t){r=s}}();var a,c=[],f=!1,l=-1;function d(){f&&a&&(f=!1,a.length?c=a.concat(c):l=-1,c.length&&p())}function p(){if(!f){var t=u(d);f=!0;for(var e=c.length;e;){for(a=c,c=[];++l1)for(var n=1;ndocument.F=Object<\/script>"),t.close(),a=t.F;r--;)delete a.prototype[i[r]];return a()};t.exports=Object.create||function(t,e){var n;return null!==t?(u.prototype=r(t),n=new u,u.prototype=null,n[s]=t):n=a(),void 0===e?n:o(n,e)}},"c/Tr":function(t,e,n){t.exports={default:n("5zde"),__esModule:!0}},cGG2:function(t,e,n){"use strict";var r=n("JP+z"),o=n("Re3r"),i=Object.prototype.toString;function s(t){return"[object Array]"===i.call(t)}function u(t){return null!==t&&"object"==typeof t}function a(t){return"[object Function]"===i.call(t)}function c(t,e){if(null!==t&&void 0!==t)if("object"!=typeof t&&(t=[t]),s(t))for(var n=0,r=t.length;n=c?t?"":void 0:(i=u.charCodeAt(a))<55296||i>56319||a+1===c||(s=u.charCodeAt(a+1))<56320||s>57343?t?u.charAt(a):i:t?u.slice(a,a+2):s-56320+(i-55296<<10)+65536}}},lO7g:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n("Gu7T"),o=n.n(r),i=n("woOf"),s=n.n(i),u=n("mtWM"),a=n.n(u),c={computed:{state:function(){return this.seed.length>=4},invalidFeedback:function(){return this.seed.length>4?"":"请输入包含视频的知乎回答链接"},validFeedback:function(){return!0===this.state?"Thank you":""}},data:function(){return{show:!0,seed:"",items:[],timer:null}},beforeDestroy:function(){clearInterval(this.timer),this.timer=null},methods:{onSubmit:function(t){t.preventDefault(),this.download(),this.getProgress()},getProgress:function(){var t=this;this.timer=setInterval(function(){for(var e=!0,n=0;n=0)return;s[e]="set-cookie"===e?(s[e]?s[e]:[]).concat([n]):s[e]?s[e]+", "+n:n}}),s):s}},p1b6:function(t,e,n){"use strict";var r=n("cGG2");t.exports=r.isStandardBrowserEnv()?{write:function(t,e,n,o,i,s){var u=[];u.push(t+"="+encodeURIComponent(e)),r.isNumber(n)&&u.push("expires="+new Date(n).toGMTString()),r.isString(o)&&u.push("path="+o),r.isString(i)&&u.push("domain="+i),!0===s&&u.push("secure"),document.cookie=u.join("; ")},read:function(t){var e=document.cookie.match(new RegExp("(^|;\\s*)("+t+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove:function(t){this.write(t,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},pBtG:function(t,e,n){"use strict";t.exports=function(t){return!(!t||!t.__CANCEL__)}},pxG4:function(t,e,n){"use strict";t.exports=function(t){return function(e){return t.apply(null,e)}}},qRfI:function(t,e,n){"use strict";t.exports=function(t,e){return e?t.replace(/\/+$/,"")+"/"+e.replace(/^\/+/,""):t}},qio6:function(t,e,n){var r=n("evD5"),o=n("77Pl"),i=n("lktj");t.exports=n("+E39")?Object.defineProperties:function(t,e){o(t);for(var n,s=i(e),u=s.length,a=0;u>a;)r.f(t,n=s[a++],e[n]);return t}},qyJz:function(t,e,n){"use strict";var r=n("+ZMJ"),o=n("kM2E"),i=n("sB3e"),s=n("msXi"),u=n("Mhyx"),a=n("QRG4"),c=n("fBQ2"),f=n("3fs2");o(o.S+o.F*!n("dY0y")(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,o,l,d=i(t),p="function"==typeof this?this:Array,h=arguments.length,v=h>1?arguments[1]:void 0,m=void 0!==v,y=0,g=f(d);if(m&&(v=r(v,h>2?arguments[2]:void 0,2)),void 0==g||p==Array&&u(g))for(n=new p(e=a(d.length));e>y;y++)c(n,y,m?v(d[y],y):d[y]);else for(l=g.call(d),n=new p;!(o=l.next()).done;y++)c(n,y,m?s(l,v,[o.value,y],!0):o.value);return n.length=y,n}})},t8qj:function(t,e,n){"use strict";t.exports=function(t,e,n,r,o){return t.config=e,n&&(t.code=n),t.request=r,t.response=o,t}},tIFN:function(t,e,n){"use strict";var r=n("cGG2"),o=n("JP+z"),i=n("XmWM"),s=n("KCLY");function u(t){var e=new i(t),n=o(i.prototype.request,e);return r.extend(n,i.prototype,e),r.extend(n,e),n}var a=u(s);a.Axios=i,a.create=function(t){return u(r.merge(s,t))},a.Cancel=n("dVOP"),a.CancelToken=n("cWxy"),a.isCancel=n("pBtG"),a.all=function(t){return Promise.all(t)},a.spread=n("pxG4"),t.exports=a,t.exports.default=a},thJu:function(t,e,n){"use strict";var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function o(){this.message="String contains an invalid character"}o.prototype=new Error,o.prototype.code=5,o.prototype.name="InvalidCharacterError",t.exports=function(t){for(var e,n,i=String(t),s="",u=0,a=r;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&e>>8-u%1*8)){if((n=i.charCodeAt(u+=.75))>255)throw new o;e=e<<8|n}return s}},"vIB/":function(t,e,n){"use strict";var r=n("O4g8"),o=n("kM2E"),i=n("880/"),s=n("hJx8"),u=n("/bQp"),a=n("94VQ"),c=n("e6n0"),f=n("PzxK"),l=n("dSzd")("iterator"),d=!([].keys&&"next"in[].keys()),p=function(){return this};t.exports=function(t,e,n,h,v,m,y){a(n,e,h);var g,w,x,b=function(t){if(!d&&t in R)return R[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",T="values"==v,C=!1,R=t.prototype,A=R[l]||R["@@iterator"]||v&&R[v],E=A||b(v),k=v?T?b("entries"):E:void 0,G="Array"==e&&R.entries||A;if(G&&(x=f(G.call(new t)))!==Object.prototype&&x.next&&(c(x,S,!0),r||"function"==typeof x[l]||s(x,l,p)),T&&A&&"values"!==A.name&&(C=!0,E=function(){return A.call(this)}),r&&!y||!d&&!C&&R[l]||s(R,l,E),u[e]=E,u[S]=p,v)if(g={values:T?E:b("values"),keys:m?E:b("keys"),entries:k},y)for(w in g)w in R||i(R,w,g[w]);else o(o.P+o.F*(d||C),e,g);return g}},xLtR:function(t,e,n){"use strict";var r=n("cGG2"),o=n("TNV1"),i=n("pBtG"),s=n("KCLY"),u=n("dIwP"),a=n("qRfI");function c(t){t.cancelToken&&t.cancelToken.throwIfRequested()}t.exports=function(t){return c(t),t.baseURL&&!u(t.url)&&(t.url=a(t.baseURL,t.url)),t.headers=t.headers||{},t.data=o(t.data,t.headers,t.transformRequest),t.headers=r.merge(t.headers.common||{},t.headers[t.method]||{},t.headers||{}),r.forEach(["delete","get","head","post","put","patch","common"],function(e){delete t.headers[e]}),(t.adapter||s.adapter)(t).then(function(e){return c(t),e.data=o(e.data,e.headers,t.transformResponse),e},function(e){return i(e)||(c(t),e&&e.response&&(e.response.data=o(e.response.data,e.response.headers,t.transformResponse))),Promise.reject(e)})}},zQR9:function(t,e,n){"use strict";var r=n("h65t")(!0);n("vIB/")(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})}});
9 | //# sourceMappingURL=0.689b9a587c6153676efc.js.map
--------------------------------------------------------------------------------
/dist/static/js/1.3cb2992300207dee1ecc.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1],{"1uuo":function(t,e){},gORT:function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a={render:function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("div",{staticClass:"hello"},[r("h1",[t._v(t._s(t.msg))]),t._v(" "),r("h2",[t._v("Essential Links")]),t._v(" "),t._m(0),t._v(" "),r("h2",[t._v("Ecosystem")]),t._v(" "),t._m(1)])},staticRenderFns:[function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("ul",[r("li",[r("a",{attrs:{href:"https://vuejs.org",target:"_blank"}},[t._v("\n Core Docs\n ")])]),t._v(" "),r("li",[r("a",{attrs:{href:"https://forum.vuejs.org",target:"_blank"}},[t._v("\n Forum\n ")])]),t._v(" "),r("li",[r("a",{attrs:{href:"https://chat.vuejs.org",target:"_blank"}},[t._v("\n Community Chat\n ")])]),t._v(" "),r("li",[r("a",{attrs:{href:"https://twitter.com/vuejs",target:"_blank"}},[t._v("\n Twitter\n ")])]),t._v(" "),r("br"),t._v(" "),r("li",[r("a",{attrs:{href:"http://vuejs-templates.github.io/webpack/",target:"_blank"}},[t._v("\n Docs for This Template\n ")])])])},function(){var t=this.$createElement,e=this._self._c||t;return e("ul",[e("li",[e("a",{attrs:{href:"http://router.vuejs.org/",target:"_blank"}},[this._v("\n vue-router\n ")])]),this._v(" "),e("li",[e("a",{attrs:{href:"http://vuex.vuejs.org/",target:"_blank"}},[this._v("\n vuex\n ")])]),this._v(" "),e("li",[e("a",{attrs:{href:"http://vue-loader.vuejs.org/",target:"_blank"}},[this._v("\n vue-loader\n ")])]),this._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/vuejs/awesome-vue",target:"_blank"}},[this._v("\n awesome-vue\n ")])])])}]};var s=r("VU/8")({name:"HelloWorld",data:function(){return{msg:"Welcome to Your Vue.js App"}}},a,!1,function(t){r("1uuo")},"data-v-d8ec41bc",null);e.default=s.exports}});
2 | //# sourceMappingURL=1.3cb2992300207dee1ecc.js.map
--------------------------------------------------------------------------------
/dist/static/js/1.3cb2992300207dee1ecc.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///src/components/HelloWorld.vue","webpack:///./src/components/HelloWorld.vue?3ba4","webpack:///./src/components/HelloWorld.vue"],"names":["components_HelloWorld","render","_vm","this","_h","$createElement","_c","_self","staticClass","_v","_s","msg","_m","staticRenderFns","attrs","href","target","Component","__webpack_require__","normalizeComponent","name","data","ssrContext","__webpack_exports__"],"mappings":"4HAsFA,ICnFAA,GADiBC,OAFjB,WAA0B,IAAAC,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BC,EAAAJ,EAAAK,MAAAD,IAAAF,EAAwB,OAAAE,EAAA,OAAiBE,YAAA,UAAoBF,EAAA,MAAAJ,EAAAO,GAAAP,EAAAQ,GAAAR,EAAAS,QAAAT,EAAAO,GAAA,KAAAH,EAAA,MAAAJ,EAAAO,GAAA,qBAAAP,EAAAO,GAAA,KAAAP,EAAAU,GAAA,GAAAV,EAAAO,GAAA,KAAAH,EAAA,MAAAJ,EAAAO,GAAA,eAAAP,EAAAO,GAAA,KAAAP,EAAAU,GAAA,MAE7GC,iBADjB,WAAoC,IAAAX,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BC,EAAAJ,EAAAK,MAAAD,IAAAF,EAAwB,OAAAE,EAAA,MAAAA,EAAA,MAAAA,EAAA,KAAiCQ,OAAOC,KAAA,oBAAAC,OAAA,YAA8Cd,EAAAO,GAAA,mCAAAP,EAAAO,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAAyEQ,OAAOC,KAAA,0BAAAC,OAAA,YAAoDd,EAAAO,GAAA,+BAAAP,EAAAO,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAAqEQ,OAAOC,KAAA,yBAAAC,OAAA,YAAmDd,EAAAO,GAAA,wCAAAP,EAAAO,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAA8EQ,OAAOC,KAAA,4BAAAC,OAAA,YAAsDd,EAAAO,GAAA,iCAAAP,EAAAO,GAAA,KAAAH,EAAA,MAAAJ,EAAAO,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAA4FQ,OAAOC,KAAA,4CAAAC,OAAA,YAAsEd,EAAAO,GAAA,mDAA2D,WAAc,IAAaL,EAAbD,KAAaE,eAA0BC,EAAvCH,KAAuCI,MAAAD,IAAAF,EAAwB,OAAAE,EAAA,MAAAA,EAAA,MAAAA,EAAA,KAAiCQ,OAAOC,KAAA,2BAAAC,OAAA,YAAvGb,KAA4JM,GAAA,oCAA5JN,KAA4JM,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAA0EQ,OAAOC,KAAA,yBAAAC,OAAA,YAA7Ob,KAAgSM,GAAA,8BAAhSN,KAAgSM,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAAoEQ,OAAOC,KAAA,+BAAAC,OAAA,YAA3Wb,KAAoaM,GAAA,oCAApaN,KAAoaM,GAAA,KAAAH,EAAA,MAAAA,EAAA,KAA0EQ,OAAOC,KAAA,uCAAAC,OAAA,YAArfb,KAAsjBM,GAAA,0CCE/2C,IAcAQ,EAdAC,EAAA,OAcAC,EFsEAC,KAAA,aACAC,KAFA,WAGA,OACAV,IAAA,gCEvEAX,GATA,EAVA,SAAAsB,GACAJ,EAAA,SAaA,kBAEA,MAUAK,EAAA,QAAAN,EAAA","file":"static/js/1.3cb2992300207dee1ecc.js","sourcesContent":["\n \n
{{ msg }}
\n
Essential Links
\n
\n
Ecosystem
\n
\n
\n\n\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/HelloWorld.vue","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"hello\"},[_c('h1',[_vm._v(_vm._s(_vm.msg))]),_vm._v(\" \"),_c('h2',[_vm._v(\"Essential Links\")]),_vm._v(\" \"),_vm._m(0),_vm._v(\" \"),_c('h2',[_vm._v(\"Ecosystem\")]),_vm._v(\" \"),_vm._m(1)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('ul',[_c('li',[_c('a',{attrs:{\"href\":\"https://vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"\\n Core Docs\\n \")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://forum.vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"\\n Forum\\n \")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://chat.vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"\\n Community Chat\\n \")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://twitter.com/vuejs\",\"target\":\"_blank\"}},[_vm._v(\"\\n Twitter\\n \")])]),_vm._v(\" \"),_c('br'),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vuejs-templates.github.io/webpack/\",\"target\":\"_blank\"}},[_vm._v(\"\\n Docs for This Template\\n \")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('ul',[_c('li',[_c('a',{attrs:{\"href\":\"http://router.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"\\n vue-router\\n \")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vuex.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"\\n vuex\\n \")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vue-loader.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"\\n vue-loader\\n \")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://github.com/vuejs/awesome-vue\",\"target\":\"_blank\"}},[_vm._v(\"\\n awesome-vue\\n \")])])])}]\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-d8ec41bc\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/HelloWorld.vue\n// module id = null\n// module chunks = ","function injectStyle (ssrContext) {\n require(\"!!../../node_modules/extract-text-webpack-plugin/dist/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-d8ec41bc\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./HelloWorld.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./HelloWorld.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./HelloWorld.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-d8ec41bc\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./HelloWorld.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-d8ec41bc\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/HelloWorld.vue\n// module id = null\n// module chunks = "],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/static/js/2.83ac2feabc358f1e7df7.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([2],{YcJa:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l={render:function(){this.$createElement;this._self._c;return this._m(0)},staticRenderFns:[function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("p",[this._v("404 - Not Found")])])}]},r=n("VU/8")(null,l,!1,null,null,null);t.default=r.exports}});
2 | //# sourceMappingURL=2.83ac2feabc358f1e7df7.js.map
--------------------------------------------------------------------------------
/dist/static/js/2.83ac2feabc358f1e7df7.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///./src/components/NotFound.vue?90b3","webpack:///./src/components/NotFound.vue"],"names":["NotFound","render","this","$createElement","_self","_c","_m","staticRenderFns","_h","_v","Component","__webpack_require__","normalizeComponent","__webpack_exports__"],"mappings":"qGAAA,IAGAA,GADiBC,OAFjB,WAA0BC,KAAaC,eAAbD,KAAuCE,MAAAC,GAAwB,OAA/DH,KAA+DI,GAAA,IAExEC,iBADjB,WAAoC,IAAaC,EAAbN,KAAaC,eAA0BE,EAAvCH,KAAuCE,MAAAC,IAAAG,EAAwB,OAAAH,EAAA,OAAAA,EAAA,KAA/DH,KAA+DO,GAAA,0BCYnGC,EAbAC,EAAA,OAaAC,CAXA,KAaAZ,GATA,EAEA,KAEA,KAEA,MAUAa,EAAA,QAAAH,EAAA","file":"static/js/2.83ac2feabc358f1e7df7.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm._m(0)}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('p',[_vm._v(\"404 - Not Found\")])])}]\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-1594d002\",\"hasScoped\":false,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/NotFound.vue\n// module id = null\n// module chunks = ","var normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nvar __vue_script__ = null\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1594d002\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./NotFound.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = null\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/NotFound.vue\n// module id = null\n// module chunks = "],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/static/js/3.1e1621ff1dbe6bca1bb4.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([3],{c27y:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l={render:function(){this.$createElement;this._self._c;return this._m(0)},staticRenderFns:[function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("p",[this._v("About")])])}]},r=n("VU/8")(null,l,!1,null,null,null);t.default=r.exports}});
2 | //# sourceMappingURL=3.1e1621ff1dbe6bca1bb4.js.map
--------------------------------------------------------------------------------
/dist/static/js/3.1e1621ff1dbe6bca1bb4.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///./src/components/About.vue?1812","webpack:///./src/components/About.vue"],"names":["About","render","this","$createElement","_self","_c","_m","staticRenderFns","_h","_v","Component","__webpack_require__","normalizeComponent","__webpack_exports__"],"mappings":"qGAAA,IAGAA,GADiBC,OAFjB,WAA0BC,KAAaC,eAAbD,KAAuCE,MAAAC,GAAwB,OAA/DH,KAA+DI,GAAA,IAExEC,iBADjB,WAAoC,IAAaC,EAAbN,KAAaC,eAA0BE,EAAvCH,KAAuCE,MAAAC,IAAAG,EAAwB,OAAAH,EAAA,OAAAA,EAAA,KAA/DH,KAA+DO,GAAA,gBCYnGC,EAbAC,EAAA,OAaAC,CAXA,KAaAZ,GATA,EAEA,KAEA,KAEA,MAUAa,EAAA,QAAAH,EAAA","file":"static/js/3.1e1621ff1dbe6bca1bb4.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm._m(0)}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('p',[_vm._v(\"About\")])])}]\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-d0fc4dfa\",\"hasScoped\":false,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/About.vue\n// module id = null\n// module chunks = ","var normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nvar __vue_script__ = null\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-d0fc4dfa\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./About.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = null\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/About.vue\n// module id = null\n// module chunks = "],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/static/js/app.cde59b67f82f386b8ea5.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([5],{"1/oy":function(t,n){},"7Otq":function(t,n){t.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd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"},"9M+g":function(t,n){},GfHa:function(t,n){},Id91:function(t,n){},Jmt5:function(t,n){},NHnr:function(t,n,c){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i=c("/5sW"),e={render:function(){var t=this.$createElement,n=this._self._c||t;return n("div",{attrs:{id:"app"}},[n("b-container",{staticClass:"p-4"},[n("b-row",[n("b-col",[n("b-img",{attrs:{center:"",fluid:"",src:c("7Otq")}})],1)],1)],1),this._v(" "),n("router-view")],1)},staticRenderFns:[]};var I=c("VU/8")({name:"App"},e,!1,function(t){c("c+Mh")},null,null).exports,u=c("Dd8w"),o=c.n(u),r=c("/ocq"),a=c("e6fC"),l=(c("Jmt5"),c("9M+g"),[{path:"/",component:"Home"},{path:"/about",component:"About"},{path:"*",component:"NotFound"}].map(function(t){return o()({},t,{component:function(){return c("mUJ2")("./"+t.component+".vue")}})}));i.a.use(r.a),i.a.use(a.a);var s=new r.a({routes:l,mode:"history"});i.a.config.productionTip=!1,new i.a({el:"#app",router:s,render:function(t){return t(I)}})},"c+Mh":function(t,n){},mUJ2:function(t,n,c){var i={"./About.vue":["c27y",3],"./HelloWorld.vue":["gORT",1],"./Home.vue":["lO7g",0],"./NotFound.vue":["YcJa",2]};function e(t){var n=i[t];return n?c.e(n[1]).then(function(){return c(n[0])}):Promise.reject(new Error("Cannot find module '"+t+"'."))}e.keys=function(){return Object.keys(i)},e.id="mUJ2",t.exports=e},zj2Q:function(t,n){}},["NHnr"]);
2 | //# sourceMappingURL=app.cde59b67f82f386b8ea5.js.map
--------------------------------------------------------------------------------
/dist/static/js/app.cde59b67f82f386b8ea5.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///./src/assets/logo.png","webpack:///./src/App.vue?e307","webpack:///./src/App.vue","webpack:///src/App.vue","webpack:///./src/router/index.js","webpack:///./src/main.js","webpack:///./src/components lazy ^\\.\\/.*\\.vue$"],"names":["module","exports","selectortype_template_index_0_src_App","render","_h","this","$createElement","_c","_self","attrs","id","staticClass","center","fluid","src","__webpack_require__","_v","staticRenderFns","src_App","normalizeComponent","name","ssrContext","routes","path","component","map","route","extends_default","vue_runtime_esm","use","vue_router_esm","es","router","mode","config","productionTip","el","h","./About.vue","./HelloWorld.vue","./Home.vue","./NotFound.vue","webpackAsyncContext","req","ids","e","then","Promise","reject","Error","keys","Object"],"mappings":"8DAAAA,EAAAC,QAAA,+nSCGAC,GADiBC,OAFjB,WAA0B,IAAaC,EAAbC,KAAaC,eAA0BC,EAAvCF,KAAuCG,MAAAD,IAAAH,EAAwB,OAAAG,EAAA,OAAiBE,OAAOC,GAAA,SAAYH,EAAA,eAAoBI,YAAA,QAAkBJ,EAAA,SAAAA,EAAA,SAAAA,EAAA,SAAsCE,OAAOG,OAAA,GAAAC,MAAA,GAAAC,IAAAC,EAAA,YAA2D,WAAjPV,KAAiPW,GAAA,KAAAT,EAAA,oBAE1PU,oBCCjB,IAuBAC,EAvBAH,EAAA,OAcAI,ECGAC,KAAA,ODDAlB,GATA,EAVA,SAAAmB,GACAN,EAAA,SAaA,KAEA,MAUA,qDEbMO,yBANFC,KAAM,IAAKC,UAAW,SACtBD,KAAM,SAAUC,UAAW,UAC3BD,KAAM,IAAKC,UAAW,aAIGC,IAAI,SAAAC,GAC/B,OAAAC,OACKD,GACHF,UAAW,kBAAMT,EAAA,OAAAA,CAAA,KAAuBW,EAAMF,UAA7B,cAIrBI,EAAA,EAAIC,IAAIC,EAAA,GACRF,EAAA,EAAIC,IAAIE,EAAA,GAER,IAAAC,EAAA,IAAmBF,EAAA,GACjBR,SACAW,KAAM,YCrBRL,EAAA,EAAIM,OAAOC,eAAgB,EAG3B,IAAIP,EAAA,GACFQ,GAAI,OACJJ,SACA7B,OAAQ,SAAAkC,GAAA,OAAKA,EAAEnB,mDCVjB,IAAAO,GACAa,eACA,OACA,GAEAC,oBACA,OACA,GAEAC,cACA,OACA,GAEAC,kBACA,OACA,IAGA,SAAAC,EAAAC,GACA,IAAAC,EAAAnB,EAAAkB,GACA,OAAAC,EAEA7B,EAAA8B,EAAAD,EAAA,IAAAE,KAAA,WACA,OAAA/B,EAAA6B,EAAA,MAFAG,QAAAC,OAAA,IAAAC,MAAA,uBAAAN,EAAA,OAKAD,EAAAQ,KAAA,WACA,OAAAC,OAAAD,KAAAzB,IAEAiB,EAAAhC,GAAA,OACAV,EAAAC,QAAAyC","file":"static/js/app.cde59b67f82f386b8ea5.js","sourcesContent":["module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd1XVe53XvvD2eGQ/lXQcKuDwc2eFlCAGnUn7kT6T86J/+aNTgsWPchJJYciEOCQ8hF+G0hFCIHRSEqAuJBCqRaUEIEbmBppAIBGnESwZje8COZ+y587j3PLq+ffadGJix53HvPevcuz60xPjec89ZZ+39nf04+9vLSZKEFArFzHA1BAqFEkShUIIoFEoQhUIJolAoQRQKJYhCoQRRKJQgCoUSRKFQKEEUCiWIQrFo+Gv/8/YH+f/nsMWSHHMChyhxqPTTdyncWyJ3ScD/ztipiB3wXSqu6P17avN+TyFC5ggv4tRnmoxWTP1+5F+Mz17GPvPl49EKBWd3UsfXllPiso8VcYtmPba3fNuKrBVXrGFCbrdPwXndFL49ltI367roOpSUI4pGypv9s7q+ltj6JxqOQ07Bo/DgxGb2/a8cX0CnAWXJ5etz2TqdHiXHKlKj9w6i9XX8Ic41DmI8FVHhmmXk85MmRhCzJoiTWnig9LfJRHihgydxzAxJhBr7Bh/hK3yu+p9568FliTJF2aKMZfVd/kQOcKP6OBmS9+Rjm4zJ6faoeN0gOUn61MncLX4CJ+MRhe+P/dRxhfew2Df4CF/hs4jWg8vQYUKYMuWyRRkLjeHQ8YP0Z9mekVjA8Qj3VVcuoeDiXu63lkUE0ym6FA5PXBaNVr7qtPumGyPR4Bt8hK/wWUR5chn6XJYoU5StUHL8l+XEx2axhkS6yk+chJuP4rXLyOkIKJkS0B67adcqfL/0Y4pixxSysK6V8Yl9Mz7i3272NRFlhzJsu24Z5l9E9Ahmwfrpoj7uw3fZtktsRZKjIXnndlLxin7+W8ZTBwPf6I+Tg9HwxK2Ob8citbCoBoaxBxMCvsFH+CqjHCtUvLzflKWUcpwB91gupG5f9/Rtx39ZZBtmWyJtphKzHTQW0diP36b4aJmcLj/zGaSkHJPb4SWFi/tOJd8bTqd9s48VBRh4RKeUX/vjgXg8cpyCmz05xkJylxSoa8M5RF0eJaVIIkGOsg2yTc3UgpD94psiWxEOqDNYoOIXuHnGwE5AXUTFi46FTnRw4l/dwEm7/pSxcYnCF/gE3zInh52RRJkVP7/MlKFQcgCbjifHTAQBfsb2qsgBO3e1Cpf3UXBej3nRJKKrxU/rcH/pKzz4vNIQuRJTEmZklbg6EL4SPsE3GQPzinmfhbJDGQolB+r8w58abs5y8DqRt4ABeptLRR7koY9NleybEYw/MPisvF/ayT1/SvDewcnIcG32wfiCAbEvoCZyGaGsitdyz6XdTctQJq6fcT5mloNfYvu5yFZkpEz+RT0UrFoqpxVBV+vQxIrkaPnrbqdvXs6hcjbU+Jq4Nvvwd/BFRNeq2npwWfkX95iyE9p6PM72P/MhCPANTBSKu5WITHcC074Y9CUTkYglKBgcV/aVtlM5Kpp/RHFjDdfka7MP/2wG6m72661QNigjlBXKTGBtsjWKNs5atCf44Uds3xc5YD8Wknd2BxWuGjCzIxLWQzlFj+IjU108OL7bafM5sm5DDdfka/8T+9AJXyTMpqFsUEYoK5SZ0NbjVlvX500Q4Ha2A+JuCcEvhVS8qp/8MzspHhMSfO7mVPaP35BMRp9JsCQldbX+hmvxNfnamzJfqVvtWnGZoGxQRigroYs6UbfvOGHn4ORVkTaIbEWwtqg3MNO+Zql0JGCdVuCayhDuG9uJB7vp+oR17FbZc+NauCauLWLmKkqXr6NsUEYoK6GtxwY6CXXnEs0n2faIHLCPhhR8bikFKwRN+xZddHWu5a7Ol9yCZ2ZwHKdOxufGNeKRqS/hmnLWW1VMmQSrl5oyEkqOPbZu02IJAsic9sU7B+5uF9cOmqUfeLOdOaAZYb/CA+M/Ic9NxUoYMNfD/PT84f7xB807EAnrrbgMUBZt1w1SEpCIqfjF1Om5EuQNth0iu1r8tPLP76LCpX2yWpHDk2dGH018p6brtD5hOHf04cR3okOTZ0lqPVAW3gVdlMhdrfsTW6drRhDgRrYJcbeKZQxTkenvegNt6YBQwrQvOxG+P3ZHEia9TuClS9Br1XKge8XnxLlxjelzZ/2w4tijDMxyoHIsVQg1zvYPcy7KeZx4jG2zyFakFJF7Whu1XT2QvhfJeryeVNdplYPo4Pi9hKd7VVxVC8O5cH4+N65hXgoKuGfEHmWAskjGxI49Ntu6XHOCAD9ie1PcLSepjDNY00fB8m6KpSyJx/jgg9LfJEfLK40818w+LXY5e5zKaMfKl+DcIlSCZp0cd3U59igDI4+WOa2LunvfvDoD9RrcNLqAjDy3yzfrtKqbAkggSDIZmSlYxzz9a8BaJ101zF2rh3BuSTJaCKGMDEGujHbedXch0X2ebbdEkkDC6a9cQoWVguS53P0JP5xcHY1W/tppD9KxgrdAw5QxnwPn4nOukrPeqkzBJb0m9oJltLtt3a07QYD1IkMAeS7/hw0BXMhzJwXJc/eV7kuiyIN8OOGuUhLP06JUeoxz4FxiZLRouTsDM9WO2OdBRtsIgrzHtk3kgH00JO+cTipc2S9jqyCaluf2xwcnfuB6LndHuEsSzdP4N/gtzoFzSZHRIsaQQiPmidyXgttsnW0YQYDvsh2ROGBPxkMqXjNA/qlCFsnZ8UdlX+kfk0pymlnMWH2JOBfz0sWI+C3OMS1dzPphhPVWHOPC5wdMzIUOzFFHb1lwB2ARF+ZOPt0gshWBPLe/wCRZlu6CIkSei/cE0fD4g2ZbVWceyxH5WPwGvzXrrSTJaDnG7oBoGS3qaCULggCPsv1W5IAd8tzLllJwvpx1WthMIfyg9OVotHy1WVQ4V37wsfgNfkuSZLQcW8Q4lruU/RVbRykrggDXiwwN3uQWnXTa1xMkz2W/on2lndNajpNtAGePw2/MOicBMlqs+8K7GBNbjrFgGe2iX0nUgiAvs+0S2YpgndaFPVRc3SdmVanZlfGjifOiw5PrT/oGvPpG/vDkEH4jZ70Vt86rl5rYimmdP41/s3Uzc4Isup9XNxwvz+0tyNAlONPrtO6hctR+QnluKqNt52O3pxvtClhvxTH0egtmEwbBMlrUxU21OFGtCHKYbavIATv3j90z26kIea4QZRtahfhIuT0anrjH7O3rpjNVHzPIaLG3Lh8Tj5TbRQihjlNyehxTwTLarbZOiiEIcBfbPnGhMtroChXW9JN/VqeYdyPEY4nwwPj6ZCL8C1T+T61JhDqRv8MxZgwlJG2BxzEsrBmgeEzseqt9ti6SNIIA8t6wm901eFDZ66d7M4UkQ56LVgTTvvtKaRqFqoTWymjxGb6LpUzrImYcuzaOIWKJmAptPWpaB2sd+V+yvSB1wB6s7qXgwiUyBpbJdBqFq6MjU18mKCKhRsTyEbx558/wnRmYJzLiV+DYBat6JQ/MX7B1UCxBAKHy3IQrH6W7MhY9MWkUMNAN948/8Mm35/jMDIKlpC3gmBWQtsAjifkE61b36kGQP7DdL7KrVZXnXiYpjYKZxj09Gh7f4kB4yIa/8ZmU1brIIYiYIXaJ3Nbjflv3xBME+DZbSVwIzfIIK89dJkSea18Ihu+XflD9yPztCJnW5Ri5VRntpNh8giVb5ygvBIHu9yaRrchYRO6fFU0CSTPQlDLte6zshx9O3g3D3yJajySd4EDaAsQMsRPaetxk61zty+YTCXRqjf9jO19cOLnyYV+p8QffpcreMXJ7BeRgh77Ds6SIYhGbMBgB2tld1DW0nGL4VxbZfKBbdUHdhol1dl7mOi0MOjttGgWT11lAwU9r1mMSsX0oxwSxgYyWOvKXtiAvBPkV239I7GqZdVqX9FDw2V5+UoYipn2nt/WRMK3LMQlW9poYCZ7WfcrWsdwSBNggMrRYdcLdhjas0+q28lzJOc8bOU7jWLh2AwzEyLxclYm6Z2ZuBEE+YLtTZEVA9tzPdBh5biJ3q5rGD8yRjXbNAPkcm0RuyjTUqf3NQBDge2yHJFaGeDyi4tUD5J3WIXmzs8Y9NDgG3un80OCYIDZCHxqHbJ2iZiEIGmnB8twgzYIkd7vMxiBON59GLJyBQLKMdiM1qOPXyMn2f2f7X5EDdshzkUbhAtED0oZMXCAGiIXgtAW/YXusURdr9NsoufLcgmP20zKy2ErrNSNGRuunMUAshL7zABq61q/RBPkd2yNSn57+X3ZTQZA8t7H3H5p7RwwEt6KP2DrUtAQBIIUsiwt99Kf+tydFntuocVhVRltNWyBTRlumGslopRNkhO1mkRVlLCT3jHYzqyU48WSN+1ZWRou0BZDRyp3Ju9nWnaYnCHA3216JlQWy0gKy557dJSaNQn0nKNL1VrhnwTLavbbOUKsQBBApzzVpFHqsPFdIGoW6AfeG7cMwrcv3TC0io80LQZ5me07kU3WkYqSlhYvkpFGoz8C8bO7RyGjlpi14ztaVliMIIFOeizQKbpI+WdsDGfLcWvcmsaK53b4gdUW3lENZXjxrgrzNdq/IAftohbzzOql4eV/zjUUcu96K7w33KFhGi7rxVisTBEBSxWPiiqYqz71mGfmDQuS5tSIHstHyPZnd7+XKaI+RgKSxEggySWmKaXkVaSwi5xSbRmGiSdZpxVZGy/eEexMso73R1o2WJwiwk+11kQNZrNO6oo+Cc7vz39Wy07q4l+CKfnNvQu/ndVsnSAkifcCOAXq7R8W1y9JdRvI87QvfnTRtgdPeujLavBLkv9meEPnUHS2Tf1EPFT67lOKRnE77munrsrkH/+IeydPXqAO/VoLMDMhz5T2irTzXpFHoKeRPnluV0XYX0mlduTLamIRJtKUR5CDbbSIrGPfX/eUdVFyTQ3luku6OaNIW/HmH5LQFt9k6oAQ5Ab7PNiyxkmGndUhRvTNyJM9F1wrZaM9IZbQmG63MocewxIejRIKg+DaKbEXGI3KWBtT2hUFKyonUZeEfB3xkX4vsM3wXvIx/IwmMqCu0WH/B9qLIpzG6Wp/rpWBFj/x1WnaCAb4G7LPgad0XbZmTEmTukDnti0yzgZvKcwNPtDzXyGjZR5ONFincVEbbVAR5je0hkU/lkTL5F3TZzQ2EvjysJr1hH/0LuiVPTz9ky1oJsgB8iwQsN5hplISns5Hn9hXl9eurMlr2zUzrVsQuk5m0ZUxKkIXhKNsWkQN2yHNPhzx3WbqQMRZGYCOjXWZ8FDzjtsWWsRJkEfgh2zvyOvhWnovsucu75GTPtdlo4RN8i+W+s3nHli0pQRaPIXEeVeW53V46YJciz2Uf4IvxiX0juW/9h/JQ8fJCkGfZnpE5YK9QsHIJBZcIkOdW141d3Gt8EiyjfcaWqRKk6Z84kOc6duODjmzluUZGyz4g6Q18UhltaxHkXbbtIgfsRyvknQt5bobZc6dltP3Gl0SudmW7LUslSJ1mPUbFeWVUepDnDpB3SgazRtW0BXxt+ABfhE7rypyVbCKCTLF9U2QrgjQKg3b7zskGv3eI0+XsuDZ8EJy2YJMtQyVIHfEztldFDtghz728j4LzGphGoZq2gK9ZMDuwiH3ngTJ7OG+VLY8EAeTKc9ts9lwk42zEOi2st+JrYZIA1xYso12Xx4qWV4K8xPZzka3ISCrPDVY1YJ1WtfVYZWW0ctdbPW7LTAnSQHyDJCoykEYhTNdpuUsK6YDZqQ85cG5cw6y3CsWmLYBXG/NayfJMkI8oVR/KG7AfC8k7u4MKVw2kM1r1eB2RpDNXuAauJVhGe6stKyVIBrid7YA4r6o5N5BG4cxOI3mtaeWtymj53LiG4FwmKJs78lzB8k4QVIsN4ryqynN7AzP1ShXIc2tYg3GuSpJO6/aKltHK3KWmhQgCPMm2R+SAfTSkANlzV9Rw2rc6MDcyWtHZaPfYsiElSPaQOYVYiSnxiIprB8kpeGn+v8U2mZD8FjxzTpybKjqtqwQ5Od5g2yGyq4Xsued3UeHSvsW3IlUZLZ8L5xSctmCHLRMliCBgN/AJcV7F6SpbjBe8gUWkUaimLeBzmOUsU2JltOMkcbd+JQiNkYB8ErNVbPe0Nmq72i4kXMiwNUnfe+AcOJfgfCWbbVkoQQTiR2xvivPKynODNX0ULF9AGoVq2gL+Lc4hWEaL2N/XTBWq2Qgic3BYled2+ekeVfOV51az0WKNF59DsIx2XbNVpmYkyPNsuyWSBBJYf+USKsxHnlvNRsu/8WXLaHfb2CtBcoD1Ir2CPJf/wxSt2xmkupGT9c6QtoCPNdO66FfJldGub8aK1KwEeY9tm8gB+2hI3jmdVLii/+RbBdktfHAsfpPIfSm4zcZcCZIjfJftiMQBO1IQQBrrn3qCRYZ20SOOMTLacbHrrRDjW5q1EjUzQbiTTzeIbEUgz+232XNne59RfX+CbLT9omW0iHFFCZJPPMr2W5EDdshzL1tKwfkzrNOqrrfi73CMYBntKzbGpATJL64X6RXWZRVtxlnP+VgaBZO2wEu/wzGatkAJUk+8zLZLZCuCdVoXciux+rhVuXYVMD7Dd7Hc9Va7bGyVIE0Amf3kaXnuIHm9qTwXhr/xmWAZbUXk+E4JsmAcZtsqcsAOee6Z7VS08lwY/sZngmW0W21MlSBNhLvY9onzCqtIxipUuKqf3L6iMfyNz4RO6+6zsWwJ+NRawNvep8S1IhMxucie+8VT0o+6PIqPiB17rG+lCtNqBPkl2wts14gbsCONwqVLzT8Fr7d6wcawZeBS60Hm1GSSTu+a6d5EY6cEyQ5/YLtf4oCd4iQ1ma3H/TZ2SpAWwLfZSqSYK0o2ZqQEaQ1AN32T1vs54yYbMyVIC+GBVuwyLLBL+kCr3rzb4oV/vdZ/jZESZHb8iqS9F5GFp2yMlCAtjCENgcZGCTI79rPdqWH4FO60sVGCKOh7bIc0DNM4ZGNCShAFEFKOsyDVARttTJQgGoJpPMb2Gw2DicFjGgYlyExYpyHQGChBZsfv2B5p4ft/xMZAoQSZFZso3TKo1VC2965QgpwQI2w3t+B932zvXaEEOSnuZtvbQve7196zQgkyZ6zXe1UoQWbH02zPtcB9PmfvVaEEmTeG9B6VIIrZ8RbbvU18f/fae1QoQRYMJKU81oT3dYwkJj1VguQOk9REaY2Pw4323hRKkEVjJ9vrTXQ/r9t7UihBaobr9V6UIIrZ8Wu2J5rgPp6w96JQgtQcG2jmhGl5QWzvQaEEqQsOst2WY/9vs/egUILUtZIN59Dv4ZyTWwmSEyDnUx7luRtJar4qJUjT4RdsL+bI3xetzwolSMOwTn1Vgihmx2tsD+XAz4esrwolSMPxLZK9XGPS+qhQgmSCo2xbBPu3xfqoUIJkhh+yvSPQr3esbwolSOYYUp+UIIrZ8SzbM4L8ecb6pFCC6BNbWw8lSB7wLtt2AX5st74olCDikPWskfRZNSVIi2OKst2+c5P1QaEEEYuH2V7N4Lqv2msrlCDisa5FrqkEUSwIL7E93sDrPW6vqVCC5AaN0l/kVZ+iBGlxfMR2awOuc6u9lkIJkjvcwXagjuc/YK+hUILkEgnVdxeRDfYaCiVIbvEk2546nHePPbdCCZJ7rMvJORVKkEzwBtuOGp5vhz2nQgnSNMBu6uM1OM84Nedu80qQFscY1SYfx2Z7LoUSpOlwH9ubi/j9m/YcCiWIDth1YK4EaUU8z7Z7Ab/bbX+rUII0PdY36DcKJUgu8R7btnkcv83+RqEEaRncwnZkDscdsccqlCAthQrbDXM47gZ7rEIJ0nJ4lO2VE3z/ij1GoQRpWaxb4HcKJUhL4GW2XTN8vst+p1CCtDw+Oc6Y6/hEoQRpCRxm23rcv7fazxRKEIXFXZRuwBDZvxUC4GsIREHflguDkyQqaVYotIulUChBFAoliEKhBFEolCAKhRJEoVCCKBRKEIVCCaJQKJQgCoUSRKFQgigUShCFIhP8vwADACog5YM65zugAAAAAElFTkSuQmCC\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/logo.png\n// module id = 7Otq\n// module chunks = 5","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{\"id\":\"app\"}},[_c('b-container',{staticClass:\"p-4\"},[_c('b-row',[_c('b-col',[_c('b-img',{attrs:{\"center\":\"\",\"fluid\":\"\",\"src\":require('./assets/logo.png')}})],1)],1)],1),_vm._v(\" \"),_c('router-view')],1)}\nvar staticRenderFns = []\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-5ef42a84\",\"hasScoped\":false,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/App.vue\n// module id = null\n// module chunks = ","function injectStyle (ssrContext) {\n require(\"!!../node_modules/extract-text-webpack-plugin/dist/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-5ef42a84\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../node_modules/vue-loader/lib/selector?type=styles&index=0!./App.vue\")\n}\nvar normalizeComponent = require(\"!../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../node_modules/vue-loader/lib/selector?type=script&index=0!./App.vue\"\nimport __vue_script__ from \"!!babel-loader!../node_modules/vue-loader/lib/selector?type=script&index=0!./App.vue\"\n/* template */\nimport __vue_template__ from \"!!../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-5ef42a84\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../node_modules/vue-loader/lib/selector?type=template&index=0!./App.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/App.vue\n// module id = null\n// module chunks = ","\n \n \n \n \n \n \n \n \n \n \n\n \n
\n\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// src/App.vue","import Vue from 'vue'\nimport Router from 'vue-router'\nimport BootstrapVue from 'bootstrap-vue'\nimport 'bootstrap/dist/css/bootstrap.css'\nimport 'bootstrap-vue/dist/bootstrap-vue.css'\n\nconst routerOptions = [\n { path: '/', component: 'Home' },\n { path: '/about', component: 'About' },\n { path: '*', component: 'NotFound' }\n\n]\n\nconst routes = routerOptions.map(route => {\n return {\n ...route,\n component: () => import(`@/components/${route.component}.vue`)\n }\n})\n\nVue.use(Router)\nVue.use(BootstrapVue)\n\nexport default new Router({\n routes,\n mode: 'history'\n})\n\n\n\n// WEBPACK FOOTER //\n// ./src/router/index.js","import Vue from 'vue'\nimport App from './App'\nimport router from './router'\n\nVue.config.productionTip = false\n\n/* eslint-disable no-new */\nnew Vue({\n el: '#app',\n router,\n render: h => h(App)\n})\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","var map = {\n\t\"./About.vue\": [\n\t\t\"c27y\",\n\t\t3\n\t],\n\t\"./HelloWorld.vue\": [\n\t\t\"gORT\",\n\t\t1\n\t],\n\t\"./Home.vue\": [\n\t\t\"lO7g\",\n\t\t0\n\t],\n\t\"./NotFound.vue\": [\n\t\t\"YcJa\",\n\t\t2\n\t]\n};\nfunction webpackAsyncContext(req) {\n\tvar ids = map[req];\n\tif(!ids)\n\t\treturn Promise.reject(new Error(\"Cannot find module '\" + req + \"'.\"));\n\treturn __webpack_require__.e(ids[1]).then(function() {\n\t\treturn __webpack_require__(ids[0]);\n\t});\n};\nwebpackAsyncContext.keys = function webpackAsyncContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackAsyncContext.id = \"mUJ2\";\nmodule.exports = webpackAsyncContext;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components lazy ^\\.\\/.*\\.vue$\n// module id = mUJ2\n// module chunks = 5"],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/static/js/manifest.7a65f38077c246a526c7.js:
--------------------------------------------------------------------------------
1 | !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var i,u,f,s=0,l=[];s 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-vue-jsx", "transform-runtime"]
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/frontend/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 |
--------------------------------------------------------------------------------
/frontend/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parserOptions: {
6 | parser: 'babel-eslint'
7 | },
8 | env: {
9 | browser: true,
10 | },
11 | extends: [
12 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
13 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
14 | 'plugin:vue/essential',
15 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
16 | 'standard'
17 | ],
18 | // required to lint *.vue files
19 | plugins: [
20 | 'vue'
21 | ],
22 | // add your custom rules here
23 | rules: {
24 | // allow async-await
25 | 'generator-star-spacing': 'off',
26 | // allow debugger during development
27 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/frontend/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | # frontend
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/frontend/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/frontend/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec (cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/frontend/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youfulife/downloader/72963c68ed95dee5f2a754eb7d7360ae57e23de4/frontend/build/logo.png
--------------------------------------------------------------------------------
/frontend/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const packageConfig = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 |
12 | return path.posix.join(assetsSubDirectory, _path)
13 | }
14 |
15 | exports.cssLoaders = function (options) {
16 | options = options || {}
17 |
18 | const cssLoader = {
19 | loader: 'css-loader',
20 | options: {
21 | sourceMap: options.sourceMap
22 | }
23 | }
24 |
25 | const postcssLoader = {
26 | loader: 'postcss-loader',
27 | options: {
28 | sourceMap: options.sourceMap
29 | }
30 | }
31 |
32 | // generate loader string to be used with extract text plugin
33 | function generateLoaders (loader, loaderOptions) {
34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35 |
36 | if (loader) {
37 | loaders.push({
38 | loader: loader + '-loader',
39 | options: Object.assign({}, loaderOptions, {
40 | sourceMap: options.sourceMap
41 | })
42 | })
43 | }
44 |
45 | // Extract CSS when that option is specified
46 | // (which is the case during production build)
47 | if (options.extract) {
48 | return ExtractTextPlugin.extract({
49 | use: loaders,
50 | fallback: 'vue-style-loader'
51 | })
52 | } else {
53 | return ['vue-style-loader'].concat(loaders)
54 | }
55 | }
56 |
57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
58 | return {
59 | css: generateLoaders(),
60 | postcss: generateLoaders(),
61 | less: generateLoaders('less'),
62 | sass: generateLoaders('sass', { indentedSyntax: true }),
63 | scss: generateLoaders('sass'),
64 | stylus: generateLoaders('stylus'),
65 | styl: generateLoaders('stylus')
66 | }
67 | }
68 |
69 | // Generate loaders for standalone style files (outside of .vue)
70 | exports.styleLoaders = function (options) {
71 | const output = []
72 | const loaders = exports.cssLoaders(options)
73 |
74 | for (const extension in loaders) {
75 | const loader = loaders[extension]
76 | output.push({
77 | test: new RegExp('\\.' + extension + '$'),
78 | use: loader
79 | })
80 | }
81 |
82 | return output
83 | }
84 |
85 | exports.createNotifierCallback = () => {
86 | const notifier = require('node-notifier')
87 |
88 | return (severity, errors) => {
89 | if (severity !== 'error') return
90 |
91 | const error = errors[0]
92 | const filename = error.file && error.file.split('!').pop()
93 |
94 | notifier.notify({
95 | title: packageConfig.name,
96 | message: severity + ': ' + error.name,
97 | subtitle: filename || '',
98 | icon: path.join(__dirname, 'logo.png')
99 | })
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/frontend/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/frontend/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | const createLintingRule = () => ({
12 | test: /\.(js|vue)$/,
13 | loader: 'eslint-loader',
14 | enforce: 'pre',
15 | include: [resolve('src'), resolve('test')],
16 | options: {
17 | formatter: require('eslint-friendly-formatter'),
18 | emitWarning: !config.dev.showEslintErrorsInOverlay
19 | }
20 | })
21 |
22 | module.exports = {
23 | context: path.resolve(__dirname, '../'),
24 | entry: {
25 | app: './src/main.js'
26 | },
27 | output: {
28 | path: config.build.assetsRoot,
29 | filename: '[name].js',
30 | publicPath: process.env.NODE_ENV === 'production'
31 | ? config.build.assetsPublicPath
32 | : config.dev.assetsPublicPath
33 | },
34 | resolve: {
35 | extensions: ['.js', '.vue', '.json'],
36 | alias: {
37 | '@': resolve('src'),
38 | }
39 | },
40 | module: {
41 | rules: [
42 | ...(config.dev.useEslint ? [createLintingRule()] : []),
43 | {
44 | test: /\.vue$/,
45 | loader: 'vue-loader',
46 | options: vueLoaderConfig
47 | },
48 | {
49 | test: /\.js$/,
50 | loader: 'babel-loader',
51 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
52 | },
53 | {
54 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
55 | loader: 'url-loader',
56 | options: {
57 | limit: 10000,
58 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
59 | }
60 | },
61 | {
62 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
63 | loader: 'url-loader',
64 | options: {
65 | limit: 10000,
66 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
67 | }
68 | },
69 | {
70 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
71 | loader: 'url-loader',
72 | options: {
73 | limit: 10000,
74 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
75 | }
76 | }
77 | ]
78 | },
79 | node: {
80 | // prevent webpack from injecting useless setImmediate polyfill because Vue
81 | // source contains it (although only uses it if it's native).
82 | setImmediate: false,
83 | // prevent webpack from injecting mocks to Node native modules
84 | // that does not make sense for the client
85 | dgram: 'empty',
86 | fs: 'empty',
87 | net: 'empty',
88 | tls: 'empty',
89 | child_process: 'empty'
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/frontend/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const path = require('path')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11 | const portfinder = require('portfinder')
12 |
13 | const HOST = process.env.HOST
14 | const PORT = process.env.PORT && Number(process.env.PORT)
15 |
16 | const devWebpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
19 | },
20 | // cheap-module-eval-source-map is faster for development
21 | devtool: config.dev.devtool,
22 |
23 | // these devServer options should be customized in /config/index.js
24 | devServer: {
25 | clientLogLevel: 'warning',
26 | historyApiFallback: {
27 | rewrites: [
28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
29 | ],
30 | },
31 | hot: true,
32 | contentBase: false, // since we use CopyWebpackPlugin.
33 | compress: true,
34 | host: HOST || config.dev.host,
35 | port: PORT || config.dev.port,
36 | open: config.dev.autoOpenBrowser,
37 | overlay: config.dev.errorOverlay
38 | ? { warnings: false, errors: true }
39 | : false,
40 | publicPath: config.dev.assetsPublicPath,
41 | proxy: config.dev.proxyTable,
42 | quiet: true, // necessary for FriendlyErrorsPlugin
43 | watchOptions: {
44 | poll: config.dev.poll,
45 | }
46 | },
47 | plugins: [
48 | new webpack.DefinePlugin({
49 | 'process.env': require('../config/dev.env')
50 | }),
51 | new webpack.HotModuleReplacementPlugin(),
52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
53 | new webpack.NoEmitOnErrorsPlugin(),
54 | // https://github.com/ampedandwired/html-webpack-plugin
55 | new HtmlWebpackPlugin({
56 | filename: 'index.html',
57 | template: 'index.html',
58 | inject: true
59 | }),
60 | // copy custom static assets
61 | new CopyWebpackPlugin([
62 | {
63 | from: path.resolve(__dirname, '../static'),
64 | to: config.dev.assetsSubDirectory,
65 | ignore: ['.*']
66 | }
67 | ])
68 | ]
69 | })
70 |
71 | module.exports = new Promise((resolve, reject) => {
72 | portfinder.basePort = process.env.PORT || config.dev.port
73 | portfinder.getPort((err, port) => {
74 | if (err) {
75 | reject(err)
76 | } else {
77 | // publish the new Port, necessary for e2e tests
78 | process.env.PORT = port
79 | // add port to devServer config
80 | devWebpackConfig.devServer.port = port
81 |
82 | // Add FriendlyErrorsPlugin
83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
84 | compilationSuccessInfo: {
85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
86 | },
87 | onErrors: config.dev.notifyOnErrors
88 | ? utils.createNotifierCallback()
89 | : undefined
90 | }))
91 |
92 | resolve(devWebpackConfig)
93 | }
94 | })
95 | })
96 |
--------------------------------------------------------------------------------
/frontend/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const webpack = require('webpack')
5 | const config = require('../config')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
13 |
14 | const env = require('../config/prod.env')
15 |
16 | const webpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({
19 | sourceMap: config.build.productionSourceMap,
20 | extract: true,
21 | usePostCSS: true
22 | })
23 | },
24 | devtool: config.build.productionSourceMap ? config.build.devtool : false,
25 | output: {
26 | path: config.build.assetsRoot,
27 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
29 | },
30 | plugins: [
31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
32 | new webpack.DefinePlugin({
33 | 'process.env': env
34 | }),
35 | new UglifyJsPlugin({
36 | uglifyOptions: {
37 | compress: {
38 | warnings: false
39 | }
40 | },
41 | sourceMap: config.build.productionSourceMap,
42 | parallel: true
43 | }),
44 | // extract css into its own file
45 | new ExtractTextPlugin({
46 | filename: utils.assetsPath('css/[name].[contenthash].css'),
47 | // Setting the following option to `false` will not extract CSS from codesplit chunks.
48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
51 | allChunks: true,
52 | }),
53 | // Compress extracted CSS. We are using this plugin so that possible
54 | // duplicated CSS from different components can be deduped.
55 | new OptimizeCSSPlugin({
56 | cssProcessorOptions: config.build.productionSourceMap
57 | ? { safe: true, map: { inline: false } }
58 | : { safe: true }
59 | }),
60 | // generate dist index.html with correct asset hash for caching.
61 | // you can customize output by editing /index.html
62 | // see https://github.com/ampedandwired/html-webpack-plugin
63 | new HtmlWebpackPlugin({
64 | filename: config.build.index,
65 | template: 'index.html',
66 | inject: true,
67 | minify: {
68 | removeComments: true,
69 | collapseWhitespace: true,
70 | removeAttributeQuotes: true
71 | // more options:
72 | // https://github.com/kangax/html-minifier#options-quick-reference
73 | },
74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
75 | chunksSortMode: 'dependency'
76 | }),
77 | // keep module.id stable when vendor modules does not change
78 | new webpack.HashedModuleIdsPlugin(),
79 | // enable scope hoisting
80 | new webpack.optimize.ModuleConcatenationPlugin(),
81 | // split vendor js into its own file
82 | new webpack.optimize.CommonsChunkPlugin({
83 | name: 'vendor',
84 | minChunks (module) {
85 | // any required modules inside node_modules are extracted to vendor
86 | return (
87 | module.resource &&
88 | /\.js$/.test(module.resource) &&
89 | module.resource.indexOf(
90 | path.join(__dirname, '../node_modules')
91 | ) === 0
92 | )
93 | }
94 | }),
95 | // extract webpack runtime and module manifest to its own file in order to
96 | // prevent vendor hash from being updated whenever app bundle is updated
97 | new webpack.optimize.CommonsChunkPlugin({
98 | name: 'manifest',
99 | minChunks: Infinity
100 | }),
101 | // This instance extracts shared chunks from code splitted chunks and bundles them
102 | // in a separate chunk, similar to the vendor chunk
103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
104 | new webpack.optimize.CommonsChunkPlugin({
105 | name: 'app',
106 | async: 'vendor-async',
107 | children: true,
108 | minChunks: 3
109 | }),
110 |
111 | // copy custom static assets
112 | new CopyWebpackPlugin([
113 | {
114 | from: path.resolve(__dirname, '../static'),
115 | to: config.build.assetsSubDirectory,
116 | ignore: ['.*']
117 | }
118 | ])
119 | ]
120 | })
121 |
122 | if (config.build.productionGzip) {
123 | const CompressionWebpackPlugin = require('compression-webpack-plugin')
124 |
125 | webpackConfig.plugins.push(
126 | new CompressionWebpackPlugin({
127 | asset: '[path].gz[query]',
128 | algorithm: 'gzip',
129 | test: new RegExp(
130 | '\\.(' +
131 | config.build.productionGzipExtensions.join('|') +
132 | ')$'
133 | ),
134 | threshold: 10240,
135 | minRatio: 0.8
136 | })
137 | )
138 | }
139 |
140 | if (config.build.bundleAnalyzerReport) {
141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
143 | }
144 |
145 | module.exports = webpackConfig
146 |
--------------------------------------------------------------------------------
/frontend/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/frontend/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.3.1
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: false,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'cheap-module-eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | cssSourceMap: true
44 | },
45 |
46 | build: {
47 | // Template for index.html
48 | index: path.resolve(__dirname, '../../dist/index.html'),
49 |
50 | // Paths
51 | assetsRoot: path.resolve(__dirname, '../../dist'),
52 | assetsSubDirectory: 'static',
53 | assetsPublicPath: '/',
54 |
55 | /**
56 | * Source Maps
57 | */
58 |
59 | productionSourceMap: true,
60 | // https://webpack.js.org/configuration/devtool/#production
61 | devtool: '#source-map',
62 |
63 | // Gzip off by default as many popular static hosts such as
64 | // Surge or Netlify already gzip all static assets for you.
65 | // Before setting to `true`, make sure to:
66 | // npm install --save-dev compression-webpack-plugin
67 | productionGzip: false,
68 | productionGzipExtensions: ['js', 'css'],
69 |
70 | // Run the build command with an extra argument to
71 | // View the bundle analyzer report after build finishes:
72 | // `npm run build --report`
73 | // Set to `true` or `false` to always turn it on or off
74 | bundleAnalyzerReport: process.env.npm_config_report
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/frontend/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 极客生活-知乎视频下载
8 |
9 |
10 |
11 |
12 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "chenyoufu ",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "lint": "eslint --ext .js,.vue src",
11 | "build": "node build/build.js"
12 | },
13 | "dependencies": {
14 | "axios": "^0.18.0",
15 | "bootstrap-vue": "^2.0.0-rc.11",
16 | "vue": "^2.5.2",
17 | "vue-router": "^3.0.1"
18 | },
19 | "devDependencies": {
20 | "autoprefixer": "^7.1.2",
21 | "babel-core": "^6.22.1",
22 | "babel-eslint": "^8.2.1",
23 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
24 | "babel-loader": "^7.1.1",
25 | "babel-plugin-syntax-jsx": "^6.18.0",
26 | "babel-plugin-transform-runtime": "^6.22.0",
27 | "babel-plugin-transform-vue-jsx": "^3.5.0",
28 | "babel-preset-env": "^1.3.2",
29 | "babel-preset-stage-2": "^6.22.0",
30 | "chalk": "^2.0.1",
31 | "copy-webpack-plugin": "^4.0.1",
32 | "css-loader": "^0.28.0",
33 | "eslint": "^4.15.0",
34 | "eslint-config-standard": "^10.2.1",
35 | "eslint-friendly-formatter": "^3.0.0",
36 | "eslint-loader": "^1.7.1",
37 | "eslint-plugin-import": "^2.7.0",
38 | "eslint-plugin-node": "^5.2.0",
39 | "eslint-plugin-promise": "^3.4.0",
40 | "eslint-plugin-standard": "^3.0.1",
41 | "eslint-plugin-vue": "^4.0.0",
42 | "extract-text-webpack-plugin": "^3.0.0",
43 | "file-loader": "^1.1.4",
44 | "friendly-errors-webpack-plugin": "^1.6.1",
45 | "html-webpack-plugin": "^2.30.1",
46 | "node-notifier": "^5.1.2",
47 | "optimize-css-assets-webpack-plugin": "^3.2.0",
48 | "ora": "^1.2.0",
49 | "portfinder": "^1.0.13",
50 | "postcss-import": "^11.0.0",
51 | "postcss-loader": "^2.0.8",
52 | "postcss-url": "^7.2.1",
53 | "rimraf": "^2.6.0",
54 | "semver": "^5.3.0",
55 | "shelljs": "^0.7.6",
56 | "uglifyjs-webpack-plugin": "^1.1.1",
57 | "url-loader": "^0.5.8",
58 | "vue-loader": "^13.3.0",
59 | "vue-style-loader": "^3.0.1",
60 | "vue-template-compiler": "^2.5.2",
61 | "webpack": "^3.6.0",
62 | "webpack-bundle-analyzer": "^2.9.0",
63 | "webpack-dev-server": "^2.9.1",
64 | "webpack-merge": "^4.1.0"
65 | },
66 | "engines": {
67 | "node": ">= 6.0.0",
68 | "npm": ">= 3.0.0"
69 | },
70 | "browserslist": [
71 | "> 1%",
72 | "last 2 versions",
73 | "not ie <= 8"
74 | ]
75 | }
76 |
--------------------------------------------------------------------------------
/frontend/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
35 |
--------------------------------------------------------------------------------
/frontend/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youfulife/downloader/72963c68ed95dee5f2a754eb7d7360ae57e23de4/frontend/src/assets/logo.png
--------------------------------------------------------------------------------
/frontend/src/assets/qrcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youfulife/downloader/72963c68ed95dee5f2a754eb7d7360ae57e23de4/frontend/src/assets/qrcode.png
--------------------------------------------------------------------------------
/frontend/src/components/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/frontend/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
Essential Links
5 |
48 |
Ecosystem
49 |
83 |
84 |
85 |
86 |
96 |
97 |
98 |
114 |
--------------------------------------------------------------------------------
/frontend/src/components/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
18 | 下载
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 0
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
163 |
--------------------------------------------------------------------------------
/frontend/src/components/NotFound.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/frontend/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import router from './router'
4 |
5 | Vue.config.productionTip = false
6 |
7 | /* eslint-disable no-new */
8 | new Vue({
9 | el: '#app',
10 | router,
11 | render: h => h(App)
12 | })
13 |
--------------------------------------------------------------------------------
/frontend/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import BootstrapVue from 'bootstrap-vue'
4 | import 'bootstrap/dist/css/bootstrap.css'
5 | import 'bootstrap-vue/dist/bootstrap-vue.css'
6 |
7 | const routerOptions = [
8 | { path: '/', component: 'Home' },
9 | { path: '/about', component: 'About' },
10 | { path: '*', component: 'NotFound' }
11 |
12 | ]
13 |
14 | const routes = routerOptions.map(route => {
15 | return {
16 | ...route,
17 | component: () => import(`@/components/${route.component}.vue`)
18 | }
19 | })
20 |
21 | Vue.use(Router)
22 | Vue.use(BootstrapVue)
23 |
24 | export default new Router({
25 | routes,
26 | mode: 'history'
27 | })
28 |
--------------------------------------------------------------------------------
/frontend/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youfulife/downloader/72963c68ed95dee5f2a754eb7d7360ae57e23de4/frontend/static/.gitkeep
--------------------------------------------------------------------------------
/npm-debug.log:
--------------------------------------------------------------------------------
1 | 0 info it worked if it ends with ok
2 | 1 verbose cli [ '/usr/local/Cellar/node/8.0.0_1/bin/node',
3 | 1 verbose cli '/usr/local/bin/npm',
4 | 1 verbose cli 'run',
5 | 1 verbose cli 'dev' ]
6 | 2 info using npm@4.1.2
7 | 3 info using node@v8.0.0
8 | 4 verbose config Skipping project config: /Users/youfu/.npmrc. (matches userconfig)
9 | 5 verbose stack Error: ENOENT: no such file or directory, open '/Users/youfu/package.json'
10 | 6 verbose cwd /Users/youfu/downloader
11 | 7 error Darwin 16.7.0
12 | 8 error argv "/usr/local/Cellar/node/8.0.0_1/bin/node" "/usr/local/bin/npm" "run" "dev"
13 | 9 error node v8.0.0
14 | 10 error npm v4.1.2
15 | 11 error path /Users/youfu/package.json
16 | 12 error code ENOENT
17 | 13 error errno -2
18 | 14 error syscall open
19 | 15 error enoent ENOENT: no such file or directory, open '/Users/youfu/package.json'
20 | 16 error enoent ENOENT: no such file or directory, open '/Users/youfu/package.json'
21 | 16 error enoent This is most likely not a problem with npm itself
22 | 16 error enoent and is related to npm not being able to find a file.
23 | 17 verbose exit [ -2, true ]
24 |
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, render_template, jsonify, request, redirect, url_for
2 | from flask_cors import CORS
3 | from random import *
4 | from backend import zhihu
5 | # from furl import furl
6 | import sys
7 | import os
8 | import hashlib
9 | import redis
10 |
11 |
12 | basedir = os.path.abspath(os.path.dirname(__file__))
13 |
14 | # print(sys.path)
15 |
16 | app = Flask(__name__,
17 | static_folder="./dist/static",
18 | template_folder="./dist")
19 |
20 | app.config['JSON_AS_ASCII'] = False
21 |
22 | cors = CORS(app, resources={"/video/*": {"origins": "*"}})
23 |
24 | r = redis.Redis(host='localhost', port=6379, decode_responses=True)
25 |
26 |
27 | @app.route('/video/progress')
28 | def video_progress():
29 | filename = request.args.get('filename', None)
30 | if filename is None:
31 | return jsonify({
32 | 'status': 'failed',
33 | 'seconds': 0,
34 | "message": "参数filename为空"
35 | })
36 | key = hashlib.md5(filename.encode('utf-8')).hexdigest()
37 | value = r.get(key) or 0
38 |
39 | return jsonify({
40 | 'status': 'success',
41 | 'filename': filename,
42 | 'seconds': round(float(value)/1000000.0),
43 | "message": "当前下载进度"
44 | })
45 |
46 |
47 | @app.route('/video/zhihu', methods=['GET', 'POST'])
48 | def video_zhihu():
49 | if request.method == 'POST':
50 | content = request.get_json(silent=True)
51 | print(content)
52 | url = content.get('url', None)
53 | if url is None:
54 | return jsonify({
55 | "status": "error",
56 | "message": "下载失败,请稍后再试"
57 | })
58 | results = zhihu.download(url, directory=basedir)
59 | return jsonify(results)
60 |
61 | file = request.args.get('file')
62 | print("download file: ", file)
63 | file_path = 'video/zhihu/' + file
64 | return redirect(url_for('static', filename=file_path))
65 |
66 |
67 | @app.route('/', defaults={'path': ''})
68 | @app.route('/')
69 | def catch_all(path):
70 | return render_template("index.html")
71 |
72 |
73 | if __name__ == '__main__':
74 | app.run(host='127.0.0.1', debug=True)
75 |
--------------------------------------------------------------------------------
/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------