Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mxrch
GitHub Repository: mxrch/GHunt
Path: blob/master/ghunt/helpers/calendar.py
252 views
1
from xmlrpc.client import Boolean
2
from dateutil.relativedelta import relativedelta
3
from beautifultable import BeautifulTable
4
import httpx
5
6
from typing import *
7
from copy import deepcopy
8
9
from ghunt.parsers.calendar import Calendar, CalendarEvents
10
from ghunt.objects.base import GHuntCreds
11
from ghunt.objects.utils import TMPrinter
12
from ghunt.apis.calendar import CalendarHttp
13
14
15
async def fetch_all(ghunt_creds: GHuntCreds, as_client: httpx.AsyncClient, email_address: str) -> Tuple[Boolean, Calendar, CalendarEvents]:
16
calendar_api = CalendarHttp(ghunt_creds)
17
found, calendar = await calendar_api.get_calendar(as_client, email_address)
18
if not found:
19
return False, None, None
20
tmprinter = TMPrinter()
21
_, events = await calendar_api.get_events(as_client, email_address, params_template="max_from_beginning")
22
next_page_token = deepcopy(events.next_page_token)
23
while next_page_token:
24
tmprinter.out(f"[~] Dumped {len(events.items)} events...")
25
_, new_events = await calendar_api.get_events(as_client, email_address, params_template="max_from_beginning", page_token=next_page_token)
26
events.items += new_events.items
27
next_page_token = deepcopy(new_events.next_page_token)
28
tmprinter.clear()
29
return True, calendar, events
30
31
def out(calendar: Calendar, events: CalendarEvents, email_address: str, display_name="", limit=5):
32
"""
33
Output fetched calendar events.
34
if limit = 0, = all events are shown
35
"""
36
37
### Calendar
38
39
print(f"Calendar ID : {calendar.id}")
40
if calendar.summary != calendar.id:
41
print(f"[+] Calendar Summary : {calendar.summary}")
42
print(f"Calendar Timezone : {calendar.time_zone}\n")
43
44
### Events
45
target_events = events.items[-limit:]
46
if target_events:
47
print(f"[+] {len(events.items)} event{'s' if len(events.items) > 1 else ''} dumped ! Showing the last {len(target_events)} one{'s' if len(target_events) > 1 else ''}...\n")
48
49
table = BeautifulTable()
50
table.set_style(BeautifulTable.STYLE_GRID)
51
table.columns.header = ["Name", "Datetime (UTC)", "Duration"]
52
53
for event in target_events:
54
title = "/"
55
if event.summary:
56
title = event.summary
57
duration = "?"
58
if event.end.date_time and event.start.date_time:
59
duration = relativedelta(event.end.date_time, event.start.date_time)
60
if duration.days or duration.hours or duration.minutes:
61
duration = (f"{(str(duration.days) + ' day' + ('s' if duration.days > 1 else '')) if duration.days else ''} "
62
f"{(str(duration.hours) + ' hour' + ('s' if duration.hours > 1 else '')) if duration.hours else ''} "
63
f"{(str(duration.minutes) + ' minute' + ('s' if duration.minutes > 1 else '')) if duration.minutes else ''}").strip()
64
65
date = "?"
66
if event.start.date_time:
67
date = event.start.date_time.strftime("%Y/%m/%d %H:%M:%S")
68
table.rows.append([title, date, duration])
69
70
print(table)
71
72
print(f"\n🗃️ Download link :\n=> https://calendar.google.com/calendar/ical/{email_address}/public/basic.ics")
73
else:
74
print("[-] No events dumped.")
75
76
### Names
77
78
names = set()
79
for event in events.items:
80
if event.creator.email == email_address and (name := event.creator.display_name) and name != display_name:
81
names.add(name)
82
if names:
83
print("\n[+] Found other names used by the target :")
84
for name in names:
85
print(f"- {name}")
86