diff --git a/client/src/app/features/changelog/changelog.component.html b/client/src/app/features/changelog/changelog.component.html index 0f0530e..1b83c69 100644 --- a/client/src/app/features/changelog/changelog.component.html +++ b/client/src/app/features/changelog/changelog.component.html @@ -1,7 +1,18 @@
+ + + +
+
+
+

{{logfile}}

+ +
+
+
-

Display log here !

+

diff --git a/client/src/app/features/changelog/changelog.component.ts b/client/src/app/features/changelog/changelog.component.ts index a71f290..f6bd28e 100644 --- a/client/src/app/features/changelog/changelog.component.ts +++ b/client/src/app/features/changelog/changelog.component.ts @@ -1,16 +1,72 @@ import { Component } from '@angular/core'; 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({ selector: 'app-changelog', standalone: true, templateUrl: './changelog.component.html', styleUrls: ['./changelog.component.css'], - imports: [MergeComponent] + imports: [CommonModule,MergeComponent] }) export class ChangelogComponent { - fetchLog(){ + + public displayableLogs: string[] = []; + + constructor( + private httpClient: HttpClient, + ){ + this.fetchLoglist(); + this.translateLogDirToString(); + } + + public fetchLoglist(): string[]{ // 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); } } diff --git a/client/src/app/features/merge/merge.component.ts b/client/src/app/features/merge/merge.component.ts index 3dcaa22..e381ba3 100644 --- a/client/src/app/features/merge/merge.component.ts +++ b/client/src/app/features/merge/merge.component.ts @@ -6,11 +6,13 @@ import { MergeServiceService } from './merge-service.service'; import { HttpClient, HttpParams } from '@angular/common/http'; import { environment } from 'src/environments/environment.development'; import { Observable } from 'rxjs'; +import { ChangelogComponent } from '../changelog/changelog.component'; +import { FetchLogService } from 'src/app/shared/services/fetch-log.service'; @Component({ selector: 'app-merge', standalone: true, - imports: [CommonModule, ReactiveFormsModule], + imports: [CommonModule, ReactiveFormsModule, ChangelogComponent], templateUrl: './merge.component.html', styleUrls: ['./merge.component.css'] }) @@ -25,12 +27,16 @@ export class MergeComponent { changelog_path: "" }); + default_output_path = "cofffeemachineConfig/merge/" + default_changelog_path = "cofffeemachineConfig/changelog/" + mergeLogs: Map | void | undefined constructor( private targets: MergeServiceService, private formBuilder: FormBuilder, private httpClient: HttpClient, + private chlog: ChangelogComponent ){ // Default fetching logs @@ -52,8 +58,8 @@ export class MergeComponent { } this.targets.master_version = this.mergeForm.value.master_version!; this.targets.dev_version = this.mergeForm.value.dev_version!; - this.targets.output_path = this.mergeForm.value.output_path!; - this.targets.changelog_path = this.mergeForm.value.changelog_path!; + this.targets.output_path = this.default_output_path + this.mergeForm.value.output_path!; + this.targets.changelog_path = this.default_changelog_path + this.mergeForm.value.changelog_path!; // TODO: Fetch merge. Modify this to websocket this.httpClient.post(environment.api+"/merge", { @@ -69,71 +75,18 @@ export class MergeComponent { if(typeof value === "object" && value !== null){ if("message" in value){ // fetch html - this.fetchLogsToDisplay("", true, false); + // this.fetchLogsToDisplay("", true, false); // fetch log file - this.fetchLogsToDisplay("", false, false); + // this.fetchLogsToDisplay("", false, false); // 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 | 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); - } - } - ) - } - } } diff --git a/client/src/app/shared/services/fetch-log.service.spec.ts b/client/src/app/shared/services/fetch-log.service.spec.ts new file mode 100644 index 0000000..4efbe24 --- /dev/null +++ b/client/src/app/shared/services/fetch-log.service.spec.ts @@ -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(); + }); +}); diff --git a/client/src/app/shared/services/fetch-log.service.ts b/client/src/app/shared/services/fetch-log.service.ts new file mode 100644 index 0000000..260f139 --- /dev/null +++ b/client/src/app/shared/services/fetch-log.service.ts @@ -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 | 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); + } + } + ) + } + } +} diff --git a/server/server.go b/server/server.go index f1dc556..7d47873 100644 --- a/server/server.go +++ b/server/server.go @@ -12,6 +12,7 @@ import ( "path/filepath" "recipe-manager/config" "recipe-manager/data" + "recipe-manager/models" "recipe-manager/routers" "recipe-manager/services/oauth" "strings" @@ -159,8 +160,7 @@ func (s *Server) createHandler() { dev_path := repo_path + dev_version + ".json" // Get who's requesting - user := r.Context().Value("user").(map[string]interface{}) - log.Println("User: ", user["email"].(string)) + user := r.Context().Value("user").(*models.User) // lookup for python exec py_exec, err := exec.LookPath("python") @@ -178,7 +178,7 @@ func (s *Server) createHandler() { } defer merge_api.Close() 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) out, err := cmd.CombinedOutput() @@ -214,8 +214,10 @@ func (s *Server) createHandler() { } } - log.Println("Log file ext: ", file_ext) - changelog_path := "cofffeemachineConfig/changelog/testlog" + file_ext + log_name := postRequest["filename"].(string) + + // log.Println("Log file ext: ", file_ext) + changelog_path := "cofffeemachineConfig/changelog/" + log_name + file_ext logFile, err := os.Open(changelog_path) if err != nil { 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 rr := routers.NewRecipeRouter(database) rr.Route(r)