Remove redundant tables and code

This commit is contained in:
Deon George 2021-06-25 13:43:55 +10:00
parent 066154f310
commit bd85f8b055
22 changed files with 44 additions and 857 deletions

View File

@ -1,20 +0,0 @@
<?php
namespace App\Classes;
/**
* Class FileReceive
* @package App\Classes
*
* This class represents a file being received.
*/
class FileReceive {
public int $soff = 0;
public int $toff = 0;
public int $foff = 0;
public int $ttot = 0;
public int $stot = 0;
public int $nf = 0;
public int $allf = 0;
public int $start = 0;
}

View File

@ -1,21 +0,0 @@
<?php
namespace App\Classes;
/**
* Class FileSend
* @package App\Classes
*
* This class represents a file being sent.
*/
class FileSend {
public int $soff = 0;
public int $stot = 0;
public int $toff = 0;
public int $foff = 0;
public int $ttot = 0;
public int $nf = 0;
public int $allf = 0;
public int $cps = 1;
public int $start = 0;
}

View File

@ -5,7 +5,8 @@ namespace App\Classes\Protocol;
use Illuminate\Support\Facades\Log;
use League\Flysystem\UnreadableFileException;
use App\Classes\{FileReceive,Protocol,Protocol\Zmodem as ZmodemClass};
use App\Classes\Protocol;
use App\Classes\Protocol\Zmodem as ZmodemClass;
use App\Classes\File\{Receive,Send};
use App\Classes\Sock\{SocketClient,SocketException};
use App\Interfaces\CRC as CRCInterface;

View File

@ -1,73 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Classes\FTNPacket;
class FtnPkt extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ftn:pkt {file : Fidonet Packet File PKT} {--dump : Dump packet} {--detail : Dump Detail}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import Packet into Database';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$pkt = new FTNPacket($this->argument('file'));
$this->info(sprintf('Packet: %s has %s messages. Addr: %s->%s (Date: %s)',
$pkt->filename,
$pkt->messages->count(),
$pkt->pktsrc,
$pkt->pktdst,
$pkt->date
));
foreach ($pkt->messages as $o)
{
$this->warn(sprintf('-- From: %s(%s)->%s(%s), Type: %s, Size: %d',
$o->from,
$o->fqfa,
$o->to,
$o->fqda,
$o->type,
strlen($o->message)
));
if ($o->unknown->count())
$this->error(sprintf('?? %s Unknown headers',$o->unknown->count()));
}
if ($this->option('detail'))
dd($o);
if ($this->option('dump'))
echo $pkt->dump();
}
}

View File

@ -1,157 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Traits\ParseNodes;
use App\Classes\FTNPacket;
use App\Models\{Echomail,Netmail,Zone};
class ImportPacket extends Command
{
use ParseNodes;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'import:pkt {file : Packet File} {--f|force : Force import of duplicates}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import Mail Packet';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
* @throws \Exception
*/
public function handle()
{
$pkt = new FTNPacket($this->argument('file'));
foreach ($pkt->messages as $o)
{
$o->date->setTimezone(($o->tzutc >= 0 ? '+' : '').substr_replace($o->tzutc,':',2,0));
switch ($o->type)
{
case 'echomail':
// See if we already have this message.
$oo = Echomail::firstOrNew([
'date'=>$o->date,
'from_ftn'=>$this->get_node(['z'=>$o->fz,'n'=>$o->fn,'f'=>$o->ff,'p'=>$o->fp])->id,
'msgid'=>$o->msgid,
]);
if (md5(utf8_decode($eo->message)) == md5($o->message))
{
$this->warn(sprintf('Duplicate message: %s@%s with id: %s',$o->from,$o->fqfa,$o->msgid));
break 2;
}
break;
case 'netmail':
// See if we already have this message.
$oo = Netmail::firstOrNew([
'date'=>$o->date,
'from_ftn'=>$this->get_node(['z'=>$o->fz,'n'=>$o->fn,'f'=>$o->ff,'p'=>$o->fp])->id,
'msgid'=>$o->msgid,
]);
$oo->to_ftn = $this->get_node(['z'=>$o->tz,'n'=>$o->tn,'f'=>$o->tf,'p'=>$o->tp])->id;
break;
default:
abort(500,'Unknown type: '.$o->type);
}
if (md5(utf8_decode($oo->message)) == md5($o->message))
{
$this->warn(sprintf('Duplicate message: %s@%s with id: %s',$o->from,$o->fqfa,$o->msgid));
if (! $this->option('force'))
continue;
}
$oo->pkt_from = $this->get_node(['z'=>$pkt->sz,'n'=>$pkt->sn,'f'=>$pkt->sf,'p'=>$pkt->sp])->id;
$oo->pkt_to = $this->get_node(['z'=>$pkt->dz,'n'=>$pkt->dn,'f'=>$pkt->df,'p'=>$pkt->dp])->id;
$oo->pkt = $pkt->filename;
$oo->pkt_date = $pkt->date;
$oo->flags = $o->flags;
$oo->cost = $o->cost;
$oo->from_user = utf8_encode($o->from);
$oo->to_user = utf8_encode($o->to);
$oo->subject = utf8_encode($o->subject);
$oo->tz = $o->tzutc;
$oo->replyid = $o->replyid;
$oo->message = utf8_encode($o->message);
$oo->origin = utf8_encode($o->origin);
$oo->save();
foreach ($o->kludge as $k=>$v)
{
$oo->kludges()->attach($k,['value'=>json_encode($v)]);
}
foreach ($o->unknown as $v)
{
$oo->kludges()->attach('UNKNOWN',['value'=>json_encode($v)]);
}
// Finish off the import
switch($o->type) {
case 'echomail':
foreach ($o->seenby as $v)
{
foreach ($this->parse_nodes(Zone::findOrFail($pkt->sz),$v) as $no)
{
$oo->seenbys()->attach($no->id);
}
}
$seq = 0;
foreach ($o->path as $v)
{
foreach ($this->parse_nodes(Zone::findOrFail($pkt->sz),$v) as $no)
{
$oo->paths()->attach($no->id,['sequence'=>$seq++]);
}
}
break;
case 'netmail':
$seq = 0;
foreach ($o->via as $v)
{
$data = preg_split('/\s/',$v);
$ftno = $this->get_node(ftn_address_split($data[0]));
unset($data[0]);
$oo->paths()->attach($ftno->id,['sequence'=>$seq++,'value'=>json_encode($data)]);
}
break;
}
}
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Node;
class NodeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Add or edit a node
*/
public function add_edit(Request $request,Node $o)
{
if ($request->post()) {
foreach ([
'zone_id','host_id','node_id','point_id',
'system','sysop','location','email',
'address','port','notes','software_id','protocol_id',
'sespass','pktpass','ticpass','fixpass'
] as $key)
$o->{$key} = $request->post($key);
foreach(['is_zc','is_rc','is_hub','is_host','active'] as $key)
$o->{$key} = $request->post($key,FALSE);
$o->save();
return redirect()->action([self::class,'home']);
}
return view('node.addedit')
->with('o',$o);
}
public function home()
{
return view('node.home');
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flag extends Model
{
protected $fillable = ['flag'];
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Kludge extends Model
{
//
}

View File

@ -1,123 +0,0 @@
<?php
namespace App\Models;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use App\Traits\ScopeActive;
class Node extends Model
{
use ScopeActive;
protected $casts = [
'is_zc'=>'boolean',
'is_rc'=>'boolean',
'is_hub'=>'boolean',
'is_host'=>'boolean',
];
protected $fillable = ['zone_id','host_id','node_id','point_id'];
/* SCOPES */
public function scopeHost()
{
// @todo
}
/* RELATIONS */
/**
* Node nodelist flags
*
* @return BelongsToMany
*/
public function flags()
{
return $this->belongsToMany(Flag::class);
}
public function zone()
{
return $this->belongsTo(Zone::class);
}
/* ATTRIBUTES */
/**
* Render the node name in full 5D
*
* @return string
*/
public function getFTNAttribute()
{
return $this->zone_id
? sprintf('%d:%d/%d.%d@%s',$this->zone->zone_id,$this->host_id,$this->node_id,$this->point_id,$this->zone->domain->name)
: '-';
}
/**
* Get this nodes uplink
*/
public function getUplinkAttribute()
{
// @todo Need to work this out properly
return static::where('zone_id','10')->where('host_id',1)->where('node_id',0)->where('point_id',0)->first();
}
/* METHODS */
/**
* Find a record in the DB for a node string, eg: 10:1/1.0
*
* @param string $ftn
* @return Node|null
* @throws Exception
*/
public static function findFTN(string $ftn): ?self
{
$matches = [];
// @todo domain can have more chars.
if (! preg_match('#^([0-9]+):([0-9]+)/([0-9]+)(.([0-9]+))?(@([a-z]{0,8}))?$#',strtolower($ftn),$matches))
throw new Exception('Invalid FTN: '.$ftn);
// Check our numbers are correct.
foreach ([1,2,3] as $i) {
if (! $matches[$i] || ($matches[$i] > 0xffff))
throw new Exception('Invalid FTN: '.$ftn);
}
if (isset($matches[5]) AND $matches[5] > 0xffff)
throw new Exception('Invalid FTN: '.$ftn);
return (new self)->active()
->select('nodes.*')
->where('zones.zone_id',$matches[1])
->where(function($query) use ($matches) {
$query->where('hub_id',$matches[2])
->orWhere('host_id',$matches[2]);
})
->join('zones',['zones.id'=>'nodes.zone_id'])
->join('domains',['domains.id'=>'zones.domain_id'])
->where('zones.active',TRUE)
->where('node_id',$matches[3])
->where('point_id',(isset($matches[5]) AND $matches[5]) ? $matches[5] : 0)
->when(isset($matches[7]),function($query) use ($matches) {
$query->where('domains.name',$matches[7]);
})
->when((! isset($matches[7]) OR ! $matches[7]),function($query) {
$query->where('domains.default',TRUE);
})
->single();
}
public function hasFlag($relation,$model): bool
{
return (bool) $this->{$relation}()
->wherePivot($model->getForeignKey(),$model->{$model->getKeyName()})
->count();
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Path extends Model
{
//
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Seenby extends Model
{
//
}

View File

@ -1,32 +0,0 @@
<?php
namespace App\Traits;
use App\Models\Zone;
trait ParseNodes
{
/**
* Parse a seenby or path list and return node models
*/
protected function parse_nodes(Zone $zo,string $line,$create=TRUE)
{
$net = FALSE;
$result = collect();
foreach (explode(' ',$line) as $node)
{
if (preg_match('#/#',$node))
{
list($net,$node) = preg_split('#/#',$node);
}
if (! $net)
throw new \Exception('Missing Net?',$node);
$result->push($this->get_node(['z'=>$zo->id,'n'=>$net,'f'=>$node,'p'=>0],$create));
}
return $result;
}
}

View File

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class DropNode extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::dropIfExists('echomail_kludge');
Schema::dropIfExists('echomail_path');
Schema::dropIfExists('echomail_seenby');
Schema::dropIfExists('kludge_netmail');
Schema::dropIfExists('netmail_path');
Schema::dropIfExists('flag_node');
Schema::dropIfExists('kludges');
Schema::dropIfExists('paths');
Schema::dropIfExists('seenbys');
Schema::dropIfExists('flags');
Schema::dropIfExists('echomails');
Schema::dropIfExists('netmails');
Schema::dropIfExists('node_setup');
Schema::dropIfExists('node_system');
Schema::dropIfExists('nodes');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

36
resources/js/app.js vendored
View File

@ -1,36 +0,0 @@
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
Vue.component('example-component', require('./components/ExampleComponent.vue'));
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => {
// return Vue.component(_.last(key.split('/')).split('.')[0], files(key))
// })
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app'
});

View File

@ -1,28 +0,0 @@
window._ = require('lodash');
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// forceTLS: true
// });

View File

@ -1,23 +0,0 @@
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card card-default">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>

View File

@ -1,20 +0,0 @@
// Body
$body-bg: #f8fafc;
// Typography
$font-family-sans-serif: "Nunito", sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
// Colors
$blue: #3490dc;
$indigo: #6574cd;
$purple: #9561e2;
$pink: #f66D9b;
$red: #e3342f;
$orange: #f6993f;
$yellow: #ffed4a;
$green: #38c172;
$teal: #4dc0b5;
$cyan: #6cb2eb;

View File

@ -1,14 +0,0 @@
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
.navbar-laravel {
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
}

View File

@ -1,166 +0,0 @@
@extends('layouts.app')
@section('htmlheader_title')
@if($o->exists) Update @else Add @endif Node
@endsection
@section('main-content')
<div class="pb-3">
<h2>@if($o->exists) Update @else Add @endif Node</h2>
<form method="POST">
{{ csrf_field() }}
<div class="row">
<div class="col-3">
<div class="bg-blue">
<div class="row m-3">
<label class="col-3" for="zone_id">Zone</label>
<select class="col-9" name="zone_id">
<option value="">&nbsp;</option>
@foreach (\App\Models\Zone::cursor() as $oo)
<option value="{{ $oo->id }}" @if($o->zone_id==$oo->id)selected @endif>{{ $oo->zone_id }} ({{ $oo->name }})</option>
@endforeach
</select>
</div>
<div class="row m-3">
<label class="col-3" for="host_id">Hub</label>
<select class="col-9" name="hub_id">
<option value="{{ $o->hub_id }}" disabled>{{ $o->hub_id }} ({{ $o->system }})</option>
</select>
</div>
<div class="row m-3">
<label class="col-3" for="host_id">Host</label>
<select class="col-9" name="host_id">
<option value="{{ $o->host_id }}" selected>{{ $o->host_id }} ({{ $o->system }})</option>
</select>
</div>
<div class="row m-3">
<label class="col-3" for="node_id">Node</label>
<input class="col-9" type="text" name="node_id" value="{{ $o->node_id }}">
</div>
<div class="row m-3">
<label class="col-3" for="point_id">Point</label>
<input class="col-9" type="text" name="point_id" value="{{ $o->point_id ?: 0 }}">
</div>
<hr>
<div class="row m-3">
<label class="col-4" for="is_rc">Is ZC</label>
<input class="col-3" type="checkbox" name="is_rc" value="1" @if($o->is_rc)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="is_rc">Is RC</label>
<input class="col-3" type="checkbox" name="is_rc" value="1" @if($o->is_regis_rcion)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="is_hub">Is Hub</label>
<input class="col-3" type="checkbox" name="is_hub" value="1" @if($o->is_hub)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="is_host">Is Host</label>
<input class="col-3" type="checkbox" name="is_host" value="1" @if($o->is_host)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="active">Active</label>
<input class="col-3" type="checkbox" name="active" value="1" @if($o->active)checked @endif>
</div>
</div>
</div>
<div class="col-9">
<div class="bg-blue">
<div class="row m-3">
<label class="col-3" for="system">BBS Name:</label>
<input class="col-9" type="text" name="system" value="{{ $o->system }}">
</div>
<div class="row m-3">
<label class="col-3" for="sysop">SYSOP Name:</label>
<input class="col-9" type="text" name="sysop" value="{{ $o->sysop }}">
</div>
<div class="row m-3">
<label class="col-3" for="email">Email Address:</label>
<input class="col-9" type="email" name="email" value="{{ $o->email }}">
</div>
<div class="row m-3">
<label class="col-3" for="location">System Location:</label>
<input class="col-9" type="text" name="location" value="{{ $o->location }}">
</div>
<div class="row m-3">
<label class="col-2" for="protocol_id">Connection Method:</label>
<div class="form-group col-2">
@foreach (\App\Models\Protocol::cursor() as $oo)
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" name="protocol_id" id="{{ $oo->id }}" value="{{ $oo->id }}" required @if($o->protocol_id==$oo->id)checked @endif>
<label class="custom-control-label" for="{{ $oo->id }}">{{ $oo->name }}</label>
</div>
@endforeach
</div>
<div class="col-8">
<div class="row m-3">
<label class="col-4" for="address">Mailer Address:</label>
<input class="col-8" type="text" name="address" value="{{ $o->address }}">
</div>
<div class="row m-3">
<label class="col-4" for="port">Mailer Port:</label>
<input class="col-4" type="text" name="port" value="{{ $o->port }}">
</div>
<div class="row m-3">
<label class="col-4" for="software_id">Mailer Software:</label>
<select class="col-8" name="software_id">
<option value="">&nbsp;</option>
@foreach (\App\Models\Software::cursor() as $oo)
<option value="{{ $oo->id }}" @if($o->protocol_id==$oo->id)selected @endif>{{ $oo->name }}</option>
@endforeach
</select>
</div>
<div class="row m-3">
<label class="col-4" for="sespass">Session Password:</label>
<input class="col-4" type="text" name="sespass" value="{{ $o->sespass }}">
</div>
<div class="row m-3">
<label class="col-4" for="pktpass">Packet Password:</label>
<input class="col-4" type="text" name="pktpass" value="{{ $o->pktpass }}">
</div>
<div class="row m-3">
<label class="col-4" for="ticpass">TIC Password:</label>
<input class="col-4" type="text" name="ticpass" value="{{ $o->ticpass }}">
</div>
<div class="row m-3">
<label class="col-4" for="fixpass">Areafix Password:</label>
<input class="col-4" type="text" name="fixpass" value="{{ $o->fixpass }}">
</div>
</div>
</div>
<div class="row m-3">
<label class="col-3" for="notes">Notes:</label>
<textarea class="col-9" rows=3 cols=68 name="notes" placeholder="Notes...">{{ $o->notes }}</textarea>
</div>
<div class="row m-3">
<div class="col-12">
<button type="submit" name="submit" class="btn btn-lg btn-success mr-0 float-right">@if ($o->exists)Save @else Add @endif</button>
<a href="{{ url('/') }}" class="btn btn-lg btn-primary float-right">Cancel</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@ -1,49 +0,0 @@
@extends('layouts.app')
@section('main-content')
<div class="row">
<div class="col-6">
<table class="table table-bordered m-5">
<thead>
<tr>
<th>ID</th>
<th>Domain</th>
<th>Node</th>
<th>Active</th>
<th>System</th>
<th>Sysop</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4"><a href="{{ url('ftn/node/addedit') }}">Add New Node</a></td>
</tr>
@foreach (\App\Models\Node::with(['zone'])->cursor() as $oo)
<tr>
<td><a href="{{ url('ftn/node/addedit',[$oo->id]) }}">{{ $oo->id }}</a></td>
<td>@if ($oo->zone_id){{ $oo->zone->name }}@else - @endif</td>
<td>{{ $oo->ftn }}</td>
<td>{{ $oo->active ? 'YES' : 'NO' }}</td>
<td>{{ $oo->system }}</td>
<td>{{ $oo->sysop }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function() {
$('table tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
</script>
@append

View File

@ -35,10 +35,6 @@ Route::middleware(['verified','activeuser'])->group(function () {
Route::match(['get','post'],'ftn/domain/addedit/{o?}',[DomainController::class,'add_edit'])
->where('o','[0-9]+');
Route::get('ftn/node',[NodeController::class,'home']);
Route::match(['get','post'],'ftn/node/addedit/{o?}',[NodeController::class,'add_edit'])
->where('o','[0-9]+');
Route::get('ftn/system',[SystemController::class,'home']);
Route::match(['get','post'],'ftn/system/addedit/{o?}',[SystemController::class,'add_edit'])
->where('o','[0-9]+');

View File

@ -23,8 +23,6 @@ class SiteAdminTest extends TestCase
$this->get('ftn/domain')
->assertRedirect('login');
$this->get('ftn/node')
->assertRedirect('login');
$this->get('ftn/zone')
->assertRedirect('login');
@ -55,8 +53,6 @@ class SiteAdminTest extends TestCase
$this->get('ftn/domain')
->assertRedirect('email/verify');
$this->get('ftn/node')
->assertRedirect('email/verify');
$this->get('ftn/zone')
->assertRedirect('email/verify');