joycecast commited on
Commit
69184f3
Β·
verified Β·
1 Parent(s): 73752c6

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +136 -0
  2. mid_upload_template.xlsx +0 -0
  3. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import re
4
+ import os
5
+
6
+ # ---------- Helpers ----------
7
+
8
+ def sanitize_string(s):
9
+ return re.sub(r'[^A-Z0-9]', '', s.upper())
10
+
11
+ def extract_letters(s, count):
12
+ letters = re.sub(r'[^A-Z]', '', s.upper())
13
+ return letters[:count].ljust(count, '0')
14
+
15
+ def extract_street_number(text: str) -> str:
16
+ text_upper = text.upper()
17
+ patterns = [
18
+ r'ROOM\s+(\d{1,4})',
19
+ r'BUILDING\s+(\d{1,4})',
20
+ r'NO\.?\s+(\d{1,4})',
21
+ ]
22
+ for pattern in patterns:
23
+ match = re.search(pattern, text_upper)
24
+ if match:
25
+ return match.group(1)
26
+ fallback = re.search(r'\d{1,4}', text_upper)
27
+ return fallback.group(0) if fallback else ''
28
+
29
+ def extract_city(text: str) -> str:
30
+ city_match = re.search(r'([A-Z]+) CITY', text.upper())
31
+ return city_match.group(1) if city_match else "UNKNOWN"
32
+
33
+ def extract_company_letters(name: str) -> str:
34
+ words = name.upper().split()
35
+ first = extract_letters(words[0], 3) if len(words) > 0 else ''
36
+ second = extract_letters(words[1], 3) if len(words) > 1 else ''
37
+ return (first + second)[:6].ljust(3, '0')
38
+
39
+ def generate_mid(country_code, company_name, full_address):
40
+ if not country_code or not company_name or not full_address:
41
+ return None
42
+ cc = sanitize_string(country_code)[:2]
43
+ if len(cc) != 2:
44
+ return None
45
+ company_part = extract_company_letters(company_name)
46
+ street_number = extract_street_number(full_address)
47
+ city = extract_city(full_address)
48
+ city_part = extract_letters(city, 3)
49
+ return f"{cc}{company_part}{street_number}{city_part}"
50
+
51
+ # ---------- Manual Entry ----------
52
+
53
+ def manual_mid(full_address, manual_company_name, country_code):
54
+ if not full_address.strip():
55
+ return "❌ Please provide a full address."
56
+
57
+ cc = sanitize_string(country_code or "CN")[:2]
58
+ if len(cc) != 2:
59
+ return "❌ Invalid country code."
60
+
61
+ company_part = extract_company_letters(manual_company_name or "")
62
+ street_number = extract_street_number(full_address)
63
+ city = extract_city(full_address)
64
+ city_part = extract_letters(city, 3)
65
+
66
+ mid = f"{cc}{company_part}{street_number}{city_part}"
67
+
68
+ return (
69
+ f"βœ… MID: {mid}\n\n"
70
+ f"Company: {manual_company_name or '(auto)'}\n"
71
+ f"Street #: {street_number or '(not found)'}\n"
72
+ f"City: {city}\n"
73
+ f"Country: {cc}"
74
+ )
75
+
76
+ # ---------- File Upload Handling ----------
77
+
78
+ def process_excel(file_obj):
79
+ try:
80
+ df = pd.read_excel(file_obj)
81
+
82
+ if not all(col in df.columns for col in ["CountryCode", "CompanyName", "FullAddress"]):
83
+ return "❌ Missing required columns: CountryCode, CompanyName, FullAddress", None
84
+
85
+ df["MID"] = df.apply(
86
+ lambda row: generate_mid(
87
+ row["CountryCode"],
88
+ row["CompanyName"],
89
+ row["FullAddress"]
90
+ ),
91
+ axis=1
92
+ )
93
+
94
+ output_path = "generated_mid_output.xlsx"
95
+ df.to_excel(output_path, index=False)
96
+ return "βœ… MID generation completed. Download the file below.", output_path
97
+
98
+ except Exception as e:
99
+ return f"❌ Error processing file: {str(e)}", None
100
+
101
+ # ---------- Gradio UI ----------
102
+
103
+ with gr.Blocks(title="MID Generator") as demo:
104
+ gr.Markdown("## 🏷️ CBP MID Code Generator")
105
+
106
+ with gr.Tab("πŸ”€ Manual Input"):
107
+ full_address = gr.Textbox(label="Full Address", lines=3)
108
+ company_name = gr.Textbox(label="Company Name", placeholder="Optional (auto-detect if blank)")
109
+ country_code = gr.Textbox(label="Country Code", value="CN")
110
+
111
+ mid_output = gr.Textbox(label="Generated MID", lines=6)
112
+ gen_btn = gr.Button("Generate MID")
113
+
114
+ gen_btn.click(
115
+ fn=manual_mid,
116
+ inputs=[full_address, company_name, country_code],
117
+ outputs=mid_output
118
+ )
119
+
120
+ with gr.Tab("πŸ“ Upload Excel File"):
121
+ gr.Markdown("**Upload an Excel file with the following columns:** `CountryCode`, `CompanyName`, `FullAddress`")
122
+ excel_input = gr.File(file_types=[".xlsx"], label="Upload Excel File")
123
+ file_status = gr.Textbox(label="Status", interactive=False)
124
+ download_link = gr.File(label="Download Output")
125
+
126
+ excel_input.change(
127
+ fn=process_excel,
128
+ inputs=[excel_input],
129
+ outputs=[file_status, download_link]
130
+ )
131
+
132
+ with gr.Tab("πŸ“„ Template"):
133
+ gr.Markdown("⬇️ Download the sample Excel template:")
134
+ gr.File(value="mid_upload_template.xlsx", label="Download Template")
135
+
136
+ demo.launch()
mid_upload_template.xlsx ADDED
Binary file (5.68 kB). View file
 
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ pandas
2
+ openpyxl