forked from cloud-atlas-ai/obsidian-ics
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.ts
160 lines (133 loc) · 4.82 KB
/
main.ts
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
import {
Editor, moment,
MarkdownView, Notice
} from 'obsidian';
import {
Calendar,
ICSSettings,
DEFAULT_SETTINGS,
} from "./settings/ICSSettings";
import ICSSettingsTab from "./settings/ICSSettingsTab";
import {
getDateFromFile
} from "obsidian-daily-notes-interface";
import {
Plugin,
request
} from 'obsidian';
import { parseIcs, filterMatchingEvents, extractMeetingInfo } from './icalUtils';
import { IEvent } from './IEvent';
export default class ICSPlugin extends Plugin {
data: ICSSettings;
async addCalendar(calendar: Calendar): Promise<void> {
this.data.calendars = {
...this.data.calendars,
[calendar.icsName]: calendar
};
await this.saveSettings();
}
async removeCalendar(calendar: Calendar) {
if (this.data.calendars[calendar.icsName]) {
delete this.data.calendars[calendar.icsName];
}
await this.saveSettings();
}
formatEvent(e: IEvent): string {
const callLinkOrLocation = e.callType ? `[${e.callType}](${e.callUrl})` : e.location;
// Conditionally format start and end time based on dataViewSyntax setting
const startTimeFormatted = this.data.format.dataViewSyntax ? `[startTime:: ${e.time}]` : `${e.time}`;
const endTimeFormatted = e.format.includeEventEndTime ? (this.data.format.dataViewSyntax ? `[endTime:: ${e.endTime}]` : `- ${e.endTime}`) : '';
// Combine all parts of the formatted event string
return [
`- ${e.format.checkbox ? '[ ]' : ''}`,
startTimeFormatted,
endTimeFormatted,
e.format.icsName ? e.icsName : '',
e.format.summary ? e.summary : '',
e.format.location ? callLinkOrLocation : '',
e.format.description && e.description ? `\n\t- ${e.description}` : '',
].filter(Boolean).join(' ').trim();
}
async getEvents(date: string) : Promise<IEvent[]> {
let events: IEvent[] = [];
let errorMessages: string[] = []; // To store error messages
for (const calendar in this.data.calendars) {
const calendarSetting = this.data.calendars[calendar];
let icsArray: any[] = [];
try {
if (calendarSetting.calendarType === 'vdir') {
// Assuming you have a method to list files in a directory
const icsFiles = app.vault.getFiles().filter(f => f.extension == "ics" && f.path.startsWith(calendarSetting.icsUrl));
for (const icsFile of icsFiles) {
const fileContent = await this.app.vault.read(icsFile);
icsArray = icsArray.concat(parseIcs(fileContent));
}
} else {
// Existing logic for remote URLs
icsArray = parseIcs(await request({ url: calendarSetting.icsUrl }));
}
} catch (error) {
console.error(`Error processing calendar ${calendarSetting.icsName}: ${error}`);
errorMessages.push(`Error processing calendar "${calendarSetting.icsName}"`);
}
var dateEvents;
// Exception handling for parsing and filtering
try {
dateEvents = filterMatchingEvents(icsArray, date);
} catch (filterError) {
console.error(`Error filtering events for calendar ${calendarSetting.icsName}: ${filterError}`);
errorMessages.push(`Error filtering events in calendar "${calendarSetting.icsName}"`);
}
try {
dateEvents.forEach((e) => {
const { callUrl, callType } = extractMeetingInfo(e);
let event: IEvent = {
utime: moment(e.start).format('X'),
time: moment(e.start).format(this.data.format.timeFormat),
endTime: moment(e.end).format(this.data.format.timeFormat),
icsName: calendarSetting.icsName,
summary: e.summary,
description: e.description,
format: calendarSetting.format,
location: e.location? e.location : null,
callUrl: callUrl,
callType: callType
};
events.push(event);
});
} catch (parseError) {
console.error(`Error parsing events for calendar ${calendarSetting.icsName}: ${parseError}`);
errorMessages.push(`Error parsing events in calendar "${calendarSetting.icsName}"`);
}
}
// Notify the user if any errors were encountered
if (errorMessages.length > 0) {
const message = `Encountered ${errorMessages.length} error(s) while processing calendars:\n\n${errorMessages.join('\n')}\nSee console for details.`;
new Notice(message);
}
return events;
}
async onload() {
await this.loadSettings();
this.addSettingTab(new ICSSettingsTab(this.app, this));
this.addCommand({
id: "import_events",
name: "import events",
editorCallback: async (editor: Editor, view: MarkdownView) => {
const fileDate = getDateFromFile(view.file, "day").format("YYYY-MM-DD");
var events: any[] = await this.getEvents(fileDate);
const mdArray = events.sort((a,b) => a.utime - b.utime).map(this.formatEvent, this);
editor.replaceRange(mdArray.join("\n"), editor.getCursor());
}
});
}
onunload() {
return;
}
async loadSettings() {
this.data = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.data);
}
}