File size: 3,895 Bytes
abbe984
 
228d915
eaad402
cac513c
1ba7288
4210dea
cac513c
228d915
4973a44
abbe984
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eaad402
 
cac513c
abbe984
 
eaad402
440ae28
 
abbe984
 
cac513c
 
abbe984
 
 
 
 
 
 
 
 
 
 
1ba7288
abbe984
 
 
1ba7288
abbe984
 
 
228d915
abbe984
812bee8
 
 
 
 
228d915
abbe984
 
 
 
440ae28
abbe984
 
 
 
 
440ae28
abbe984
440ae28
abbe984
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os

import gradio as gr
import pandas as pd
from geolocation_apis import addresses_to_coordinates, coordinates_to_route
from pdf_parser import process_pdf_hebrew_rtl
from llm_api import llm_parser
from map_visualize import generate_route_map


def summarize_items(items):
    """
    Returns a preview list for the dataset component.
    """
    return [
        [
            f"{i + 1}. [{item['source']}] " + (
                os.path.basename(item['file'].name) if item['source'] == 'PDF' else item['content'][:40]
            ) + "..."
        ]
        for i, item in enumerate(items)
    ]


def add_files(files, items):
    """
    Adds uploaded PDF file objects to the state.
    """
    new_items = [{"source": "PDF", "file": f} for f in files]
    items += new_items
    return items, gr.update(samples=summarize_items(items))


def add_text(text, items):
    """
    Adds pasted text content to the state.
    """
    if text.strip():
        items.append({"source": "Paste", "content": text.strip()})
    return items, gr.update(samples=summarize_items(items))


def delete_item(evt: gr.SelectData, items):
    """
    Deletes an item when selected in the dataset component.
    """
    del items[evt.index]
    return items, gr.update(samples=summarize_items(items))


def run_pipeline(items):
    """
    Processes PDFs and pasted text through the LLM pipeline,
    geocodes addresses, computes an optimized route,
    and writes two HTML outputs (data table and map).
    """
    # Separate file-based and pasted inputs
    pdf_paths = [item['file'].name for item in items if item['source'] == 'PDF']
    # Parse PDFs to text
    text_docs = [process_pdf_hebrew_rtl(path) for path in pdf_paths]
    # Include any pasted text directly
    pasted_texts = [item['content'] for item in items if item['source'] == 'Paste']

    # Combine for LLM parsing
    docs = text_docs + pasted_texts
    results, llm_parsed = llm_parser(docs=docs)

    # Geolocation and routing
    locations = addresses_to_coordinates([r.business_address for r in results])
    points = [loc.coords for loc in locations]
    route = coordinates_to_route(points)

    # Build data table
    df = pd.DataFrame([loc.to_dict() for loc in locations])
    llm_parsed = llm_parsed.rename(columns={'business_address': 'Address'})
    df = df.join(llm_parsed.set_index('Address'), on='Address')

    # Write HTML outputs
    data_output_path = './data_output.html'
    with open(data_output_path, mode='w', encoding='utf-8') as html:
        html.write(df.to_html(index=False, escape=False))

    map_output_path = './map_output.html'
    generate_route_map(route, map_output_path)

    return data_output_path, map_output_path


# Build Gradio interface
with gr.Blocks() as demo:
    state = gr.State([])

    with gr.Row():
        file_input = gr.Files(file_types=['.pdf'], label="Upload PDFs")
        file_btn = gr.Button("Add PDFs")

    with gr.Row():
        paste_box = gr.Textbox(lines=3, placeholder="Paste text content...", label="Paste Text")
        paste_btn = gr.Button("Add Text")

    gr.Markdown("### ๐Ÿ“ Inputs:")
    item_list = gr.Dataset(
        components=[gr.Textbox(visible=False)],  # hide the textbox
        samples=[],
        headers=["Items"]
    )

    # Register callbacks for managing inputs
    file_btn.click(add_files, inputs=[file_input, state], outputs=[state, item_list])
    paste_btn.click(add_text, inputs=[paste_box, state], outputs=[state, item_list])
    item_list.select(delete_item, inputs=state, outputs=[state, item_list])

    # Processing and output
    process_btn = gr.Button("Process & Download HTML")
    data_out = gr.File(label="๐Ÿ“Š Business Data HTML")
    map_out = gr.File(label="๐Ÿ—บ๏ธ Route Map HTML")
    process_btn.click(run_pipeline, inputs=state, outputs=[data_out, map_out])

# Launch the app
if __name__ == '__main__':
    demo.launch()