moved login scripts processing into tabby-terminal

This commit is contained in:
Eugene Pankov
2021-07-05 23:56:38 +02:00
parent 461cd2bec7
commit bf762cc4c7
16 changed files with 270 additions and 344 deletions

View File

@@ -1,22 +1,15 @@
import stripAnsi from 'strip-ansi'
import SerialPort from 'serialport'
import { Logger, LogService, NotificationsService, Profile } from 'tabby-core'
import { LogService, NotificationsService, Profile } from 'tabby-core'
import { Subject, Observable } from 'rxjs'
import { Injector, NgZone } from '@angular/core'
import { BaseSession, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
export interface LoginScript {
expect: string
send: string
isRegex?: boolean
optional?: boolean
}
import { BaseSession, LoginScriptsOptions, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
export interface SerialProfile extends Profile {
options: SerialProfileOptions
}
export interface SerialProfileOptions extends StreamProcessingOptions {
export interface SerialProfileOptions extends StreamProcessingOptions, LoginScriptsOptions {
port: string
baudrate?: number
databits?: number
@@ -26,7 +19,6 @@ export interface SerialProfileOptions extends StreamProcessingOptions {
xon?: boolean
xoff?: boolean
xany?: boolean
scripts?: LoginScript[]
color?: string
}
@@ -40,9 +32,7 @@ export interface SerialPortInfo {
}
export class SerialSession extends BaseSession {
scripts?: LoginScript[]
serial: SerialPort
logger: Logger
get serviceMessage$ (): Observable<string> { return this.serviceMessage }
private serviceMessage = new Subject<string>()
@@ -51,62 +41,20 @@ export class SerialSession extends BaseSession {
private notifications: NotificationsService
constructor (injector: Injector, public profile: SerialProfile) {
super()
this.logger = injector.get(LogService).create(`serial-${profile.options.port}`)
super(injector.get(LogService).create(`serial-${profile.options.port}`))
this.zone = injector.get(NgZone)
this.notifications = injector.get(NotificationsService)
this.scripts = profile.options.scripts ?? []
this.streamProcessor = new TerminalStreamProcessor(profile.options)
this.streamProcessor.outputToSession$.subscribe(data => {
this.serial?.write(data.toString())
})
this.streamProcessor.outputToTerminal$.subscribe(data => {
this.emitOutput(data)
const dataString = data.toString()
if (this.scripts) {
let found = false
for (const script of this.scripts) {
let match = false
let cmd = ''
if (script.isRegex) {
const re = new RegExp(script.expect, 'g')
if (re.test(dataString)) {
cmd = dataString.replace(re, script.send)
match = true
found = true
}
} else {
if (dataString.includes(script.expect)) {
cmd = script.send
match = true
found = true
}
}
if (match) {
this.logger.info('Executing script: "' + cmd + '"')
this.serial.write(cmd + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
if (script.optional) {
this.logger.debug('Skip optional script: ' + script.expect)
found = true
this.scripts = this.scripts.filter(x => x !== script)
} else {
break
}
}
}
if (found) {
this.executeUnconditionalScripts()
}
}
this.loginScriptProcessor?.feedFromSession(data)
})
this.setLoginScriptsOptions(profile.options)
}
async start (): Promise<void> {
@@ -151,6 +99,7 @@ export class SerialSession extends BaseSession {
})
this.open = true
setTimeout(() => this.streamProcessor.start())
this.serial.on('readable', () => {
this.streamProcessor.feedFromSession(this.serial.read())
@@ -163,7 +112,7 @@ export class SerialSession extends BaseSession {
}
})
this.executeUnconditionalScripts()
this.loginScriptProcessor?.executeUnconditionalScripts()
}
write (data: Buffer): void {
@@ -205,18 +154,4 @@ export class SerialSession extends BaseSession {
async getWorkingDirectory (): Promise<string|null> {
return null
}
private executeUnconditionalScripts () {
if (this.scripts) {
for (const script of this.scripts) {
if (!script.expect) {
console.log('Executing script:', script.send)
this.serial.write(script.send + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
break
}
}
}
}
}

View File

@@ -80,43 +80,6 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
li(ngbNavItem)
a(ngbNavLink) Login scripts
ng-template(ngbNavContent)
table(*ngIf='profile.options.scripts.length > 0')
tr
th String to expect
th String to be sent
th.pl-2 Regex
th.pl-2 Optional
th.pl-2 Actions
tr(*ngFor='let script of profile.options.scripts')
td.pr-2
input.form-control(
type='text',
[(ngModel)]='script.expect'
)
td
input.form-control(
type='text',
[(ngModel)]='script.send'
)
td.pl-2
checkbox(
[(ngModel)]='script.isRegex',
)
td.pl-2
checkbox(
[(ngModel)]='script.optional',
)
td.pl-2
.input-group.flex-nowrap
button.btn.btn-outline-info.ml-0((click)='moveScriptUp(script)')
i.fas.fa-arrow-up
button.btn.btn-outline-info.ml-0((click)='moveScriptDown(script)')
i.fas.fa-arrow-down
button.btn.btn-outline-danger.ml-0((click)='deleteScript(script)')
i.fas.fa-trash
button.btn.btn-outline-info.mt-2((click)='addScript()')
i.fas.fa-plus
span New item
login-scripts-settings([options]='profile.options')
div([ngbNavOutlet]='nav')

View File

@@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component } from '@angular/core'
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
import { PlatformService, ProfileSettingsComponent } from 'tabby-core'
import { LoginScript, SerialPortInfo, BAUD_RATES, SerialProfile } from '../api'
import { ProfileSettingsComponent } from 'tabby-core'
import { SerialPortInfo, BAUD_RATES, SerialProfile } from '../api'
import { SerialService } from '../services/serial.service'
/** @hidden */
@@ -14,7 +14,6 @@ export class SerialProfileSettingsComponent implements ProfileSettingsComponent
foundPorts: SerialPortInfo[]
constructor (
private platform: PlatformService,
private serial: SerialService,
) { }
@@ -40,50 +39,6 @@ export class SerialProfileSettingsComponent implements ProfileSettingsComponent
}
async ngOnInit () {
this.profile.options.scripts = this.profile.options.scripts ?? []
this.foundPorts = await this.serial.listPorts()
}
moveScriptUp (script: LoginScript) {
if (!this.profile.options.scripts) {
this.profile.options.scripts = []
}
const index = this.profile.options.scripts.indexOf(script)
if (index > 0) {
this.profile.options.scripts.splice(index, 1)
this.profile.options.scripts.splice(index - 1, 0, script)
}
}
moveScriptDown (script: LoginScript) {
if (!this.profile.options.scripts) {
this.profile.options.scripts = []
}
const index = this.profile.options.scripts.indexOf(script)
if (index >= 0 && index < this.profile.options.scripts.length - 1) {
this.profile.options.scripts.splice(index, 1)
this.profile.options.scripts.splice(index + 1, 0, script)
}
}
async deleteScript (script: LoginScript) {
if (this.profile.options.scripts && (await this.platform.showMessageBox(
{
type: 'warning',
message: 'Delete this script?',
detail: script.expect,
buttons: ['Keep', 'Delete'],
defaultId: 1,
}
)).response === 1) {
this.profile.options.scripts = this.profile.options.scripts.filter(x => x !== script)
}
}
addScript () {
if (!this.profile.options.scripts) {
this.profile.options.scripts = []
}
this.profile.options.scripts.push({ expect: '', send: '' })
}
}