├── .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\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/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd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\"\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// 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 | 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 | 6 | -------------------------------------------------------------------------------- /frontend/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 85 | 86 | 96 | 97 | 98 | 114 | -------------------------------------------------------------------------------- /frontend/src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 163 | -------------------------------------------------------------------------------- /frontend/src/components/NotFound.vue: -------------------------------------------------------------------------------- 1 | 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 | --------------------------------------------------------------------------------