Completed
Push — master ( a4261d...fc5e52 )
by John
14s
created

BabelRequire   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 2
Metric Value
eloc 62
dl 0
loc 110
rs 10
c 5
b 0
f 2
wmc 23

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A delDir() 0 12 4
C handle() 0 59 17
A postProc() 0 4 1
1
<?php
2
3
namespace App\Console\Commands\Babel;
4
5
use Illuminate\Console\Command;
6
use Exception;
7
use PhpZip\ZipFile;
8
use Symfony\Component\Console\Output\BufferedOutput;
9
10
class BabelRequire extends Command
11
{
12
    /**
13
     * The name and signature of the console command.
14
     *
15
     * @var string
16
     */
17
    protected $signature = 'babel:require {extension : The package name of the extension} {--exception}';
18
19
    /**
20
     * The console command description.
21
     *
22
     * @var string
23
     */
24
    protected $description = 'Download a given Babel Extension to NOJ';
25
26
    /**
27
     * Create a new command instance.
28
     *
29
     * @return void
30
     */
31
    public function __construct()
32
    {
33
        parent::__construct();
34
    }
35
36
    /**
37
     * Execute the console command.
38
     *
39
     * @return mixed
40
     */
41
    public function handle()
42
    {
43
        $extension = $this->argument('extension');
44
        $exception = $this->option('exception');
45
        $output = new BufferedOutput();
46
        if(is_dir(babel_path("Extension/$extension/"))) {
47
            if(!$exception) $this->line("\n  <bg=red;fg=white> Exception </> : <fg=yellow>An extension named <fg=green>$extension</> already took place, did you mean <fg=green>php artisan bable:update $extension</>?</>\n");
48
            else throw new Exception("\n  <bg=red;fg=white> Exception </> : <fg=yellow>An extension named <fg=green>$extension</> already took place, did you mean <fg=green>php artisan bable:update $extension</>?</>\n");
49
            return;
50
        }
51
        $marketspaceRaw=json_decode(file_get_contents(env("BABEL_MIRROR","https://acm.njupt.edu.cn/babel")."/babel.json"),true);
52
        $marketspacePackages=$marketspaceRaw["packages"];
53
        $marketspaceHash=$marketspaceRaw["content-hash"];
0 ignored issues
show
Unused Code introduced by
The assignment to $marketspaceHash is dead and can be removed.
Loading history...
54
        $packageCodeColumn=array_column($marketspacePackages, 'code');
55
        $targetPackage=$marketspacePackages[array_search($extension, $packageCodeColumn)];
56
        // if(!isset($targetPackage["downloadURL"]) || trim($targetPackage["downloadURL"])=="" || is_null($targetPackage["downloadURL"])){
57
        if(!isset($targetPackage["downloadURL"]) || !is_array($targetPackage["downloadURL"]) || is_null($targetPackage["downloadURL"]) || !isset($targetPackage["downloadURL"][0]["url"]) || trim($targetPackage["downloadURL"][0]["url"])=="" || is_null($targetPackage["downloadURL"][0]["url"])){
58
            if(!$exception) $this->line("\n  <bg=red;fg=white> Exception </> : <fg=yellow>No available download link.</>\n");
59
            else throw new Exception("\n  <bg=red;fg=white> Exception </> : <fg=yellow>No available download link.</>\n");
60
            return;
61
        }
62
        //todo: check requirements
63
        $this->line("Downloading <fg=green>$extension</>(<fg=yellow>{$targetPackage['version']}</>)");
64
        $filename="$extension-".basename($targetPackage["downloadURL"][0]["url"]);
65
        file_put_contents(babel_path("Tmp/$filename"),file_get_contents($targetPackage["downloadURL"][0]["url"]));
66
        // unzip
67
        if(!is_dir(babel_path("Tmp/$extension/"))) mkdir(babel_path("Tmp/$extension/"));
68
        try {
69
            $zipFile = new ZipFile();
70
            $zipFile->openFile(babel_path("Tmp/$filename"))->extractTo(babel_path("Tmp/$extension/"))->close();
71
            $babelPath=glob_recursive(babel_path("Tmp/$extension/babel.json"));
72
            if(empty($babelPath)){
73
                if(!$exception) $this->line("\n  <bg=red;fg=white> Exception </> : <fg=yellow>There exists no <fg=green>babel.json</> files.</>\n");
74
                else throw new Exception("\n  <bg=red;fg=white> Exception </> : <fg=yellow>No available download link.</>\n");
75
                return;
76
            } else {
77
                $babelPath=dirname($babelPath[0]);
78
                // if(is_dir(babel_path("Extension/$extension/"))) mkdir(babel_path("Extension/$extension/"));
79
                rename($babelPath,babel_path("Extension/$extension/"));
80
            }
81
        } catch(\PhpZip\Exception\ZipException $e) {
82
            $this->postProc($filename,$extension);
83
            if(!$exception) $this->line("\n  <bg=red;fg=white> Exception </> : <fg=yellow>An error occoured when extract <fg=green>$extension</>.</>\n");
84
            else {
85
                throw new Exception("\n  <bg=red;fg=white> Exception </> : <fg=yellow>An error occoured when extract <fg=green>$extension</>.</>\n");
86
            }
87
            return;
88
        } catch(Exception $e){
89
            $this->postProc($filename,$extension);
90
            if(!$exception) $this->line("\n  <bg=red;fg=white> Exception </> : <fg=yellow>An error occoured when extract <fg=green>$extension</>.</>\n");
91
            else {
92
                throw new Exception("\n  <bg=red;fg=white> Exception </> : <fg=yellow>An error occoured when extract <fg=green>$extension</>.</>\n");
93
            }
94
            return;
95
        }
96
        $this->postProc($filename,$extension);
97
        $this->line("Downloaded <fg=green>$extension</>(<fg=yellow>{$targetPackage['version']}</>)");
98
        $this->call("babel:install", ['extension' => $extension]);
99
        $output->fetch();
100
    }
101
102
    private function postProc($filename,$extension)
103
    {
104
        unlink(babel_path("Tmp/$filename"));
105
        $this->delDir(babel_path("Tmp/$extension/"));
106
    }
107
108
    private function delDir($dir){
109
        if(!is_dir($dir)) return;
110
        $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS);
111
        $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST);
112
        foreach($files as $file) {
113
            if ($file->isDir()){
114
                rmdir($file->getRealPath());
115
            } else {
116
                unlink($file->getRealPath());
117
            }
118
        }
119
        rmdir($dir);
120
    }
121
}
122