import gradio as gr import re from datetime import datetime def format_daily_plan(notes): """ Parses comma-separated notes/to-dos for time-stamped events and untimed tasks. Outputs a schedule and a numbered task list. """ entries = [n.strip() for n in notes.split(",") if n.strip()] schedule = [] tasks = [] time_pattern = re.compile( r"""(?xi) (?P.*?) # description (non-greedy) \s+at\s+ # literal ' at ' (?P\d{1,2}) # hour (?::(?P\d{2}))? # optional :MM \s*(?Pam|pm)? # optional AM/PM $ """ ) for entry in entries: m = time_pattern.match(entry) if m: desc = m.group("desc").strip().capitalize() hour = int(m.group("hour")) minute = int(m.group("minute") or 0) ampm = m.group("ampm") # normalize to 24h then back to formatted string if ampm: if ampm.lower() == "pm" and hour != 12: hour += 12 if ampm.lower() == "am" and hour == 12: hour = 0 time_str = datetime.strptime(f"{hour:02d}:{minute:02d}", "%H:%M").strftime("%I:%M %p") schedule.append((time_str, desc)) else: tasks.append(entry.capitalize()) # sort schedule by time schedule.sort(key=lambda x: datetime.strptime(x[0], "%I:%M %p")) # build output lines = ["Today's Plan:\n"] for t, d in schedule: lines.append(f"{t}: {d}") if tasks: lines.append("\nTasks:") for idx, task in enumerate(tasks, 1): lines.append(f" {idx}. {task}") return "\n".join(lines) # Gradio UI iface = gr.Interface( fn=format_daily_plan, inputs=gr.Textbox( lines=2, placeholder="e.g. meeting at 9, lunch w/ Sarah at 12pm, clean room, finish math hw" ), outputs=gr.Textbox(label="Today's Plan"), title="🗒️ Daily Notes → Structured Plan", description=( "Convert your free-form notes into a time-based schedule and a structured, numbered task list." ), theme="default" ) if __name__ == "__main__": iface.launch(server_name="0.0.0.0", server_port=7860)