104 lines
3.0 KiB
PHP
104 lines
3.0 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace App\Console\Commands\BBS;
|
||
|
|
||
|
use Illuminate\Console\Command;
|
||
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||
|
|
||
|
use App\Models\BBS\{Frame,Mode};
|
||
|
use Illuminate\Support\Arr;
|
||
|
|
||
|
class FrameImport extends Command
|
||
|
{
|
||
|
/**
|
||
|
* The name and signature of the console command.
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $signature = 'frame:import {frame} {file} '.
|
||
|
'{--index=a : The frame index }'.
|
||
|
'{--access=0 : Is frame accessible }'.
|
||
|
'{--public=0 : Is frame limited to CUG }'.
|
||
|
'{--cost=0 : Frame Cost }'.
|
||
|
'{--mode=Ansi : Frame Emulation Mode }'.
|
||
|
'{--replace : Replace existing frame}'.
|
||
|
'{--type=i : Frame Type}'.
|
||
|
'{--title= : Frame Title}'.
|
||
|
'{--keys= : Key Destinations [0,1,2,3,4,5,6,7,8,9]}'.
|
||
|
'{--trim= : Trim off header (first n chars)}';
|
||
|
|
||
|
/**
|
||
|
* The console command description.
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $description = 'Import frames into the database. The frames should be in binary format.';
|
||
|
|
||
|
/**
|
||
|
* Execute the console command.
|
||
|
*
|
||
|
* @return mixed
|
||
|
* @throws \Exception
|
||
|
*/
|
||
|
public function handle()
|
||
|
{
|
||
|
if (! is_numeric($this->argument('frame')))
|
||
|
throw new \Exception('Frame is not numeric: '.$this->argument('frame'));
|
||
|
|
||
|
if ((strlen($this->option('index')) !== 1) || (! preg_match('/^[a-z]$/',$this->option('index'))))
|
||
|
throw new \Exception('Subframe failed validation');
|
||
|
|
||
|
if (! file_exists($this->argument('file')))
|
||
|
throw new \Exception('File not found: '.$this->argument('file'));
|
||
|
|
||
|
$mo = Mode::where('name',$this->option('mode'))->firstOrFail();
|
||
|
|
||
|
$o = new Frame;
|
||
|
if ($this->option('replace')) {
|
||
|
try {
|
||
|
$o = $o->where('frame',$this->argument('frame'))
|
||
|
->where('index',$this->option('index'))
|
||
|
->where('mode_id',$mo->id)
|
||
|
->orderBy('created_at','DESC')
|
||
|
->firstOrNew();
|
||
|
|
||
|
} catch (ModelNotFoundException $e) {
|
||
|
$this->error('Frame not found to replace: '.$this->argument('frame').$this->option('index'));
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$o->frame = $this->argument('frame');
|
||
|
$o->index = $this->option('index');
|
||
|
$o->mode_id = $mo->id;
|
||
|
$o->access = $this->option('access');
|
||
|
$o->public = $this->option('public');
|
||
|
$o->cost = $this->option('cost');
|
||
|
$o->type = $this->option('type');
|
||
|
$o->title = $this->option('title');
|
||
|
|
||
|
$keys = [];
|
||
|
if ($this->option('keys'))
|
||
|
$keys = explode(',',$this->option('keys'));
|
||
|
|
||
|
foreach (range(0,9) as $key) {
|
||
|
$index = sprintf('r%d',$key);
|
||
|
|
||
|
$o->{$index} = (($x=Arr::get($keys,$key,NULL)) === "null") ? NULL : $x;
|
||
|
}
|
||
|
|
||
|
// We need to escape any back slashes, so they dont get interpretted as hex
|
||
|
$o->content = $this->option('trim')
|
||
|
? substr(file_get_contents($this->argument('file')),$this->option('trim'))
|
||
|
: file_get_contents($this->argument('file'));
|
||
|
|
||
|
// If we have 0x1aSAUCE, we'll discard the sauce.
|
||
|
if ($x = strpos($o->content,chr(0x1a).'SAUCE')) {
|
||
|
$o->content = substr($o->content,0,$x-1).chr(0x0a);
|
||
|
}
|
||
|
|
||
|
$o->save();
|
||
|
|
||
|
$this->info(sprintf('Saved frame: [%s] as [%s] with [%d]',$o->page,$mo->name,$o->id));
|
||
|
}
|
||
|
}
|