Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import re | |
| import os | |
| # ---------- Helpers ---------- | |
| def sanitize_string(s): | |
| return re.sub(r'[^A-Z0-9]', '', s.upper()) | |
| def extract_letters(s, count): | |
| letters = re.sub(r'[^A-Z]', '', s.upper()) | |
| return letters[:count].ljust(count, '0') | |
| def extract_street_number(text: str) -> str: | |
| text_upper = text.upper() | |
| patterns = [ | |
| r'ROOM\s+(\d{1,4})', | |
| r'BUILDING\s+(\d{1,4})', | |
| r'NO\.?\s+(\d{1,4})', | |
| ] | |
| for pattern in patterns: | |
| match = re.search(pattern, text_upper) | |
| if match: | |
| return match.group(1) | |
| fallback = re.search(r'\d{1,4}', text_upper) | |
| return fallback.group(0) if fallback else '' | |
| def extract_city(text: str) -> str: | |
| city_match = re.search(r'([A-Z]+) CITY', text.upper()) | |
| return city_match.group(1) if city_match else "UNKNOWN" | |
| def extract_company_letters(name: str) -> str: | |
| words = name.upper().split() | |
| first = extract_letters(words[0], 3) if len(words) > 0 else '' | |
| second = extract_letters(words[1], 3) if len(words) > 1 else '' | |
| return (first + second)[:6].ljust(3, '0') | |
| def generate_mid(country_code, company_name, full_address): | |
| if not country_code or not company_name or not full_address: | |
| return None | |
| cc = sanitize_string(country_code)[:2] | |
| if len(cc) != 2: | |
| return None | |
| company_part = extract_company_letters(company_name) | |
| street_number = extract_street_number(full_address) | |
| city = extract_city(full_address) | |
| city_part = extract_letters(city, 3) | |
| return f"{cc}{company_part}{street_number}{city_part}" | |
| # ---------- Manual Entry ---------- | |
| def manual_mid(full_address, manual_company_name, country_code): | |
| if not full_address.strip(): | |
| return "β Please provide a full address." | |
| cc = sanitize_string(country_code or "CN")[:2] | |
| if len(cc) != 2: | |
| return "β Invalid country code." | |
| company_part = extract_company_letters(manual_company_name or "") | |
| street_number = extract_street_number(full_address) | |
| city = extract_city(full_address) | |
| city_part = extract_letters(city, 3) | |
| mid = f"{cc}{company_part}{street_number}{city_part}" | |
| return ( | |
| f"β MID: {mid}\n\n" | |
| f"Company: {manual_company_name or '(auto)'}\n" | |
| f"Street #: {street_number or '(not found)'}\n" | |
| f"City: {city}\n" | |
| f"Country: {cc}" | |
| ) | |
| # ---------- File Upload Handling ---------- | |
| def process_excel(file_obj): | |
| try: | |
| df = pd.read_excel(file_obj) | |
| if not all(col in df.columns for col in ["CountryCode", "CompanyName", "FullAddress"]): | |
| return "β Missing required columns: CountryCode, CompanyName, FullAddress", None | |
| df["MID"] = df.apply( | |
| lambda row: generate_mid( | |
| row["CountryCode"], | |
| row["CompanyName"], | |
| row["FullAddress"] | |
| ), | |
| axis=1 | |
| ) | |
| output_path = "generated_mid_output.xlsx" | |
| df.to_excel(output_path, index=False) | |
| return "β MID generation completed. Download the file below.", output_path | |
| except Exception as e: | |
| return f"β Error processing file: {str(e)}", None | |
| # ---------- Gradio UI ---------- | |
| with gr.Blocks(title="MID Generator") as demo: | |
| gr.Markdown("## π·οΈ CBP MID Code Generator") | |
| with gr.Tab("π€ Manual Input"): | |
| full_address = gr.Textbox(label="Full Address", lines=3) | |
| company_name = gr.Textbox(label="Company Name", placeholder="Optional (auto-detect if blank)") | |
| country_code = gr.Textbox(label="Country Code", value="CN") | |
| mid_output = gr.Textbox(label="Generated MID", lines=6) | |
| gen_btn = gr.Button("Generate MID") | |
| gen_btn.click( | |
| fn=manual_mid, | |
| inputs=[full_address, company_name, country_code], | |
| outputs=mid_output | |
| ) | |
| with gr.Tab("π Upload Excel File"): | |
| gr.Markdown("**Upload an Excel file with the following columns:** `CountryCode`, `CompanyName`, `FullAddress`") | |
| excel_input = gr.File(file_types=[".xlsx"], label="Upload Excel File") | |
| file_status = gr.Textbox(label="Status", interactive=False) | |
| download_link = gr.File(label="Download Output") | |
| excel_input.change( | |
| fn=process_excel, | |
| inputs=[excel_input], | |
| outputs=[file_status, download_link] | |
| ) | |
| with gr.Tab("π Template"): | |
| gr.Markdown("β¬οΈ Download the sample Excel template:") | |
| gr.File(value="mid_upload_template.xlsx", label="Download Template") | |
| demo.launch() | |