Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -11,6 +11,27 @@ CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
|
|
11 |
AUTHORITY_URL = 'https://login.microsoftonline.com/common'
|
12 |
REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
def sticky_menu():
|
15 |
st.markdown(
|
16 |
"""
|
@@ -47,195 +68,7 @@ def sticky_menu():
|
|
47 |
""",
|
48 |
unsafe_allow_html=True
|
49 |
)
|
50 |
-
|
51 |
-
def dashboard(access_token):
|
52 |
-
st.subheader("1️⃣ Dashboard")
|
53 |
-
|
54 |
-
# Timeframe selector
|
55 |
-
timeframe = st.selectbox("Select Timeframe", ["Day", "Week", "Month"])
|
56 |
-
|
57 |
-
now = datetime.now()
|
58 |
-
|
59 |
-
if timeframe == "Day":
|
60 |
-
start_time = now.replace(hour=0, minute=0, second=0)
|
61 |
-
end_time = now.replace(hour=23, minute=59, second=59)
|
62 |
-
elif timeframe == "Week":
|
63 |
-
start_time = now - timedelta(days=now.weekday()) # Start of the week (Monday)
|
64 |
-
end_time = start_time + timedelta(days=6)
|
65 |
-
elif timeframe == "Month":
|
66 |
-
start_time = now.replace(day=1, hour=0, minute=0, second=0)
|
67 |
-
next_month = (now.month % 12) + 1
|
68 |
-
end_time = start_time.replace(month=next_month, day=1) - timedelta(days=1)
|
69 |
-
|
70 |
-
# Fetch and display calendar events for the selected timeframe
|
71 |
-
events = make_api_call(access_token, f"me/calendarView?startDateTime={start_time.isoformat()}&endDateTime={end_time.isoformat()}&$orderby=start/dateTime")
|
72 |
-
|
73 |
-
if events and 'value' in events:
|
74 |
-
st.write(f"📅 Events from {start_time.date()} to {end_time.date()}")
|
75 |
-
for event in events['value']:
|
76 |
-
start_date = datetime.fromisoformat(event['start']['dateTime'][:-1])
|
77 |
-
st.write(f"**{event['subject']}** | {start_date.strftime('%Y-%m-%d %H:%M')}")
|
78 |
-
st.write("---")
|
79 |
-
else:
|
80 |
-
st.write("No events found or unable to fetch events.")
|
81 |
-
|
82 |
-
def landing_page():
|
83 |
-
st.subheader("🏠 Landing Page")
|
84 |
-
st.write("Welcome to the app! Use the menu above to navigate.")
|
85 |
-
|
86 |
-
def upcoming_events(access_token):
|
87 |
-
st.subheader("📅 Upcoming Events")
|
88 |
-
|
89 |
-
# Show upcoming events from the current date
|
90 |
-
now = datetime.now()
|
91 |
-
events = make_api_call(access_token, f"me/calendar/events?$top=10&$orderby=start/dateTime&$filter=start/dateTime ge {now.isoformat()}")
|
92 |
-
|
93 |
-
if events and 'value' in events:
|
94 |
-
st.write("Upcoming Events:")
|
95 |
-
for event in events['value']:
|
96 |
-
start_date = datetime.fromisoformat(event['start']['dateTime'][:-1])
|
97 |
-
st.write(f"**{event['subject']}** | {start_date.strftime('%Y-%m-%d %H:%M')}")
|
98 |
-
st.write("---")
|
99 |
-
else:
|
100 |
-
st.write("No upcoming events.")
|
101 |
-
|
102 |
-
def schedule(access_token):
|
103 |
-
st.subheader("📆 Schedule")
|
104 |
-
|
105 |
-
# Display a weekly or daily schedule from the current date
|
106 |
-
now = datetime.now()
|
107 |
-
week_start = now - timedelta(days=now.weekday()) # Start of the week (Monday)
|
108 |
-
week_end = week_start + timedelta(days=6)
|
109 |
-
|
110 |
-
st.write(f"Schedule for the week {week_start.strftime('%Y-%m-%d')} to {week_end.strftime('%Y-%m-%d')}")
|
111 |
-
|
112 |
-
events = make_api_call(access_token, f"me/calendarView?startDateTime={week_start.isoformat()}&endDateTime={week_end.isoformat()}&$orderby=start/dateTime")
|
113 |
-
|
114 |
-
if events and 'value' in events:
|
115 |
-
for event in events['value']:
|
116 |
-
start_date = datetime.fromisoformat(event['start']['dateTime'][:-1])
|
117 |
-
st.write(f"**{event['subject']}** | {start_date.strftime('%Y-%m-%d %H:%M')}")
|
118 |
-
st.write("---")
|
119 |
-
else:
|
120 |
-
st.write("No events found.")
|
121 |
-
|
122 |
-
def agenda(access_token):
|
123 |
-
st.subheader("📝 Agenda")
|
124 |
-
|
125 |
-
# Display a list of tasks or meetings
|
126 |
-
tasks = make_api_call(access_token, 'me/todo/lists')
|
127 |
-
if tasks and 'value' in tasks:
|
128 |
-
st.write("Agenda Items:")
|
129 |
-
for task in tasks['value']:
|
130 |
-
st.write(f"Task: {task['title']}")
|
131 |
-
st.write("---")
|
132 |
-
else:
|
133 |
-
st.write("No tasks or agenda items.")
|
134 |
-
|
135 |
-
def event_details(access_token):
|
136 |
-
st.subheader("🔍 Event Details")
|
137 |
-
|
138 |
-
# Fetch and display details for a specific event
|
139 |
-
event_id = st.text_input("Enter Event ID")
|
140 |
-
|
141 |
-
if event_id:
|
142 |
-
event = make_api_call(access_token, f'me/events/{event_id}')
|
143 |
-
if event:
|
144 |
-
st.write(f"Event: {event['subject']}")
|
145 |
-
st.write(f"Start: {event['start']['dateTime']}")
|
146 |
-
st.write(f"End: {event['end']['dateTime']}")
|
147 |
-
st.write(f"Description: {event.get('bodyPreview', 'No description')}")
|
148 |
-
else:
|
149 |
-
st.write("Unable to fetch event details.")
|
150 |
-
|
151 |
-
def add_event(access_token):
|
152 |
-
st.subheader("➕ Add Event")
|
153 |
-
|
154 |
-
# Create event
|
155 |
-
event_subject = st.text_input("Event Subject")
|
156 |
-
event_date = st.date_input("Event Date")
|
157 |
-
event_time = st.time_input("Event Time")
|
158 |
-
|
159 |
-
if st.button("Add Event"):
|
160 |
-
event_start = datetime.combine(event_date, event_time)
|
161 |
-
event_end = event_start + timedelta(hours=1)
|
162 |
-
|
163 |
-
new_event = {
|
164 |
-
"subject": event_subject,
|
165 |
-
"start": {
|
166 |
-
"dateTime": event_start.isoformat(),
|
167 |
-
"timeZone": "UTC"
|
168 |
-
},
|
169 |
-
"end": {
|
170 |
-
"dateTime": event_end.isoformat(),
|
171 |
-
"timeZone": "UTC"
|
172 |
-
}
|
173 |
-
}
|
174 |
-
|
175 |
-
result = make_api_call(access_token, 'me/events', method='POST', data=new_event)
|
176 |
-
if result:
|
177 |
-
st.success("Event added successfully!")
|
178 |
-
else:
|
179 |
-
st.error("Failed to add event.")
|
180 |
-
|
181 |
-
def filter_by(access_token):
|
182 |
-
st.subheader("🔎 Filter By")
|
183 |
-
|
184 |
-
# Filter calendar events by title, date range, or organizer
|
185 |
-
filter_by_title = st.text_input("Event Title Contains")
|
186 |
-
filter_by_start_date = st.date_input("Start Date After", datetime.now() - timedelta(days=30))
|
187 |
-
filter_by_end_date = st.date_input("End Date Before", datetime.now() + timedelta(days=30))
|
188 |
-
|
189 |
-
filters = []
|
190 |
-
if filter_by_title:
|
191 |
-
filters.append(f"contains(subject, '{filter_by_title}')")
|
192 |
-
if filter_by_start_date:
|
193 |
-
filters.append(f"start/dateTime ge {filter_by_start_date.isoformat()}T00:00:00Z")
|
194 |
-
if filter_by_end_date:
|
195 |
-
filters.append(f"end/dateTime le {filter_by_end_date.isoformat()}T23:59:59Z")
|
196 |
-
|
197 |
-
filter_query = " and ".join(filters) if filters else ''
|
198 |
-
events_endpoint = f"me/calendarView?startDateTime={filter_by_start_date.isoformat()}&endDateTime={filter_by_end_date.isoformat()}&$orderby=start/dateTime"
|
199 |
-
|
200 |
-
if filter_query:
|
201 |
-
events_endpoint += f"&$filter={filter_query}"
|
202 |
-
|
203 |
-
events = make_api_call(access_token, events_endpoint)
|
204 |
|
205 |
-
if events and 'value' in events:
|
206 |
-
for event in events['value']:
|
207 |
-
start_date = datetime.fromisoformat(event['start']['dateTime'][:-1])
|
208 |
-
st.write(f"**{event['subject']}** | {start_date.strftime('%Y-%m-%d %H:%M')}")
|
209 |
-
st.write("---")
|
210 |
-
else:
|
211 |
-
st.write("No events found.")
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
ProductNaming='''
|
217 |
-
🌌🔗 Git Cosmos Glow: Graph & Mobile Flow 📱💫
|
218 |
-
🚀📊 Cosmic Git Wit: Graph Power, Mobile Hit 📲✨
|
219 |
-
🌠🔧 Git Galaxy Gear: Graph Magic, Mobile Clear 📱🎩
|
220 |
-
🌌🔍 Cosmos Code Quest: Graph Zest, Mobile Best 📲🏆
|
221 |
-
🚀💾 Git Star Suite: Graph Might, Mobile Delight 📱✨
|
222 |
-
🌠🔗 Cosmic Link Sync: Graph Blink, Mobile Think 📲💡
|
223 |
-
🌌🛠️ Git Nebula Tools: Graph Rules, Mobile Cools 📱❄️
|
224 |
-
🚀🔮 Cosmos Code Charm: Graph Farm, Mobile Arm 📲💪
|
225 |
-
🌠🔍 Git Galaxy Sight: Graph Bright, Mobile Light 📱💡
|
226 |
-
🌌🚀 Cosmic Git Flight: Graph Insight, Mobile Might 📲💥
|
227 |
-
|
228 |
-
"1️⃣ Dashboard",
|
229 |
-
"🏠 Landing Page",
|
230 |
-
"📅 Upcoming Events",
|
231 |
-
"📆 Schedule",
|
232 |
-
"📝 Agenda",
|
233 |
-
"🔍 Event Details",
|
234 |
-
"➕ Add Event",
|
235 |
-
"🔎 Filter By"
|
236 |
-
|
237 |
-
'''
|
238 |
-
|
239 |
# Define product to scope mapping, links, AI capabilities, and Graph solutions
|
240 |
PRODUCT_SCOPES = {
|
241 |
"📧 Outlook": {
|
@@ -390,48 +223,10 @@ def make_api_call(access_token, endpoint, method='GET', data=None):
|
|
390 |
st.error(f"API call failed: {response.status_code} - {response.text}")
|
391 |
return None
|
392 |
|
393 |
-
|
394 |
def handle_outlook_integration(access_token):
|
395 |
st.subheader("📧 Outlook Integration")
|
396 |
st.markdown(f"[Open Outlook]({PRODUCT_SCOPES['📧 Outlook']['link']})")
|
397 |
|
398 |
-
# Filters for emails
|
399 |
-
st.write("### Filter Emails:")
|
400 |
-
filter_by_sender = st.text_input("Sender Email")
|
401 |
-
filter_by_subject = st.text_input("Subject Contains")
|
402 |
-
filter_by_date = st.date_input("Emails received after", datetime.now() - timedelta(days=30))
|
403 |
-
|
404 |
-
# Create query filters
|
405 |
-
filters = []
|
406 |
-
if filter_by_sender:
|
407 |
-
filters.append(f"from/emailAddress/address eq '{filter_by_sender}'")
|
408 |
-
if filter_by_subject:
|
409 |
-
filters.append(f"contains(subject, '{filter_by_subject}')")
|
410 |
-
if filter_by_date:
|
411 |
-
filters.append(f"receivedDateTime ge {filter_by_date.isoformat()}T00:00:00Z")
|
412 |
-
|
413 |
-
filter_query = " and ".join(filters) if filters else ''
|
414 |
-
|
415 |
-
# Fetch emails with applied filters
|
416 |
-
emails_endpoint = 'me/messages?$top=10'
|
417 |
-
if filter_query:
|
418 |
-
emails_endpoint += f"&$filter={filter_query}&$orderby=receivedDateTime desc"
|
419 |
-
|
420 |
-
emails = make_api_call(access_token, emails_endpoint)
|
421 |
-
if emails and 'value' in emails:
|
422 |
-
for email in emails['value']:
|
423 |
-
with st.expander(f"From: {email['from']['emailAddress']['name']} - Subject: {email['subject']}"):
|
424 |
-
st.write(f"Received: {email['receivedDateTime']}")
|
425 |
-
st.write(f"Body: {email['bodyPreview']}")
|
426 |
-
else:
|
427 |
-
st.write("No emails found or unable to fetch emails.")
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
def handle_outlook_integration_old(access_token):
|
432 |
-
st.subheader("📧 Outlook Integration")
|
433 |
-
st.markdown(f"[Open Outlook]({PRODUCT_SCOPES['📧 Outlook']['link']})")
|
434 |
-
|
435 |
# Read emails
|
436 |
emails = make_api_call(access_token, 'me/messages?$top=10&$orderby=receivedDateTime desc')
|
437 |
if emails and 'value' in emails:
|
@@ -493,46 +288,8 @@ def handle_outlook_integration_old(access_token):
|
|
493 |
else:
|
494 |
st.error("Failed to delete email.")
|
495 |
|
496 |
-
def handle_calendar_integration(access_token):
|
497 |
-
st.subheader("📅 Calendar Integration")
|
498 |
-
st.markdown(f"[Open Calendar]({PRODUCT_SCOPES['📅 Calendar']['link']})")
|
499 |
-
|
500 |
-
# Filters for calendar events
|
501 |
-
st.write("### Filter Calendar Events:")
|
502 |
-
filter_by_title = st.text_input("Event Title Contains")
|
503 |
-
filter_by_start_date = st.date_input("Start Date After", datetime.now() - timedelta(days=30))
|
504 |
-
filter_by_end_date = st.date_input("End Date Before", datetime.now() + timedelta(days=30))
|
505 |
-
|
506 |
-
# Create query filters
|
507 |
-
filters = []
|
508 |
-
if filter_by_title:
|
509 |
-
filters.append(f"contains(subject, '{filter_by_title}')")
|
510 |
-
if filter_by_start_date:
|
511 |
-
filters.append(f"start/dateTime ge {filter_by_start_date.isoformat()}T00:00:00Z")
|
512 |
-
if filter_by_end_date:
|
513 |
-
filters.append(f"end/dateTime le {filter_by_end_date.isoformat()}T23:59:59Z")
|
514 |
-
|
515 |
-
filter_query = " and ".join(filters) if filters else ''
|
516 |
-
|
517 |
-
# Fetch events with applied filters
|
518 |
-
events_endpoint = f"me/calendarView?startDateTime={filter_by_start_date.isoformat()}T00:00:00&endDateTime={filter_by_end_date.isoformat()}T23:59:59"
|
519 |
-
if filter_query:
|
520 |
-
events_endpoint += f"&$filter={filter_query}&$orderby=start/dateTime"
|
521 |
-
|
522 |
-
events = make_api_call(access_token, events_endpoint)
|
523 |
-
|
524 |
-
if events and 'value' in events:
|
525 |
-
st.write("### Upcoming Events")
|
526 |
-
for event in events['value']:
|
527 |
-
start_date = datetime.fromisoformat(event['start']['dateTime'][:-1]) # Remove 'Z' from the end
|
528 |
-
st.write(f"**{event['subject']}** | {start_date.strftime('%Y-%m-%d %H:%M')}")
|
529 |
-
st.write("---")
|
530 |
-
else:
|
531 |
-
st.write("No events found or unable to fetch events.")
|
532 |
-
|
533 |
-
|
534 |
|
535 |
-
def
|
536 |
st.subheader("📅 Calendar Integration")
|
537 |
st.markdown(f"[Open Calendar]({PRODUCT_SCOPES['📅 Calendar']['link']})")
|
538 |
|
@@ -731,13 +488,15 @@ def handle_onedrive_integration(access_token):
|
|
731 |
else:
|
732 |
st.error("Failed to delete file.")
|
733 |
|
|
|
|
|
|
|
734 |
def main():
|
735 |
st.title("🦄 MS Graph API with AI & Cloud Integration for M365")
|
736 |
|
737 |
# Sticky Menu
|
738 |
sticky_menu()
|
739 |
-
|
740 |
-
# Sidebar Menu for Product Selection
|
741 |
st.sidebar.title("📝 M365 Products")
|
742 |
st.sidebar.write("Select products to integrate:")
|
743 |
|
@@ -749,17 +508,6 @@ def main():
|
|
749 |
st.sidebar.write(f"AI Capabilities: {details['ai_capabilities']}")
|
750 |
st.sidebar.write(f"Graph Solution: {details['graph_solution']}")
|
751 |
|
752 |
-
# Handle query parameters via session_state
|
753 |
-
if 'section' not in st.session_state:
|
754 |
-
st.session_state['section'] = 'dashboard' # Default section is the dashboard
|
755 |
-
|
756 |
-
selected_section = st.session_state['section']
|
757 |
-
|
758 |
-
# Example of re-running based on interaction (you can change sections)
|
759 |
-
if st.button("Go to Landing Page"):
|
760 |
-
st.session_state['section'] = 'landing-page'
|
761 |
-
|
762 |
-
# Request scopes and authentication management
|
763 |
request_scopes = BASE_SCOPES.copy()
|
764 |
for product in selected_products:
|
765 |
request_scopes.extend(PRODUCT_SCOPES[product]['scopes'])
|
@@ -775,7 +523,7 @@ def main():
|
|
775 |
)
|
776 |
st.write('👋 Please [click here]({}) to log in and authorize the app.'.format(auth_url))
|
777 |
|
778 |
-
query_params = st.
|
779 |
if 'code' in query_params:
|
780 |
code = query_params.get('code')
|
781 |
st.write('🔑 Authorization Code Obtained:', code[:10] + '...')
|
@@ -784,8 +532,7 @@ def main():
|
|
784 |
access_token = get_access_token(code)
|
785 |
st.session_state['access_token'] = access_token
|
786 |
st.success("Access token acquired successfully!")
|
787 |
-
|
788 |
-
st.session_state['section'] = 'dashboard'
|
789 |
except Exception as e:
|
790 |
st.error(f"Error acquiring access token: {str(e)}")
|
791 |
st.stop()
|
@@ -796,6 +543,22 @@ def main():
|
|
796 |
if user_info:
|
797 |
st.sidebar.write(f"👋 Hello, {user_info.get('displayName', 'User')}!")
|
798 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
799 |
# Handle navigation based on the selected section
|
800 |
if selected_section == 'dashboard':
|
801 |
dashboard(access_token)
|
@@ -814,6 +577,7 @@ def main():
|
|
814 |
elif selected_section == 'filter-by':
|
815 |
filter_by(access_token)
|
816 |
|
|
|
817 |
|
818 |
if __name__ == "__main__":
|
819 |
main()
|
|
|
11 |
AUTHORITY_URL = 'https://login.microsoftonline.com/common'
|
12 |
REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
|
13 |
|
14 |
+
# 1. Configuration
|
15 |
+
Site_Name = '🏠Event 📅Schedule and 📝Agenda 🔍Dashboard'
|
16 |
+
title="🏠Event 📅Schedule and 📝Agenda 🔍Dashboard"
|
17 |
+
helpURL='https://huggingface.co/awacke1'
|
18 |
+
bugURL='https://huggingface.co/spaces/awacke1'
|
19 |
+
icons='📅'
|
20 |
+
#icons = Image.open("icons.ico")
|
21 |
+
st.set_page_config(
|
22 |
+
page_title=title,
|
23 |
+
page_icon=icons,
|
24 |
+
layout="wide",
|
25 |
+
#initial_sidebar_state="expanded",
|
26 |
+
initial_sidebar_state="auto",
|
27 |
+
menu_items={
|
28 |
+
'Get Help': helpURL,
|
29 |
+
'Report a bug': bugURL,
|
30 |
+
'About': title
|
31 |
+
}
|
32 |
+
)
|
33 |
+
|
34 |
+
# Sticky navigation menu
|
35 |
def sticky_menu():
|
36 |
st.markdown(
|
37 |
"""
|
|
|
68 |
""",
|
69 |
unsafe_allow_html=True
|
70 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
# Define product to scope mapping, links, AI capabilities, and Graph solutions
|
73 |
PRODUCT_SCOPES = {
|
74 |
"📧 Outlook": {
|
|
|
223 |
st.error(f"API call failed: {response.status_code} - {response.text}")
|
224 |
return None
|
225 |
|
|
|
226 |
def handle_outlook_integration(access_token):
|
227 |
st.subheader("📧 Outlook Integration")
|
228 |
st.markdown(f"[Open Outlook]({PRODUCT_SCOPES['📧 Outlook']['link']})")
|
229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
# Read emails
|
231 |
emails = make_api_call(access_token, 'me/messages?$top=10&$orderby=receivedDateTime desc')
|
232 |
if emails and 'value' in emails:
|
|
|
288 |
else:
|
289 |
st.error("Failed to delete email.")
|
290 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
|
292 |
+
def handle_calendar_integration(access_token):
|
293 |
st.subheader("📅 Calendar Integration")
|
294 |
st.markdown(f"[Open Calendar]({PRODUCT_SCOPES['📅 Calendar']['link']})")
|
295 |
|
|
|
488 |
else:
|
489 |
st.error("Failed to delete file.")
|
490 |
|
491 |
+
|
492 |
+
|
493 |
+
|
494 |
def main():
|
495 |
st.title("🦄 MS Graph API with AI & Cloud Integration for M365")
|
496 |
|
497 |
# Sticky Menu
|
498 |
sticky_menu()
|
499 |
+
|
|
|
500 |
st.sidebar.title("📝 M365 Products")
|
501 |
st.sidebar.write("Select products to integrate:")
|
502 |
|
|
|
508 |
st.sidebar.write(f"AI Capabilities: {details['ai_capabilities']}")
|
509 |
st.sidebar.write(f"Graph Solution: {details['graph_solution']}")
|
510 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
511 |
request_scopes = BASE_SCOPES.copy()
|
512 |
for product in selected_products:
|
513 |
request_scopes.extend(PRODUCT_SCOPES[product]['scopes'])
|
|
|
523 |
)
|
524 |
st.write('👋 Please [click here]({}) to log in and authorize the app.'.format(auth_url))
|
525 |
|
526 |
+
query_params = st.query_params
|
527 |
if 'code' in query_params:
|
528 |
code = query_params.get('code')
|
529 |
st.write('🔑 Authorization Code Obtained:', code[:10] + '...')
|
|
|
532 |
access_token = get_access_token(code)
|
533 |
st.session_state['access_token'] = access_token
|
534 |
st.success("Access token acquired successfully!")
|
535 |
+
st.rerun()
|
|
|
536 |
except Exception as e:
|
537 |
st.error(f"Error acquiring access token: {str(e)}")
|
538 |
st.stop()
|
|
|
543 |
if user_info:
|
544 |
st.sidebar.write(f"👋 Hello, {user_info.get('displayName', 'User')}!")
|
545 |
|
546 |
+
if selected_products:
|
547 |
+
for product in selected_products:
|
548 |
+
if product == "📧 Outlook":
|
549 |
+
handle_outlook_integration(access_token)
|
550 |
+
elif product == "📅 Calendar":
|
551 |
+
handle_calendar_integration(access_token)
|
552 |
+
elif product == "📋 Tasks":
|
553 |
+
handle_tasks_integration(access_token)
|
554 |
+
elif product == "🗂️ OneDrive":
|
555 |
+
handle_onedrive_integration(access_token)
|
556 |
+
# Add more product integrations here
|
557 |
+
else:
|
558 |
+
st.write("No products selected. Please select products from the sidebar.")
|
559 |
+
|
560 |
+
|
561 |
+
|
562 |
# Handle navigation based on the selected section
|
563 |
if selected_section == 'dashboard':
|
564 |
dashboard(access_token)
|
|
|
577 |
elif selected_section == 'filter-by':
|
578 |
filter_by(access_token)
|
579 |
|
580 |
+
|
581 |
|
582 |
if __name__ == "__main__":
|
583 |
main()
|