From 43e6eea25340bcf00cd9eda33a9c1eb70a710996 Mon Sep 17 00:00:00 2001 From: Rafhan Mazaya Fathurrahman Date: Thu, 2 Jul 2026 16:57:47 +0700 Subject: [PATCH] feat: make manual-images list dynamic and resolve checkmark encoding issues --- backend/compare_accuracy.py | 4 +- backend/compile_json.py | 2 +- backend/fix_encoding_chars.py | 33 +++++++++++ backend/fix_store_labels.py | 2 +- .../pfm-web-app/public/comparison_report.xlsx | Bin 14571 -> 14535 bytes .../src/app/api/manual-images/route.ts | 52 ++++++------------ backend/sources/manual_labels.json | 4 +- 7 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 backend/fix_encoding_chars.py diff --git a/backend/compare_accuracy.py b/backend/compare_accuracy.py index 95a34f8..3762222 100644 --- a/backend/compare_accuracy.py +++ b/backend/compare_accuracy.py @@ -27,7 +27,7 @@ def main(): # Load automated results auto_results = {} - with open(jsonl_file, "r") as f: + with open(jsonl_file, "r", encoding="utf-8") as f: for line in f: if not line.strip(): continue @@ -44,7 +44,7 @@ def main(): manual_labels = {} for mf in manual_files: try: - with open(mf, "r") as f: + with open(mf, "r", encoding="utf-8") as f: data = json.load(f) filename = data.get("filename") if filename: diff --git a/backend/compile_json.py b/backend/compile_json.py index 33aab02..4fc56f8 100644 --- a/backend/compile_json.py +++ b/backend/compile_json.py @@ -23,7 +23,7 @@ def main(): for mf in sorted(manual_files): try: - with open(mf, "r") as f: + with open(mf, "r", encoding="utf-8") as f: data = json.load(f) manual_list.append(data) except Exception as e: diff --git a/backend/fix_encoding_chars.py b/backend/fix_encoding_chars.py new file mode 100644 index 0000000..118f987 --- /dev/null +++ b/backend/fix_encoding_chars.py @@ -0,0 +1,33 @@ +import os +import glob + +def main(): + uploads_dir = "backend/uploads" + if not os.path.exists(uploads_dir): + uploads_dir = "uploads" + + manual_pattern = os.path.join(uploads_dir, "manual_label_*.json") + manual_files = glob.glob(manual_pattern) + fixed_count = 0 + + for mf in manual_files: + try: + with open(mf, "r", encoding="utf-8") as f: + content = f.read() + + if "✓" in content: + # Replace with the correct checkmark character + content = content.replace("✓", "✓") + + with open(mf, "w", encoding="utf-8") as f: + f.write(content) + + print(f"Fixed encoding corruption in: {mf}") + fixed_count += 1 + except Exception as e: + print(f"Error fixing {mf}: {e}") + + print(f"Encoding fix completed. Files fixed: {fixed_count}") + +if __name__ == "__main__": + main() diff --git a/backend/fix_store_labels.py b/backend/fix_store_labels.py index 923d72e..9ee9803 100644 --- a/backend/fix_store_labels.py +++ b/backend/fix_store_labels.py @@ -17,7 +17,7 @@ def main(): for mf in manual_files: try: - with open(mf, "r") as f: + with open(mf, "r", encoding="utf-8") as f: data = json.load(f) is_modified = False diff --git a/backend/pfm-web-app/public/comparison_report.xlsx b/backend/pfm-web-app/public/comparison_report.xlsx index 0e6cd0b79f6d52b7fc91472d29cba486b4e7e6ff..84fd945f98b3c126d6890a0b42ea2655b20e59d9 100644 GIT binary patch delta 5943 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 diff --git a/backend/pfm-web-app/src/app/api/manual-images/route.ts b/backend/pfm-web-app/src/app/api/manual-images/route.ts index fd74b47..e44deca 100644 --- a/backend/pfm-web-app/src/app/api/manual-images/route.ts +++ b/backend/pfm-web-app/src/app/api/manual-images/route.ts @@ -1,38 +1,22 @@ import { NextResponse } from "next/server"; - -const testFiles = [ - "1782870899198-sample_do.jpeg", - "1782872141829-rotated_1782872118246_rotated_1782872112296_rotated_1782872107513_CAP3481952560331460805.jpg", - "1782875271815-rotated_1782875258464_rotated_1782875254091_rotated_1782875250123_CAP1599226410575173446.jpg", - "1782884664859-rotated_1782884661516_rotated_1782884658097_rotated_1782884654697_CAP5956452738616729026.jpg", - "1782888127716-CAP6161747431193129837.jpg", - "1782888211457-rotated_1782888204591_rotated_1782888199962_rotated_1782888195402_CAP7202641176939787142.jpg", - "1782888609885-rotated_1782888593813_1000000454.jpg", - "1782890303600-1000000465.jpg", - "1782892728794-1000000466.jpg", - "1782909791970-sample_do.jpeg", - "IMG_20260630_145445.jpg", - "IMG_20260701_134446.jpg", - "IMG_20260701_134504.jpg", - "IMG_20260701_134533.jpg", - "IMG_20260701_134555.jpg", - "IMG_20260701_134555~2.jpg", - "IMG_20260701_134635.jpg", - "IMG_20260701_134636.jpg", - "IMG_20260701_134646.jpg", - "IMG_20260701_134646~2.jpg", - "IMG_20260701_134704.jpg", - "IMG_20260701_134704~2.jpg", - "IMG_20260701_134810.jpg", - "IMG_20260701_134817.jpg", - "IMG_20260701_135900.jpg", - "IMG_20260701_135910.jpg", - "IMG_20260701_135923.jpg", - "IMG_20260701_135938.jpg", - "IMG_20260701_135950.jpg", - "IMG_20260701_140005.jpg" -]; +import fs from "fs"; +import path from "path"; export async function GET() { - return NextResponse.json({ files: testFiles }); + try { + const dirPath = path.join(process.cwd(), "public/test-images"); + if (!fs.existsSync(dirPath)) { + return NextResponse.json({ files: [] }); + } + const files = fs.readdirSync(dirPath).filter(file => { + const ext = path.extname(file).toLowerCase(); + return ext === ".jpg" || ext === ".jpeg" || ext === ".png"; + }); + // Sort files to keep consistent ordering in UI + files.sort(); + return NextResponse.json({ files }); + } catch (error: any) { + console.error("Error reading test-images directory:", error); + return NextResponse.json({ error: error.message }, { status: 500 }); + } } diff --git a/backend/sources/manual_labels.json b/backend/sources/manual_labels.json index 07f970e..d7f2447 100644 --- a/backend/sources/manual_labels.json +++ b/backend/sources/manual_labels.json @@ -114,7 +114,7 @@ "kodeBarang": "21002601", "namaBarang": "Prima Nasi Spicy Chick Sambal Geprek COPY", "banyak": "1 80X", - "jumlah": "6 PAC✓" + "jumlah": "6 PAC✓" } ] }, @@ -338,7 +338,7 @@ "kodeBarang": "11048000", "namaBarang": "BEBEK PARTING-NEW(*)", "banyak": "2 BOX", - "jumlah": "30 PAC ✓" + "jumlah": "30 PAC ✓" } ] },