File size: 2,812 Bytes
5d3056e
21eada5
4fef53c
bf857f3
437c339
feedb11
21eada5
437c339
 
f474072
437c339
 
4fef53c
f474072
 
 
4fef53c
feedb11
437c339
 
4fef53c
437c339
f474072
feedb11
 
437c339
feedb11
f474072
437c339
f474072
437c339
feedb11
f474072
437c339
4fef53c
437c339
 
 
b0957f0
437c339
f474072
437c339
f474072
4fef53c
437c339
 
 
b0957f0
4fef53c
437c339
 
 
f474072
 
 
4fef53c
9460907
437c339
 
 
 
 
 
21eada5
437c339
 
 
21eada5
437c339
21eada5
437c339
 
f474072
 
 
 
437c339
 
 
 
 
 
 
 
 
 
b0957f0
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
import gradio as gr
import pandas as pd
import requests
from docx import Document
import tempfile
from datetime import datetime


def search_duckduckgo(query):
    if not query.strip():
        return [], "⚠️ Please enter a valid query."

    url = f"https://api.duckduckgo.com/?q={query}&format=json&no_redirect=1"
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()

        results = []
        for topic in data.get("RelatedTopics", []):
            if "Text" in topic and "FirstURL" in topic:
                results.append([topic["Text"], topic["FirstURL"]])
            elif "Topics" in topic:
                for sub in topic["Topics"]:
                    if "Text" in sub and "FirstURL" in sub:
                        results.append([sub["Text"], sub["FirstURL"]])

        if not results:
            return [], "πŸ” No results found."

        return results, f"βœ… Found {len(results)} results for: **{query}**"

    except Exception as e:
        return [], f"❌ Error fetching results: {str(e)}"


def save_csv(data):
    if not data:
        return ""
    df = pd.DataFrame(data, columns=["Title", "URL"])
    with tempfile.NamedTemporaryFile(delete=False, suffix=".csv", mode="w", newline='', encoding="utf-8") as tmp:
        df.to_csv(tmp.name, index=False)
        return tmp.name


def save_docx(data):
    if not data:
        return ""
    doc = Document()
    doc.add_heading("Search Results", 0)
    for i, (title, url) in enumerate(data, start=1):
        doc.add_paragraph(f"{i}. {title}\n{url}")
    with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp:
        doc.save(tmp.name)
        return tmp.name


with gr.Blocks() as demo:
    gr.Markdown("## πŸ”Ž DuckDuckGo Search with Export")
    gr.Markdown(
        "Enter a search query to get instant answers from DuckDuckGo. "
        "You can also download the results as CSV or Word DOCX."
    )

    query_input = gr.Textbox(placeholder="Enter a topic (e.g., climate change)", label="Search Query")
    search_button = gr.Button("Search")
    status_output = gr.Markdown()

    results_table = gr.Dataframe(headers=["Title", "URL"], label="Results", interactive=False)

    csv_button = gr.Button("Export as CSV")
    docx_button = gr.Button("Export as DOCX")

    csv_file = gr.File(label="Download CSV")
    docx_file = gr.File(label="Download DOCX")

    # App logic
    def do_search(query):
        results, status = search_duckduckgo(query)
        return results, status

    search_button.click(fn=do_search, inputs=query_input, outputs=[results_table, status_output])
    csv_button.click(fn=save_csv, inputs=results_table, outputs=csv_file)
    docx_button.click(fn=save_docx, inputs=results_table, outputs=docx_file)

demo.launch()