From fed315367a17e7b971d1abc8c3cb3d1811aec8ab Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Thu, 22 Feb 2024 16:04:34 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=20WIP=20migrating=20tmp=20to?= =?UTF-8?q?=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/core/layout/layout.component.html | 14 ++ .../src/app/core/layout/layout.component.ts | 66 ++++++-- .../src/app/core/services/recipe.service.ts | 51 ++++-- .../features/changelog/changelog.component.ts | 4 +- .../merge/merge-service.service.spec.ts | 16 -- .../features/merge/merge-service.service.ts | 14 -- .../app/features/merge/merge.component.css | 0 .../app/features/merge/merge.component.html | 56 +------ .../features/merge/merge.component.spec.ts | 21 --- .../src/app/features/merge/merge.component.ts | 93 ++--------- .../app/features/recipes/recipes.component.ts | 66 ++++---- server/data/redis.go | 36 +++++ server/routers/recipe.go | 150 +++++++++++++++--- 13 files changed, 317 insertions(+), 270 deletions(-) delete mode 100644 client/src/app/features/merge/merge-service.service.spec.ts delete mode 100644 client/src/app/features/merge/merge-service.service.ts delete mode 100644 client/src/app/features/merge/merge.component.css delete mode 100644 client/src/app/features/merge/merge.component.spec.ts diff --git a/client/src/app/core/layout/layout.component.html b/client/src/app/core/layout/layout.component.html index 010993c..769afe1 100644 --- a/client/src/app/core/layout/layout.component.html +++ b/client/src/app/core/layout/layout.component.html @@ -34,7 +34,19 @@ alt="Tao Bin Logo" /> + +
+

{{redisStatus}}

+
+ + + +
@@ -155,3 +167,5 @@
+ + diff --git a/client/src/app/core/layout/layout.component.ts b/client/src/app/core/layout/layout.component.ts index 1478473..71bcbcd 100644 --- a/client/src/app/core/layout/layout.component.ts +++ b/client/src/app/core/layout/layout.component.ts @@ -1,10 +1,15 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, RouterModule } from '@angular/router'; -import { DatePipe, NgFor, NgIf, NgOptimizedImage } from '@angular/common'; +import { CommonModule, DatePipe, NgFor, NgIf, NgOptimizedImage } from '@angular/common'; import { GoogleButtonComponent } from 'src/app/shared/googleButton/googleButton.component'; import { UserService } from '../services/user.service'; import { User } from '../models/user.model'; import { Subject, Subscription, map, share, takeUntil, timer } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { environment } from 'src/environments/environment'; +import { RecipeService } from '../services/recipe.service'; +import { AsyncStorage } from 'src/app/shared/helpers/asyncStorage'; +import { MergeComponent } from "../../features/merge/merge.component"; interface MenuItem { name: string; @@ -13,17 +18,19 @@ interface MenuItem { } @Component({ - selector: 'app-layout', - templateUrl: './layout.component.html', - standalone: true, - imports: [ - RouterModule, - NgFor, - NgIf, - GoogleButtonComponent, - DatePipe, - NgOptimizedImage, - ], + selector: 'app-layout', + templateUrl: './layout.component.html', + standalone: true, + imports: [ + RouterModule, + NgFor, + NgIf, + GoogleButtonComponent, + DatePipe, + NgOptimizedImage, + CommonModule, + MergeComponent + ] }) export class LayoutComponent implements OnInit, OnDestroy { current_department = this._router.snapshot.paramMap.get('department')!; @@ -51,12 +58,17 @@ export class LayoutComponent implements OnInit, OnDestroy { user: User | null = null; exit$ = new Subject(); + redisStatus:string = "Offline"; + showDetectChanges: boolean = false; + constructor( private _userService: UserService, - private _router: ActivatedRoute + private _router: ActivatedRoute, + private _httpClient: HttpClient, + private _recipeService: RecipeService ) {} - ngOnInit(): void { + async ngOnInit(): Promise { this._userService.currentUser .pipe(takeUntil(this.exit$)) .subscribe((user) => (this.user = user)); @@ -69,6 +81,32 @@ export class LayoutComponent implements OnInit, OnDestroy { .subscribe((time) => { this.date = time; }); + + this._httpClient.get(environment.api + "/health/redis").subscribe((status) => { + this.redisStatus = (status as any)["status"]; + }); + + // check if saves existed + this._recipeService.getSavedTmp( + await this._recipeService.getCurrentCountry(), + this._recipeService.getCurrentFile() + ).subscribe({ + next: async (data: any) => { + if(data != undefined && typeof data === 'object'){ + // check if attr exists + if(data.files != null){ + this.showDetectChanges = true; + await AsyncStorage.setItem("detectChanges", "true"); + } else { + this.showDetectChanges = false; + await AsyncStorage.setItem("detectChanges", "false"); + } + } else { + this.showDetectChanges = false; + await AsyncStorage.setItem("detectChanges", "false"); + } + } + }); } ngOnDestroy() { diff --git a/client/src/app/core/services/recipe.service.ts b/client/src/app/core/services/recipe.service.ts index bd0ad3d..9ef3939 100644 --- a/client/src/app/core/services/recipe.service.ts +++ b/client/src/app/core/services/recipe.service.ts @@ -47,7 +47,10 @@ export class RecipeService { return this.tmp_files; } - constructor(private _httpClient: HttpClient, private _route: ActivatedRoute) {} + constructor( + private _httpClient: HttpClient, + private _route: ActivatedRoute + ) {} getRecipesDashboard( params: any = { @@ -95,8 +98,9 @@ export class RecipeService { ); } - async getRecipeDetail(productCode: string): Promise> { - + async getRecipeDetail( + productCode: string + ): Promise> { let asyncCountry = await this.getCurrentCountry(this.department!); console.log('get detail by asyncCountry', asyncCountry); @@ -115,8 +119,7 @@ export class RecipeService { async getRecipeDetailMat( productCode: string - ): Promise> { - + ): Promise> { let asyncCountry = await this.getCurrentCountry(this.department!); return this._httpClient.get<{ result: RecipeDetailMat[] }>( @@ -133,10 +136,8 @@ export class RecipeService { } getCurrentFile(): string { - // TODO: get default from server - const currentRecipeFile = localStorage.getItem('currentRecipeFile'); if (currentRecipeFile) { return currentRecipeFile; @@ -150,9 +151,7 @@ export class RecipeService { } async getCurrentCountry(department?: string): Promise { - - if(department){ - + if (department) { // translate back to full name let fullname = getCountryMapSwitcher(department); @@ -167,7 +166,9 @@ export class RecipeService { // const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); - const currentRecipeCountry = await AsyncStorage.getItem('currentRecipeCountry'); + const currentRecipeCountry = await AsyncStorage.getItem( + 'currentRecipeCountry' + ); if (currentRecipeCountry) { return currentRecipeCountry; } @@ -275,13 +276,37 @@ export class RecipeService { ); } - async getRawRecipeOfProductCode(country: string, filename: string, productCode: string): Promise> { + async getRawRecipeOfProductCode( + country: string, + filename: string, + productCode: string + ): Promise> { return this._httpClient.get<{}>( - environment.api + '/recipes/' + country + '/' + filename + '/' + productCode + '/raw_full', + environment.api + + '/recipes/' + + country + + '/' + + filename + + '/' + + productCode + + '/raw_full', { withCredentials: true, responseType: 'json', } ); } + + async getPatchListOfCurrentFile( + country: string, + filename: string + ): Promise> { + + console.log("try get patches", country, filename); + + return this._httpClient.get( + environment.api + '/recipes/patch/get/' + country + '/' + filename , + { withCredentials: true, responseType: 'json' } + ); + } } diff --git a/client/src/app/features/changelog/changelog.component.ts b/client/src/app/features/changelog/changelog.component.ts index 73f4a79..5414a22 100644 --- a/client/src/app/features/changelog/changelog.component.ts +++ b/client/src/app/features/changelog/changelog.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } 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'; @@ -10,7 +10,7 @@ import { FetchLogService } from 'src/app/shared/services/fetch-log.service'; standalone: true, templateUrl: './changelog.component.html', styleUrls: ['./changelog.component.css'], - imports: [CommonModule, MergeComponent], + imports: [CommonModule], }) export class ChangelogComponent { public displayableLogs: string[] = []; diff --git a/client/src/app/features/merge/merge-service.service.spec.ts b/client/src/app/features/merge/merge-service.service.spec.ts deleted file mode 100644 index 3f2fc2d..0000000 --- a/client/src/app/features/merge/merge-service.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { MergeServiceService } from './merge-service.service'; - -describe('MergeServiceService', () => { - let service: MergeServiceService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(MergeServiceService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/client/src/app/features/merge/merge-service.service.ts b/client/src/app/features/merge/merge-service.service.ts deleted file mode 100644 index f25f8f7..0000000 --- a/client/src/app/features/merge/merge-service.service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable({ - providedIn: 'root' -}) -export class MergeServiceService { - - master_version: number = 0; - dev_version: number = 0; - output_path:string = ""; - changelog_path:string = ""; - - constructor() { } -} diff --git a/client/src/app/features/merge/merge.component.css b/client/src/app/features/merge/merge.component.css deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/app/features/merge/merge.component.html b/client/src/app/features/merge/merge.component.html index 54b864f..d46d9c1 100644 --- a/client/src/app/features/merge/merge.component.html +++ b/client/src/app/features/merge/merge.component.html @@ -1,55 +1 @@ - -
- -

Merge 2 json

- -
-
-

- ❓ What does this function do? -

-
-

- Apply changes from the `dev` version -
into the `master` version -

-
-
- -
-

- ❗Beware❗ -
`master` = base version -
`dev` = your version -

-
-
-
- - -
- -
- - -
- - -
- - -
- - -
- - -
- - -
-
- - -
- +

merge works!

diff --git a/client/src/app/features/merge/merge.component.spec.ts b/client/src/app/features/merge/merge.component.spec.ts deleted file mode 100644 index f6228ba..0000000 --- a/client/src/app/features/merge/merge.component.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { MergeComponent } from './merge.component'; - -describe('MergeComponent', () => { - let component: MergeComponent; - let fixture: ComponentFixture; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [MergeComponent] - }); - fixture = TestBed.createComponent(MergeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/client/src/app/features/merge/merge.component.ts b/client/src/app/features/merge/merge.component.ts index 8a5cc9c..a354acc 100644 --- a/client/src/app/features/merge/merge.component.ts +++ b/client/src/app/features/merge/merge.component.ts @@ -1,90 +1,31 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common'; - -import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; -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'; +import { RecipeService } from 'src/app/core/services/recipe.service'; @Component({ selector: 'app-merge', standalone: true, - imports: [CommonModule, ReactiveFormsModule, ChangelogComponent], + imports: [CommonModule], templateUrl: './merge.component.html', - styleUrls: ['./merge.component.css'] }) -export class MergeComponent { +export class MergeComponent implements OnInit { - exceptionValues = [0, null, undefined] - - mergeForm = this.formBuilder.group({ - master_version: 0, - dev_version: 0, - output_path: "", - changelog_path: "" - }); - - default_output_path = "cofffeemachineConfig/merge/" - default_changelog_path = "cofffeemachineConfig/changelog/" - - mergeLogs: Map | void | undefined + patchMap: any = {} constructor( - private targets: MergeServiceService, - private formBuilder: FormBuilder, - private httpClient: HttpClient, - private chlog: ChangelogComponent - ){ - // Default fetching logs + private _recipeService: RecipeService + ) { } - // fetch html - // this.fetchLogsToDisplay("", true, false); - // // fetch log file - // this.fetchLogsToDisplay("", false, false); - // // fetch json - // this.mergeLogs = this.fetchLogsToDisplay("", false, true); + async ngOnInit(): Promise { + (await this._recipeService.getPatchListOfCurrentFile( + await this._recipeService.getCurrentCountry(), + this._recipeService.getCurrentFile() + )).subscribe({ + next: (data: any) => { + this.patchMap = data; + console.log("patches",this.patchMap); + } + }); } - private isException(value: any){ - return this.exceptionValues.includes(value) - } - - fetchMerge(){ - if(this.isException(this.mergeForm.value.master_version) || this.isException(this.mergeForm.value.dev_version)){ - return - } - this.targets.master_version = this.mergeForm.value.master_version!; - this.targets.dev_version = this.mergeForm.value.dev_version!; - 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", { - master: this.targets.master_version, - dev: this.targets.dev_version, - output: this.targets.output_path, - changelog: this.targets.changelog_path - }, { - withCredentials: true - }).subscribe({ - next: (value: T) => { - console.log(value) - if(typeof value === "object" && value !== null){ - if("message" in value){ - // fetch html - // this.fetchLogsToDisplay("", true, false); - // fetch log file - // this.fetchLogsToDisplay("", false, false); - // fetch json - this.mergeLogs = new FetchLogService(this.httpClient).fetchLogsToDisplay("", false, true,this.targets.changelog_path); - this.chlog.fetchLoglist(); - this.chlog.translateLogDirToString(); - } - } - }, - }) - } } diff --git a/client/src/app/features/recipes/recipes.component.ts b/client/src/app/features/recipes/recipes.component.ts index cf2a738..ea91847 100644 --- a/client/src/app/features/recipes/recipes.component.ts +++ b/client/src/app/features/recipes/recipes.component.ts @@ -89,7 +89,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { savedTmpfiles: any[] = []; saveTab: boolean = false; - showSaveNoti: boolean = true; + showSaveNoti: boolean = false; department: string = this.route.parent!.snapshot.params['department']; copyList: any[] = []; @@ -197,7 +197,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { }) ); - // FIXME: Lag assigned + // : Lag assigned this.recipesDashboard$.subscribe(async (data) => { this.currentVersion = data.configNumber; @@ -241,37 +241,37 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { // end of FIXME - this._recipeService - .getSavedTmp( - await this._recipeService.getCurrentCountry(this.department), - this._recipeService.getCurrentFile() - ) - .subscribe({ - next: (files: any) => { - console.log('Obtain saves: ', typeof files, files); - this.showSaveNoti = false; - if (files != undefined && typeof files === 'object') { - if (files.files != null) { - console.log( - 'Obtain saves object: ', - files.files[0], - typeof files - ); - this.savedTmpfiles = files.files; - } else { - this.showSaveNoti = false; - this.savedTmpfiles = []; - console.log(this.showSaveNoti, this.savedTmpfiles); - } - // let svf = (document.getElementById('select_savefile_modal') as HTMLInputElement)!.checked; - // console.log("isSavedModalOpened",svf) - } else { - this.showSaveNoti = false; - this.savedTmpfiles = []; - console.log(this.showSaveNoti, this.savedTmpfiles); - } - }, - }); + // this._recipeService + // .getSavedTmp( + // await this._recipeService.getCurrentCountry(this.department), + // this._recipeService.getCurrentFile() + // ) + // .subscribe({ + // next: (files: any) => { + // console.log('Obtain saves: ', typeof files, files); + // this.showSaveNoti = false; + // if (files != undefined && typeof files === 'object') { + // if (files.files != null) { + // console.log( + // 'Obtain saves object: ', + // files.files[0], + // typeof files + // ); + // this.savedTmpfiles = files.files; + // } else { + // this.showSaveNoti = false; + // this.savedTmpfiles = []; + // console.log(this.showSaveNoti, this.savedTmpfiles); + // } + // // let svf = (document.getElementById('select_savefile_modal') as HTMLInputElement)!.checked; + // // console.log("isSavedModalOpened",svf) + // } else { + // this.showSaveNoti = false; + // this.savedTmpfiles = []; + // console.log(this.showSaveNoti, this.savedTmpfiles); + // } + // }, + // }); (await this._materialService.getMaterialCodes()) .pipe( diff --git a/server/data/redis.go b/server/data/redis.go index c4cf2c9..e283717 100644 --- a/server/data/redis.go +++ b/server/data/redis.go @@ -135,3 +135,39 @@ func (r *RedisCli) SetKeyTimeout(key string, value interface{}, timeout int) err fmt.Println("error on EXPIRE ", err) return err } + +func (r *RedisCli) KeyList() ([]string, error) { + // if cannot pass healthcheck, return err + if err := r.HealthCheck(); err != nil { + fmt.Println("HS> KEYS error ", err) + return nil, err + } + + keys := r.Client.Keys(context.Background(), "*") + + return keys.Result() +} + +// list operations + +func (r *RedisCli) GetList(key string) ([]string, error) { + // if cannot pass healthcheck, return err + if err := r.HealthCheck(); err != nil { + fmt.Println("HS> List.GET error ", err) + return nil, err + } + + return r.Client.LRange(context.Background(), key, 0, -1).Result() +} + +func (r *RedisCli) Add(key string, value interface{}) error { + // if cannot pass healthcheck, return err + if err := r.HealthCheck(); err != nil { + fmt.Println("HS> List.ADD error ", err) + return err + } + + err := r.Client.RPush(context.Background(), key, value) + + return err.Err() +} diff --git a/server/routers/recipe.go b/server/routers/recipe.go index be8964b..f12cb63 100644 --- a/server/routers/recipe.go +++ b/server/routers/recipe.go @@ -101,6 +101,8 @@ func (rr *RecipeRouter) Route(r chi.Router) { r.Get("/saved/{country}/{filename_version_only}", rr.getSavedRecipes) + r.Get("/patch/get/{country}/{filename}", rr.getSavedAsPatches) + r.Get("/departments", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") @@ -447,6 +449,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) { tempRecipe := models.Recipe01{} tempRecipe = tempRecipe.FromMap(changeMap) rr.data.SetValuesToRecipe(targetRecipe.Recipe01, tempRecipe) + rr.taoLogger.Log.Debug("ApplyChange", zap.Any("status", "passed")) // check if changed @@ -462,7 +465,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) { // gen hash commit_hash, err := data.HashCommit(8) - rr.cache_db.SetToKey(commit_hash, targetRecipe) + // rr.cache_db.SetToKey(commit_hash, targetRecipe) commit := data.CommitLog{ @@ -474,31 +477,68 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) { Relation: filename, } + // ------------------------ SKIP THIS ------------------------ + // TODO: save only changes. + + // get new tempfile name if redis is connected; + + productCodeNoSpl := strings.ReplaceAll(changes.ProductCode, "-", "") + patchName := "Recipe_" + productCodeNoSpl + "-" + commit_hash + "_" + filename + ".patch" + + // if cache service online + if rr.cache_db.HealthCheck() == nil { + // do change mode + commit.Change_file = patchName + commit.Relation = commit.Relation + "/patch" + + // add to patch list of that filename + // filename:patchlist + err := rr.cache_db.Add(countryID+"."+filename+":patchList", commit.Id) + + // add failed + if err != nil { + rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipe", zap.Error(errors.WithMessage(err, "Error when tried to add to patch list"))) + http.Error(w, "Internal Error", http.StatusInternalServerError) + return + } + + } else { + + // this following codes do need users to pass update to each other + // otherwise, the changes will diverge + + file, _ := os.Create(temp_file_name) + if err != nil { + rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipe", zap.Error(errors.WithMessage(err, "Error when tried to create file"))) + http.Error(w, "Internal Error", http.StatusInternalServerError) + return + } + + // write to local if cannot connect + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + // full + err = encoder.Encode(targetRecipe) + + // ------------------------------------------------------------- + + // partial + // err = encoder.Encode(changes) + + // put changes to redis + + if err != nil { + rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipe", zap.Error(errors.WithMessage(err, "Error when write file"))) + http.Error(w, "Internal Error", http.StatusInternalServerError) + return + } + } + + // add to commit err = data.Insert(&commit) - file, _ := os.Create(temp_file_name) - if err != nil { - rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipe", zap.Error(errors.WithMessage(err, "Error when tried to create file"))) - http.Error(w, "Internal Error", http.StatusInternalServerError) - return - } - - encoder := json.NewEncoder(file) - encoder.SetIndent("", " ") - // full - err = encoder.Encode(targetRecipe) - - // partial - // err = encoder.Encode(changes) - - // put changes to redis - - if err != nil { - rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipe", zap.Error(errors.WithMessage(err, "Error when write file"))) - http.Error(w, "Internal Error", http.StatusInternalServerError) - return - } - err = rr.cache_db.SetToKey(commit_hash+"_"+filename, changes) + err = rr.cache_db.SetToKey(patchName, changes) + // TODO: ^----- change this to patch if err != nil { rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipeCache", zap.Error(errors.WithMessage(err, "Error when write file"))) @@ -567,6 +607,64 @@ func (rr *RecipeRouter) getSavedRecipes(w http.ResponseWriter, r *http.Request) json.NewEncoder(w).Encode(map[string]interface{}{"files": commits}) } +func (rr *RecipeRouter) getSavedAsPatches(w http.ResponseWriter, r *http.Request) { + + filename := chi.URLParam(r, "filename") + country := chi.URLParam(r, "country") + + countryID, err := rr.data.GetCountryIDByName(country) + if err != nil { + http.Error(w, fmt.Sprintf("Country Name: %s not found!!!", country), http.StatusNotFound) + return + } + + patchList, err := rr.cache_db.GetList(countryID + "." + filename + ":patchList") + if err != nil { + // silent return, no patch + return + } + + rr.taoLogger.Log.Debug("RecipeRouter.getSavedAsPatches", zap.Any("targetPatchOf", countryID+"."+filename+":patchList"), zap.Any("patchList", patchList)) + + // find patch content from patch list + keys, err := rr.cache_db.KeyList() + if err != nil { + // keys found nothing + http.Error(w, "Internal Error", http.StatusInternalServerError) + return + } + + // loop through keys, if contain patch id + patchMap := map[string]models.Recipe01{} + for _, key := range keys { + if strings.Contains(key, filename) && strings.Contains(key, "patch") { + + // check if legit saved file from patchList + for _, patchID := range patchList { + if strings.Contains(key, patchID) { + // get patch content + var recipePatch models.Recipe01 + err := rr.cache_db.GetKeyTo(key, &recipePatch) + if err != nil { + // silent return, no patch + return + } + + // append to patch list + // patchContents = append(patchContents, recipePatch) + patchMap[patchID] = recipePatch + } + } + } + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(patchMap) + + rr.taoLogger.Log.Debug("RecipeRouter.getSavedAsPatches", zap.Any("patchMap", patchMap)) +} + func (rr *RecipeRouter) getToppings(w http.ResponseWriter, r *http.Request) { countryID := chi.URLParam(r, "country") @@ -626,7 +724,7 @@ func (rr *RecipeRouter) getRawRecipeOfProductCode(w http.ResponseWriter, r *http productCode := chi.URLParam(r, "product_code") // debug - rr.taoLogger.Log.Debug("RecipeRouter.getRawRecipeOfProductCode", zap.Any("countryID", countryID), zap.Any("filename", filename), zap.Any("productCode", productCode)) + // rr.taoLogger.Log.Debug("RecipeRouter.getRawRecipeOfProductCode", zap.Any("countryID", countryID), zap.Any("filename", filename), zap.Any("productCode", productCode)) w.Header().Add("Content-Type", "application/json") @@ -638,7 +736,7 @@ func (rr *RecipeRouter) getRawRecipeOfProductCode(w http.ResponseWriter, r *http } // return recipe - rr.taoLogger.Log.Debug("RecipeRouter.getRawRecipeOfProductCode", zap.Any("recipe", recipe)) + // rr.taoLogger.Log.Debug("RecipeRouter.getRawRecipeOfProductCode", zap.Any("recipe", recipe)) json.NewEncoder(w).Encode(recipe) }