Skip to content

Commit

Permalink
add plugin log download button
Browse files Browse the repository at this point in the history
  • Loading branch information
bwp91 committed Dec 10, 2023
1 parent 39ce09f commit db7de32
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 21 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to homebridge-config-ui-x will be documented in this file.

## BETA

### UI Changes

- Add plugin log download button

## 4.54.1 (2023-12-08)

### Bug Fixes
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions ui/src/app/core/log.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,25 @@ export class LogService {
// subscribe to incoming data events from server to client
this.io.socket.on('stdout', (data: string) => {
if (this.pluginName) {
const lines = data.split('\n');
const lines = data.split('\n\r');
let includeNextLine = false;

lines.forEach((line) => {
lines.forEach((line: string) => {
if (!line) {
return;
}

if (includeNextLine) {
if (line.match(/36m\[.*?]/)) {
includeNextLine = false;
} else {
this.term.write(line + '\r\n');
this.term.write(line + '\n\r');
return;
}
}

if (line.includes(`36m[${this.pluginName}]`)) {
this.term.write(line + '\r\n');
this.term.write(line + '\n\r');
includeNextLine = true;
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ <h5 class="modal-title">Logs: {{ plugin.displayName || plugin.name }}</h5>
<div #pluginlogoutput class="w-100 bg-black plugin-log-output terminal align-self-end w-100 h-100 mb-0 p-2"></div>
</div>
<div class="modal-footer justify-content-between">
<div class="text-left"> </div>
<div class="text-center">
<div class="text-left">
<button type="button" class="btn btn-elegant" data-dismiss="modal" (click)="activeModal.dismiss('Dismiss')">
{{ 'form.button_close' | translate }}
</button>
</div>
<div class="text-right"></div>
<div class="text-center"></div>
<div class="text-right">
<button class="btn btn-primary" (click)="downloadLogFile()">
{{ 'logs.label_download' | translate }}
</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import {
Component,
ElementRef,
Expand All @@ -7,11 +8,13 @@ import {
OnInit,
ViewChild,
} from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { saveAs } from 'file-saver';
import { ToastrService } from 'ngx-toastr';
import { Subject } from 'rxjs';
import { ApiService } from '@/app/core/api.service';
import { ConfirmComponent } from '@/app/core/components/confirm/confirm.component';
import { LogService } from '@/app/core/log.service';

@Component({
Expand All @@ -23,11 +26,13 @@ export class PluginLogModalComponent implements OnInit, OnDestroy {
@Input() plugin: any;
@ViewChild('pluginlogoutput', { static: true }) termTarget: ElementRef;
private resizeEvent = new Subject();
private pluginAlias: string;

constructor(
public activeModal: NgbActiveModal,
private $api: ApiService,
private $log: LogService,
private $modal: NgbModal,
private $toastr: ToastrService,
private $translate: TranslateService,
) { }
Expand All @@ -43,11 +48,10 @@ export class PluginLogModalComponent implements OnInit, OnDestroy {

getPluginLog() {
// Get the plugin name as configured in the config file
console.log(this.plugin);
this.$api.get(`/config-editor/plugin/${encodeURIComponent(this.plugin.name)}`).subscribe(
(result) => {
const logAlias = this.plugin.name === 'homebridge-config-ui-x' ? 'Homebridge UI' : (result[0]?.name || this.plugin.name);
this.$log.startTerminal(this.termTarget, {}, this.resizeEvent, logAlias);
this.pluginAlias = this.plugin.name === 'homebridge-config-ui-x' ? 'Homebridge UI' : (result[0]?.name || this.plugin.name);
this.$log.startTerminal(this.termTarget, {}, this.resizeEvent, this.pluginAlias);
},
(err) => {
this.$toastr.error(`${err.error.message || err.message}`, this.$translate.instant('toast.title_error'));
Expand All @@ -56,6 +60,61 @@ export class PluginLogModalComponent implements OnInit, OnDestroy {
);
}

downloadLogFile() {
const ref = this.$modal.open(ConfirmComponent);
ref.componentInstance.title = this.$translate.instant('logs.title_download_log_file');
ref.componentInstance.message = this.$translate.instant('logs.message_download_warning');
ref.componentInstance.confirmButtonLabel = this.$translate.instant('logs.label_download');
ref.componentInstance.faIconClass = 'fas fa-fw fa-user-secret primary-text';

ref.result.then(() => {
this.$api.get('/platform-tools/hb-service/log/download?colour=yes', { observe: 'response', responseType: 'text' })
.subscribe(
(res: HttpResponse<any>) => {
if (!res.body) {
return;
}
const lines = res.body.split('\n');
let finalOutput = '';
let includeNextLine = false;

lines.forEach((line: string) => {
if (!line) {
return;
}

if (includeNextLine) {
if (line.match(/36m\[.*?]/)) {
includeNextLine = false;
} else {
finalOutput += line.replace(/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]/g, '') + '\r\n';
return;
}
}

if (line.includes(`36m[${this.pluginAlias}]`)) {
finalOutput += line.replace(/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]/g, '') + '\r\n';
includeNextLine = true;
}
});

saveAs(new Blob([finalOutput], { type: 'text/plain;charset=utf-8' }), `${this.plugin.name}.log.txt`);
},
async (err: HttpErrorResponse) => {
let message: string;
try {
message = JSON.parse(await err.error.text()).message;
} catch (e) {
// do nothing
}
this.$toastr.error(message || 'Failed to download log file', this.$translate.instant('toast.title_error'));
},
);
}).catch(() => {
// do nothing
});
}

ngOnDestroy() {
this.$log.destroyTerminal();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="flex-column d-flex align-items-stretch h-100 w-100 pb-1">
<div style="cursor: move;" class="drag-handler pl-2 pt-1 pb-1 pr-2">Homebridge</div>
<div class="d-flex flex-wrap w-100 pr-3 pl-2 justify-content-start gridster-item-content overflow-auto no-scrollbars">
<div class="hb-status-item d-flex flex-row mr-4">
<div class="hb-status-item d-flex flex-row" style="min-width:max(25%, 250px);">
<div class="d-flex">
<div class="mb-0 px-3 py-1 hb-status-icon">
<i class="fas fa-fw primary-text" [ngClass]="{
Expand Down Expand Up @@ -32,7 +32,7 @@
</div>
</div>

<div class="hb-status-item d-flex flex-row mr-4 pr-4">
<div class="hb-status-item d-flex flex-row" style="min-width:max(25%, 250px);">
<div class="d-flex">
<div class="mb-0 px-3 py-1 hb-status-icon">
<i class="fas fa-fw fa-cog fa-spin primary-text" *ngIf="!homebridgePkg.installedVersion"></i>
Expand Down Expand Up @@ -65,7 +65,7 @@
</div>
</div>

<div class="hb-status-item d-flex flex-row mr-4 pr-4">
<div class="hb-status-item d-flex flex-row" style="min-width:max(25%, 250px);">
<div class="d-flex">
<div class="mb-0 px-3 py-1 hb-status-icon">
<i class="fas fa-fw fa-cog fa-spin primary-text" *ngIf="!homebridgeUiPkg.installedVersion"></i>
Expand Down Expand Up @@ -98,7 +98,7 @@
</div>
</div>

<div class="hb-status-item d-flex flex-row mr-4 pr-4">
<div class="hb-status-item d-flex flex-row" style="min-width:max(25%, 250px);">
<div class="d-flex">
<div class="mb-0 px-3 py-1 hb-status-icon">
<i class="fas fa-fw fa-arrow-alt-circle-up primary-text" *ngIf="homebridgePluginStatus.length"></i>
Expand Down

0 comments on commit db7de32

Please sign in to comment.