add fetch all merge logs
This commit is contained in:
parent
baa66609ee
commit
325020fd37
6 changed files with 205 additions and 70 deletions
|
|
@ -1,7 +1,18 @@
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex-1 flex-wrap bg-stone-200 p-8" id="log-disp">
|
<div class="flex-1 flex-wrap bg-stone-200 p-8" id="log-disp">
|
||||||
|
<!-- query search -->
|
||||||
|
<!-- {{fetchLoglist()}} -->
|
||||||
|
<button type="button" class="button bg-stone-400 p-2 rounded m-2 text-black font-bold" (click)="refreshLogList()">Refresh 🔃</button>
|
||||||
|
<div class="grid grid-cols-4 gap-4 m-1 auto-cols-min" id="log-dir-list">
|
||||||
|
<div *ngFor="let logfile of displayableLogs">
|
||||||
|
<div class="font-semibold text-center bg-stone-700 p-2 rounded-md text-white">
|
||||||
|
<p>{{logfile}}</p>
|
||||||
|
<button class="button bg-stone-400 p-2 rounded m-2 text-black" type="button" (click)="viewLog(logfile)">View</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="log-dl"></div>
|
<div id="log-dl"></div>
|
||||||
<p class="flex flex-wrap" id="log-disp-texts"> Display log here !</p>
|
<p class="flex flex-wrap" id="log-disp-texts"></p>
|
||||||
</div>
|
</div>
|
||||||
<!-- Temporary remove log -->
|
<!-- Temporary remove log -->
|
||||||
<div class="flex-3 sticky top-0 bg-slate-700 h-screen justify-centers items-center">
|
<div class="flex-3 sticky top-0 bg-slate-700 h-screen justify-centers items-center">
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,72 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { MergeComponent } from '../merge/merge.component';
|
import { MergeComponent } from '../merge/merge.component';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { environment } from 'src/environments/environment.development';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FetchLogService } from 'src/app/shared/services/fetch-log.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-changelog',
|
selector: 'app-changelog',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
templateUrl: './changelog.component.html',
|
templateUrl: './changelog.component.html',
|
||||||
styleUrls: ['./changelog.component.css'],
|
styleUrls: ['./changelog.component.css'],
|
||||||
imports: [MergeComponent]
|
imports: [CommonModule,MergeComponent]
|
||||||
})
|
})
|
||||||
export class ChangelogComponent {
|
export class ChangelogComponent {
|
||||||
fetchLog(){
|
|
||||||
|
public displayableLogs: string[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private httpClient: HttpClient,
|
||||||
|
){
|
||||||
|
this.fetchLoglist();
|
||||||
|
this.translateLogDirToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public fetchLoglist(): string[]{
|
||||||
// TODO: Fetch changelog.html
|
// TODO: Fetch changelog.html
|
||||||
fetch("/changelog")
|
// fetch("/changelog")
|
||||||
|
let dirlist: any[] = []
|
||||||
|
this.httpClient.get(environment.api+"/mergelogList", {
|
||||||
|
withCredentials: true
|
||||||
|
}).subscribe({
|
||||||
|
next: (value) => {
|
||||||
|
console.log(value)
|
||||||
|
if(typeof value === "object" && value !== null){
|
||||||
|
if("dirs" in value){
|
||||||
|
console.log("dirs", value)
|
||||||
|
// dirlist.push(...(value as {dirs: unknown[]})["dirs"]);
|
||||||
|
this.displayableLogs = value.dirs as any[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
console.error('Error fetch json: ',err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log(dirlist);
|
||||||
|
return dirlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public translateLogDirToString(){
|
||||||
|
console.log("LogDirList: ", this.displayableLogs)
|
||||||
|
let dirSelector = document.getElementById("log-dir-list")
|
||||||
|
// for(let dir of this.displayableLogs){
|
||||||
|
// console.log(dir)
|
||||||
|
// const p = document.createElement('p');
|
||||||
|
// p.innerText = dir;
|
||||||
|
// dirSelector!.appendChild(p);
|
||||||
|
// dirSelector?.replaceChild(p, dirSelector.children[])
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshLogList(){
|
||||||
|
this.fetchLoglist();
|
||||||
|
this.translateLogDirToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
viewLog(name:string){
|
||||||
|
new FetchLogService(this.httpClient).fetchLogsToDisplay("", true, false, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,13 @@ import { MergeServiceService } from './merge-service.service';
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import { environment } from 'src/environments/environment.development';
|
import { environment } from 'src/environments/environment.development';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
import { ChangelogComponent } from '../changelog/changelog.component';
|
||||||
|
import { FetchLogService } from 'src/app/shared/services/fetch-log.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-merge',
|
selector: 'app-merge',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [CommonModule, ReactiveFormsModule],
|
imports: [CommonModule, ReactiveFormsModule, ChangelogComponent],
|
||||||
templateUrl: './merge.component.html',
|
templateUrl: './merge.component.html',
|
||||||
styleUrls: ['./merge.component.css']
|
styleUrls: ['./merge.component.css']
|
||||||
})
|
})
|
||||||
|
|
@ -25,12 +27,16 @@ export class MergeComponent<T> {
|
||||||
changelog_path: ""
|
changelog_path: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
default_output_path = "cofffeemachineConfig/merge/"
|
||||||
|
default_changelog_path = "cofffeemachineConfig/changelog/"
|
||||||
|
|
||||||
mergeLogs: Map<string, string> | void | undefined
|
mergeLogs: Map<string, string> | void | undefined
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private targets: MergeServiceService,
|
private targets: MergeServiceService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient,
|
||||||
|
private chlog: ChangelogComponent
|
||||||
){
|
){
|
||||||
// Default fetching logs
|
// Default fetching logs
|
||||||
|
|
||||||
|
|
@ -52,8 +58,8 @@ export class MergeComponent<T> {
|
||||||
}
|
}
|
||||||
this.targets.master_version = this.mergeForm.value.master_version!;
|
this.targets.master_version = this.mergeForm.value.master_version!;
|
||||||
this.targets.dev_version = this.mergeForm.value.dev_version!;
|
this.targets.dev_version = this.mergeForm.value.dev_version!;
|
||||||
this.targets.output_path = this.mergeForm.value.output_path!;
|
this.targets.output_path = this.default_output_path + this.mergeForm.value.output_path!;
|
||||||
this.targets.changelog_path = this.mergeForm.value.changelog_path!;
|
this.targets.changelog_path = this.default_changelog_path + this.mergeForm.value.changelog_path!;
|
||||||
|
|
||||||
// TODO: Fetch merge. Modify this to websocket
|
// TODO: Fetch merge. Modify this to websocket
|
||||||
this.httpClient.post<T>(environment.api+"/merge", {
|
this.httpClient.post<T>(environment.api+"/merge", {
|
||||||
|
|
@ -69,71 +75,18 @@ export class MergeComponent<T> {
|
||||||
if(typeof value === "object" && value !== null){
|
if(typeof value === "object" && value !== null){
|
||||||
if("message" in value){
|
if("message" in value){
|
||||||
// fetch html
|
// fetch html
|
||||||
this.fetchLogsToDisplay("", true, false);
|
// this.fetchLogsToDisplay("", true, false);
|
||||||
// fetch log file
|
// fetch log file
|
||||||
this.fetchLogsToDisplay("", false, false);
|
// this.fetchLogsToDisplay("", false, false);
|
||||||
// fetch json
|
// fetch json
|
||||||
this.mergeLogs = this.fetchLogsToDisplay("", false, true);
|
this.mergeLogs = new FetchLogService(this.httpClient).fetchLogsToDisplay("", false, true,"");
|
||||||
|
this.chlog.fetchLoglist();
|
||||||
|
this.chlog.translateLogDirToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchLogsToDisplay(query: string, isDisplayOnly: boolean, requestJson: boolean) : Map<string, string> | void{
|
|
||||||
let additionalParams:string = "?query=";
|
|
||||||
if(query != ""){
|
|
||||||
additionalParams += query
|
|
||||||
} else {
|
|
||||||
additionalParams = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
let jsontarget;
|
|
||||||
|
|
||||||
if(requestJson){
|
|
||||||
this.httpClient.post(environment.api+"/dllog"+additionalParams, {
|
|
||||||
htmlfile: isDisplayOnly,
|
|
||||||
requestJson: requestJson
|
|
||||||
}, {
|
|
||||||
responseType: 'json',
|
|
||||||
withCredentials: true
|
|
||||||
}).subscribe({
|
|
||||||
next: (value) => {
|
|
||||||
jsontarget = value;
|
|
||||||
},
|
|
||||||
error: (err) => {
|
|
||||||
console.error('Error fetch json: ',err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return jsontarget;
|
|
||||||
} else {
|
|
||||||
this.httpClient.post(environment.api+"/dllog"+additionalParams, {
|
|
||||||
htmlfile: isDisplayOnly,
|
|
||||||
requestJson: requestJson
|
|
||||||
},{
|
|
||||||
responseType: 'blob',
|
|
||||||
withCredentials: true,
|
|
||||||
}).subscribe(
|
|
||||||
{
|
|
||||||
next: (value) => {
|
|
||||||
const blob = new Blob([value], { type: 'application/octet-stream' });
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = 'logfile.log';
|
|
||||||
a.innerText = "Click here to download as `.log` file";
|
|
||||||
if(isDisplayOnly){
|
|
||||||
blob.text().then(v => document.getElementById("log-disp-texts")!.innerHTML = v);
|
|
||||||
} else {
|
|
||||||
document.getElementById("log-dl")?.appendChild(a);
|
|
||||||
document.getElementById("log-dl")!.className = "bg-yellow-500 rounded p-2 sticky top-0";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: (err) => {
|
|
||||||
console.error('Error downloading log file: ',err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
client/src/app/shared/services/fetch-log.service.spec.ts
Normal file
16
client/src/app/shared/services/fetch-log.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FetchLogService } from './fetch-log.service';
|
||||||
|
|
||||||
|
describe('FetchLogService', () => {
|
||||||
|
let service: FetchLogService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(FetchLogService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
78
client/src/app/shared/services/fetch-log.service.ts
Normal file
78
client/src/app/shared/services/fetch-log.service.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { environment } from 'src/environments/environment.development';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class FetchLogService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private httpClient: HttpClient
|
||||||
|
) {}
|
||||||
|
|
||||||
|
|
||||||
|
public fetchLogsToDisplay(query: string, isDisplayOnly: boolean, requestJson: boolean, filename:string) : Map<string, string> | void{
|
||||||
|
let additionalParams:string = "?query=";
|
||||||
|
if(query != ""){
|
||||||
|
additionalParams += query
|
||||||
|
} else {
|
||||||
|
additionalParams = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
let jsontarget;
|
||||||
|
|
||||||
|
if(requestJson){
|
||||||
|
this.httpClient.post(environment.api+"/dllog"+additionalParams, {
|
||||||
|
htmlfile: isDisplayOnly,
|
||||||
|
requestJson: requestJson,
|
||||||
|
filename: filename
|
||||||
|
}, {
|
||||||
|
responseType: 'json',
|
||||||
|
withCredentials: true
|
||||||
|
}).subscribe({
|
||||||
|
next: (value: any) => {
|
||||||
|
jsontarget = value;
|
||||||
|
},
|
||||||
|
error: (err: any) => {
|
||||||
|
console.error('Error fetch json: ',err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return jsontarget;
|
||||||
|
} else {
|
||||||
|
this.httpClient.post(environment.api+"/dllog"+additionalParams, {
|
||||||
|
htmlfile: isDisplayOnly,
|
||||||
|
requestJson: requestJson,
|
||||||
|
filename: filename
|
||||||
|
},{
|
||||||
|
responseType: 'blob',
|
||||||
|
withCredentials: true,
|
||||||
|
}).subscribe(
|
||||||
|
{
|
||||||
|
next: (value: BlobPart) => {
|
||||||
|
const blob = new Blob([value], { type: 'application/octet-stream' });
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'logfile.log';
|
||||||
|
a.innerText = "Click here to download as `.log` file";
|
||||||
|
if(isDisplayOnly){
|
||||||
|
blob.text().then(v => document.getElementById("log-disp-texts")!.innerHTML = v);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while(document.getElementById("log-dl")?.firstChild){
|
||||||
|
document.getElementById("log-dl")?.removeChild(document.getElementById("log-dl")!.firstChild!);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("log-dl")?.appendChild(a);
|
||||||
|
document.getElementById("log-dl")!.className = "bg-yellow-500 rounded p-2 sticky top-0";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (err: any) => {
|
||||||
|
console.error('Error downloading log file: ',err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"recipe-manager/config"
|
"recipe-manager/config"
|
||||||
"recipe-manager/data"
|
"recipe-manager/data"
|
||||||
|
"recipe-manager/models"
|
||||||
"recipe-manager/routers"
|
"recipe-manager/routers"
|
||||||
"recipe-manager/services/oauth"
|
"recipe-manager/services/oauth"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -159,8 +160,7 @@ func (s *Server) createHandler() {
|
||||||
dev_path := repo_path + dev_version + ".json"
|
dev_path := repo_path + dev_version + ".json"
|
||||||
|
|
||||||
// Get who's requesting
|
// Get who's requesting
|
||||||
user := r.Context().Value("user").(map[string]interface{})
|
user := r.Context().Value("user").(*models.User)
|
||||||
log.Println("User: ", user["email"].(string))
|
|
||||||
|
|
||||||
// lookup for python exec
|
// lookup for python exec
|
||||||
py_exec, err := exec.LookPath("python")
|
py_exec, err := exec.LookPath("python")
|
||||||
|
|
@ -178,7 +178,7 @@ func (s *Server) createHandler() {
|
||||||
}
|
}
|
||||||
defer merge_api.Close()
|
defer merge_api.Close()
|
||||||
log.Println("Locate python api", merge_api.Name())
|
log.Println("Locate python api", merge_api.Name())
|
||||||
cmd := exec.Command(py_exec, merge_api.Name(), "merge", master_path, dev_path, output_path, changelog_path, "", user["email"].(string))
|
cmd := exec.Command(py_exec, merge_api.Name(), "merge", master_path, dev_path, output_path, changelog_path, "", user.Name)
|
||||||
|
|
||||||
log.Println("Run merge command", cmd)
|
log.Println("Run merge command", cmd)
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
|
|
@ -214,8 +214,10 @@ func (s *Server) createHandler() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Log file ext: ", file_ext)
|
log_name := postRequest["filename"].(string)
|
||||||
changelog_path := "cofffeemachineConfig/changelog/testlog" + file_ext
|
|
||||||
|
// log.Println("Log file ext: ", file_ext)
|
||||||
|
changelog_path := "cofffeemachineConfig/changelog/" + log_name + file_ext
|
||||||
logFile, err := os.Open(changelog_path)
|
logFile, err := os.Open(changelog_path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
@ -247,6 +249,25 @@ func (s *Server) createHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Get("/mergelogList", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ch_dir, err := os.ReadDir("cofffeemachineConfig/changelog")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
displayable := make([]string, 0)
|
||||||
|
|
||||||
|
for _, file := range ch_dir {
|
||||||
|
if strings.Contains(file.Name(), ".html") {
|
||||||
|
|
||||||
|
displayable = append(displayable, file.Name()[:len(file.Name())-len(filepath.Ext(file.Name()))])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(w).Encode(map[string][]string{"dirs": displayable})
|
||||||
|
})
|
||||||
|
|
||||||
// Recipe Router
|
// Recipe Router
|
||||||
rr := routers.NewRecipeRouter(database)
|
rr := routers.NewRecipeRouter(database)
|
||||||
rr.Route(r)
|
rr.Route(r)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue