Spaces:
Sleeping
Sleeping
| import os, json, gradio as gr | |
| from PIL import Image | |
| import pytesseract | |
| # --- import your logic --- | |
| from checker import ( | |
| evaluate_section, | |
| fair_housing_flags, | |
| COMPANY_NAME_DEFAULT, | |
| COMPANY_PHONES_DEFAULT, | |
| DISCLAIMER_DEFAULT, | |
| contains_disclaimer, | |
| count_name_instances, | |
| count_phone_instances, | |
| ) | |
| def run_check(image, ptxt, social, agent_name, agent_phone, | |
| company_name, company_phones_json, disclaimer): | |
| # OCR | |
| itxt = "" | |
| ocr_err = None | |
| if image is not None: | |
| try: | |
| itxt = pytesseract.image_to_string(image) | |
| except Exception as e: | |
| ocr_err = str(e) | |
| # Compose combined content | |
| content = "\n\n".join([x for x in [itxt, ptxt, f"Social={social}"] if x]) | |
| # Fair-housing flags on combined content | |
| fh_flags = fair_housing_flags(content) | |
| fair_housing_block = {"compliant": len(fh_flags) == 0, "Flags": fh_flags} | |
| # Parse office phones | |
| try: | |
| company_phones = json.loads(company_phones_json) | |
| if isinstance(company_phones, str): | |
| company_phones = [company_phones] | |
| except Exception: | |
| company_phones = COMPANY_PHONES_DEFAULT | |
| # Social disclaimer toggle (same behavior as your prototype) | |
| require_disclaimer_on_social = os.getenv("REQUIRE_DISCLAIMER_ON_SOCIAL", "1") == "1" | |
| def eval_section(text): | |
| flags = [] | |
| company_name_count = count_name_instances(text, company_name) | |
| agent_name_count = count_name_instances(text, agent_name) | |
| office_phone_count = count_phone_instances(text, company_phones) | |
| agent_phone_count = count_phone_instances(text, [agent_phone] if agent_phone else []) | |
| name_equal = (company_name_count == agent_name_count) | |
| phone_equal = (office_phone_count == agent_phone_count) | |
| disclaimer_ok = True | |
| if social and require_disclaimer_on_social: | |
| disclaimer_ok = contains_disclaimer(text, disclaimer) | |
| if not disclaimer_ok: | |
| flags.append("Missing disclaimer on social content") | |
| if not name_equal: | |
| flags.append(f"Name imbalance: company={company_name_count} vs agent={agent_name_count}") | |
| if not phone_equal: | |
| flags.append(f"Phone imbalance: office={office_phone_count} vs agent={agent_phone_count}") | |
| compliant = name_equal and phone_equal and disclaimer_ok | |
| return {"compliant": compliant, "Flags": flags} | |
| img_block = eval_section(itxt) | |
| if ocr_err: | |
| img_block["Flags"].append(f"OCR error: {ocr_err}") | |
| ptxt_block = eval_section(ptxt or "") | |
| # final payload in your exact shape | |
| payload = { | |
| "Fair_Housing": fair_housing_block, | |
| "img": img_block, | |
| "Ptxt": ptxt_block | |
| } | |
| return json.dumps(payload, indent=2) | |
| with gr.Blocks(title="Image + Text Compliance Check") as demo: | |
| gr.Markdown("# Image + Text Compliance Check") | |
| with gr.Row(): | |
| image = gr.Image(type="pil", label="Upload image (optional)") | |
| ptxt = gr.Textbox(lines=8, label="Post Text (Ptxt)") | |
| with gr.Row(): | |
| social = gr.Checkbox(label="Social", value=False) | |
| agent_name = gr.Textbox(label="Agent Name", placeholder="e.g., Jane Doe") | |
| agent_phone = gr.Textbox(label="Agent Phone (digits or formatted)") | |
| with gr.Accordion("Advanced", open=False): | |
| company_name = gr.Textbox(label="Company Name", value=COMPANY_NAME_DEFAULT) | |
| company_phones_json = gr.Textbox(label="Company Phones (JSON list)", value=json.dumps(COMPANY_PHONES_DEFAULT)) | |
| disclaimer = gr.Textbox(label="Disclaimer", value=DISCLAIMER_DEFAULT) | |
| run_btn = gr.Button("Run Compliance Check") | |
| out = gr.Code(label="Result JSON", language="json") | |
| run_btn.click( | |
| fn=run_check, | |
| inputs=[image, ptxt, social, agent_name, agent_phone, company_name, company_phones_json, disclaimer], | |
| outputs=[out], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |