| import gradio as gr |
| import os |
| import pickle |
| import datetime |
| import pandas as pd |
| import plotly.graph_objects as go |
| from googleapiclient.discovery import build |
| from google_auth_oauthlib.flow import InstalledAppFlow |
| from google.auth.transport.requests import Request |
| import io |
| from googleapiclient.http import MediaIoBaseDownload |
| from huggingface_hub import InferenceClient |
|
|
| |
| SCOPES = ['https://www.googleapis.com/auth/calendar'] |
|
|
| def authenticate_google_calendar(): |
| """Authenticate and return the Google Calendar API service.""" |
| creds = None |
| |
| if os.path.exists('token.pickle'): |
| with open('token.pickle', 'rb') as token: |
| creds = pickle.load(token) |
| |
| |
| if not creds or not creds.valid: |
| if creds and creds.expired and creds.refresh_token: |
| creds.refresh(Request()) |
| else: |
| flow = InstalledAppFlow.from_client_secrets_file( |
| 'credentials.json', SCOPES) |
| creds = flow.run_local_server(port=0) |
| |
| |
| with open('token.pickle', 'wb') as token: |
| pickle.dump(creds, token) |
|
|
| return build('calendar', 'v3', credentials=creds) |
|
|
| def add_event_to_calendar(event_details): |
| """Add the event to the user's Google Calendar.""" |
| service = authenticate_google_calendar() |
|
|
| event = { |
| 'summary': event_details['title'], |
| 'start': { |
| 'dateTime': f"{event_details['date']}T{event_details['time']}:00", |
| 'timeZone': 'UTC', |
| }, |
| 'end': { |
| 'dateTime': f"{event_details['date']}T{event_details['time']}:00", |
| 'timeZone': 'UTC', |
| }, |
| } |
|
|
| try: |
| |
| created_event = service.events().insert(calendarId='primary', body=event).execute() |
| return created_event |
| except Exception as e: |
| return f"Failed to add event: {str(e)}" |
|
|
| def get_calendar_events(): |
| """Fetch events from the user's Google Calendar.""" |
| service = authenticate_google_calendar() |
| now = datetime.datetime.utcnow().isoformat() + 'Z' |
| events_result = service.events().list(calendarId='primary', timeMin=now, maxResults=10, singleEvents=True, orderBy='startTime').execute() |
| events = events_result.get('items', []) |
|
|
| |
| events_data = [] |
| for event in events: |
| event_start = event['start'].get('dateTime', event['start'].get('date')) |
| events_data.append({ |
| 'Event': event['summary'], |
| 'Start Time': event_start |
| }) |
|
|
| |
| df = pd.DataFrame(events_data) |
| df['Start Time'] = pd.to_datetime(df['Start Time']) |
| return df |
|
|
| def plot_calendar(events_df): |
| """Plot an interactive calendar using Plotly with a Notion-like clean design.""" |
| |
| |
| events_df['Start Time'] = pd.to_datetime(events_df['Start Time']) |
| events_df['Date'] = events_df['Start Time'].dt.date |
| events_df['Hour'] = events_df['Start Time'].dt.hour |
| events_df['Minute'] = events_df['Start Time'].dt.minute |
| |
| |
| unique_dates = events_df['Date'].unique() |
| |
| |
| calendar_grid = go.Figure() |
| calendar_grid.update_layout( |
| title="Upcoming Events", |
| xaxis=dict(tickvals=list(range(len(unique_dates))), ticktext=unique_dates, title="Date"), |
| yaxis=dict(tickvals=[0, 1, 2, 3, 4, 5], ticktext=["9 AM", "12 PM", "3 PM", "6 PM", "9 PM", "12 AM"], title="Time Slot"), |
| showlegend=False, |
| margin=dict(l=40, r=40, b=40, t=40), |
| height=600, |
| template="plotly_white" |
| ) |
| |
| |
| for _, event in events_df.iterrows(): |
| start_hour = event['Hour'] |
| event_date = event['Date'] |
| event_time = f"{start_hour}:00" |
| event_text = event['Event'] |
| |
| calendar_grid.add_trace(go.Scatter( |
| x=[list(unique_dates).index(event_date)], |
| y=[start_hour % 12], |
| text=event_text, |
| mode="markers+text", |
| textposition="middle center", |
| marker=dict(color="blue", size=12, opacity=0.7), |
| name=event_text |
| )) |
|
|
| return calendar_grid |
|
|
| |
| client = InferenceClient("HuggingFaceH4/zephyr-7b-beta") |
|
|
| def respond( |
| message, |
| history: list[tuple[str, str]], |
| system_message, |
| max_tokens, |
| temperature, |
| top_p, |
| ): |
| |
| 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=max_tokens, |
| stream=True, |
| temperature=temperature, |
| top_p=top_p, |
| ): |
| token = message.choices[0].delta.content |
| response += token |
| yield response |
|
|
| |
| if "schedule" in message.lower(): |
| |
| event_details = parse_event_details(message) |
| created_event = add_event_to_calendar(event_details) |
| events_df = get_calendar_events() |
| return f"Event scheduled for {event_details['date']} at {event_details['time']}.\n{plot_calendar(events_df)}" |
|
|
| def parse_event_details(user_input): |
| """Parse user input to extract event details like title, date, and time.""" |
| today = datetime.date.today() |
| tomorrow = today + datetime.timedelta(days=1) |
| |
| |
| event_title = "Meeting" |
| event_date = tomorrow.strftime("%Y-%m-%d") |
| event_time = "15:00" |
| |
| return {"title": event_title, "date": event_date, "time": event_time} |
|
|
| |
| with gr.Blocks() as demo: |
| gr.Markdown("## Chatbot for Scheduling and Calendar") |
| chatbot = gr.ChatInterface( |
| respond, |
| additional_inputs=[ |
| gr.Textbox(value="You are a friendly chatbot. You can help schedule events.", label="System message"), |
| gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"), |
| gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"), |
| gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"), |
| ], |
| ) |
|
|
| with gr.Row(): |
| calendar_button = gr.Button("Show Calendar") |
| calendar_plot = gr.Plot() |
|
|
| calendar_button.click( |
| lambda: plot_calendar(get_calendar_events()), |
| outputs=calendar_plot |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|