File size: 6,849 Bytes
1d029eb
 
e128db1
 
a8a3ce3
1ae3fcb
91ab614
a8a3ce3
 
5ff825c
 
a8a3ce3
f7a1b1d
a8a3ce3
 
216e873
 
 
a8a3ce3
216e873
a8a3ce3
f7a1b1d
a19992d
a8a3ce3
 
f7a1b1d
a8a3ce3
f7a1b1d
 
a8a3ce3
13d2f6c
a19992d
 
91ab614
a8a3ce3
 
e128db1
 
 
176deb5
 
e128db1
1ae3fcb
a8a3ce3
0897fdf
 
176deb5
0897fdf
176deb5
a8a3ce3
 
 
 
 
176deb5
fe3ee0f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0897fdf
fe3ee0f
 
 
0897fdf
fe3ee0f
 
 
 
 
 
 
 
1ae3fcb
 
 
 
0897fdf
e128db1
1ae3fcb
 
4967af8
1ae3fcb
 
1e2a25a
1ae3fcb
 
 
 
 
 
 
 
 
 
 
 
 
8b94936
1ae3fcb
 
f463dfd
1ae3fcb
 
 
ef1ee2b
f463dfd
 
216e873
05f71ae
 
 
 
 
 
 
 
 
 
 
 
 
 
216e873
 
f329e38
1e2a25a
e128db1
 
 
f463dfd
 
 
 
1ae3fcb
 
f463dfd
075f389
f463dfd
716e1a2
 
 
 
 
 
 
 
a8a3ce3
a02844f
64f77f5
216e873
1e2a25a
8b94936
1e2a25a
e128db1
1e2a25a
 
 
 
5ff825c
 
1ae3fcb
 
 
 
 
5ff825c
1ae3fcb
0897fdf
b3eb52b
5ff825c
 
43b7d18
f463dfd
 
 
 
64b3340
a19992d
 
05f71ae
62b19be
a19992d
 
 
05f71ae
877da7e
 
1ae3fcb
216e873
 
 
a19992d
216e873
 
a19992d
f723138
216e873
f723138
a19992d
f723138
 
216e873
 
 
a19992d
216e873
 
a19992d
d6ea91d
216e873
 
a19992d
216e873
 
1e2a25a
76839f2
 
 
075f389
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import gradio as gr
from huggingface_hub import InferenceClient
import requests
from bs4 import BeautifulSoup
import pandas as pd
import ast

client = InferenceClient("meta-llama/Llama-3.2-3B-Instruct")

# Global data store for the table
data = []

def respond(message, history, system_message):
    messages = [{"role": "system", "content": system_message}]
    for val in history:
        if val[0]:
            messages.append({"role": "user", "content": val[0]})
        if val[1]:
            messages.append({"role": "assistant", "content": val[1]})
            
    messages.append({"role": "user", "content": message})
    
    response = ""
    for message in client.chat_completion(
        messages,
        max_tokens=2048,
        stream=True,
        temperature=0.7,
        top_p=0.9,
    ):
        if message.choices[0].delta.content is not None:
            response += message.choices[0].delta.content
            yield response

def extract_table(url):
    global data
    try:
        response = requests.get(url)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, 'html.parser')
        table = soup.find('table')
        if not table:
            return "<p>No table found on page</p>", []
        
        # Clear existing data
        data = []
        rows = table.find_all('tr')
        for i, row in enumerate(rows[1:]):
            cells = row.find_all('td')
            if len(cells) >= 2:
                data.append({
                    'Date': cells[0].text.strip()[:10],
                    'Topic': cells[1].text.strip(),
                })
        
        #Create HTML table
        html = '''
        <style>
            .dataframe {
                border-collapse: collapse;
                width: 100%;
                margin: 10px 0;
            }
            .dataframe th, .dataframe td {
                border: 1px solid #ddd;
                padding: 8px;
                text-align: left;
            }
            .dataframe th {
                background-color: #f6f8fa;
            }
            .dataframe tr:nth-child(even) {
                background-color: #f9f9f9;
            }
        </style>
        '''
        
        html += '<table class="dataframe">'
        html += '<thead><tr><th>Date</th><th>Topic</th></tr></thead>'
        html += '<tbody>'
        
        for row in data:
            html += f'''
                <tr>
                    <td>{row['Date']}</td>
                    <td>{row['Topic']}</td>
                </tr>
            '''
        html += '</tbody></table>'

        # Generate choices for dropdown
        choices = [f"{row['Topic']} ({row['Date']})" for row in data]
        return html, choices
        
    except Exception as e:
        print(f"Error in extract_table: {e}")
        return f"<p>Error: {str(e)}</p>", []

def prepare_topic(selected_topic):
    print(f"Preparing topic: {selected_topic}")  # Debug print
    try:
        if not selected_topic:
            return "Please select a topic first"
            
        # Handle potential list or string input
        if isinstance(selected_topic, list):
            selected_topic = selected_topic[0] if selected_topic else ""
        
        # Find the index of the selected topic
        for row in data:
            full_topic = f"{row['Topic']} ({row['Date']})"
            if full_topic == selected_topic:
                topic = row["Topic"]
                date = row["Date"]
                message = f"Please prepare a 15-minutes reading material covering main topics for '{topic}' lecture scheduled for {date}"
                print(f"Generated preparation message: {message}")  # Debug print
                return message
        
        print(f"Topic not found: {selected_topic}")
        return "Error: Topic not found"
    
    except Exception as e:
        print(f"Unexpected error in prepare_topic: {e}")
        return "Error: Could not prepare topic"

def add_text(history, text):
    history = history + [(text, None)]
    return history

def generate_response(history, system_message):
    if not history:
        return history
    
    response = ""
    for chunk in respond(history[-1][0], history[:-1], system_message):
        response = chunk
        history[-1] = (history[-1][0], response)
        yield history

def clear_chat():
    return [], ""

# Gradio app
with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=1):
            # Dropdown for selecting topic
            topic_dropdown = gr.Dropdown(
                label="Select Topic",
                choices=[],
                interactive=True,
                value=None
            )

            prepare_btn = gr.Button("Prepare Topic")
            url_input = gr.Textbox(
                value="https://id2223kth.github.io/schedule/",
                label="Table URL"
            )
            table_output = gr.HTML(label="Extracted Table")
            extract_btn = gr.Button("Extract Table")
            
            
            
        with gr.Column(scale=3):
            chatbot = gr.Chatbot()
            msg = gr.Textbox(label="Message")
            system_message = gr.Textbox(
                value="Students lecture preparation companion.",
                label="System message"
            )

            with gr.Row():
                submit = gr.Button("Submit")
                clear = gr.Button("Clear")
    
    # Event handlers
    # Extract table and update dropdown
    def update_interface(url):
        html, choices = extract_table(url)
        return html, gr.Dropdown(choices=choices)

    extract_btn.click(
        fn=update_interface,
        inputs=[url_input],
        outputs=[table_output, topic_dropdown]
    )
    
    # Prepare topic handler
    prepare_btn.click(
        fn=prepare_topic,
        inputs=[topic_dropdown],
        outputs=[msg]
    ).success(
        fn=add_text,
        inputs=[chatbot, msg],
        outputs=[chatbot],
        queue=False
    ).then(
        fn=generate_response,
        inputs=[chatbot, system_message],
        outputs=[chatbot]
    )
    
    # Message submit handlers
    msg.submit(
        fn=add_text,
        inputs=[chatbot, msg],
        outputs=[chatbot]
    ).success(
        fn=lambda: "",
        outputs=[msg]
    ).then(
        fn=generate_response,
        inputs=[chatbot, system_message],
        outputs=[chatbot]
    )
    
    submit.click(
        fn=add_text,
        inputs=[chatbot, msg],
        outputs=[chatbot]
    ).success(
        fn=lambda: "",
        outputs=[msg]
    ).then(
        fn=generate_response,
        inputs=[chatbot, system_message],
        outputs=[chatbot]
    )
    
    # Clear button handler
    clear.click(fn=clear_chat, outputs=[chatbot, msg])

if __name__ == "__main__":
    demo.launch(share=True)