Skip to content

Commit 6a40e6a

Browse files
committed
add choose month feature
format
1 parent 4f68eed commit 6a40e6a

File tree

3 files changed

+111
-64
lines changed

3 files changed

+111
-64
lines changed

src/js/popup.js

Lines changed: 61 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,72 @@
1-
function downloadICS(events) {
2-
let icsContent = `BEGIN:VCALENDAR
3-
VERSION:2.0
4-
CALSCALE:GREGORIAN
5-
PRODID:-//Moodle to Calendar//EN
6-
`;
1+
import { getCurrentYearMonth, downloadICS } from "./utils.js";
72

8-
for (const event of events) {
9-
const { title, description, startDate, endDate } = event;
10-
const format = (d) => d.toISOString().replace(/[-:]/g, "").split(".")[0] + "Z";
3+
function initializeInputs() {
4+
const { year, month } = getCurrentYearMonth();
5+
document.getElementById("yearInput").value = year;
6+
document.getElementById("monthInput").value = month;
7+
}
118

12-
icsContent += `BEGIN:VEVENT
13-
SUMMARY:${title}
14-
DESCRIPTION:${description || ""}
15-
DTSTART:${format(startDate)}
16-
DTEND:${format(endDate)}
17-
END:VEVENT
18-
`;
19-
}
9+
async function fetchCalendarData(sesskey) {
10+
const year = parseInt(document.getElementById("yearInput").value);
11+
const month = parseInt(document.getElementById("monthInput").value);
12+
// day is dont care
13+
const day = 1;
2014

21-
icsContent += "END:VCALENDAR";
15+
const response = await fetch(
16+
`https://ecourse2.ccu.edu.tw/lib/ajax/service.php?sesskey=${sesskey}&info=core_calendar_get_calendar_monthly_view`,
17+
{
18+
method: "POST",
19+
headers: { "Content-Type": "application/json" },
20+
body: JSON.stringify([
21+
{
22+
index: 0,
23+
methodname: "core_calendar_get_calendar_monthly_view",
24+
args: { year, month, day },
25+
},
26+
]),
27+
credentials: "include",
28+
}
29+
);
2230

23-
const blob = new Blob([icsContent], { type: "text/calendar" });
24-
const url = URL.createObjectURL(blob);
25-
const a = document.createElement("a");
26-
a.href = url;
27-
a.download = "moodle-homework.ics";
28-
a.click();
29-
URL.revokeObjectURL(url);
31+
const raw_data = await response.json();
32+
console.log(raw_data);
33+
return raw_data[0]["data"]["weeks"]
34+
.flatMap((week) => week.days)
35+
.flatMap((day) => day.events)
36+
.map((event) => ({
37+
description: event.course.fullname,
38+
title: event.activityname,
39+
startDate: new Date(event.timestart * 1000 - 3600 * 1000),
40+
endDate: new Date(event.timestart * 1000),
41+
}));
3042
}
3143

32-
document.getElementById("exportBtn").addEventListener("click", async () => {
33-
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
34-
chrome.tabs.sendMessage(tabs[0].id, { action: "get_sesskey" }, async (res) => {
35-
const sesskey = res?.sesskey;
36-
if (!sesskey) return console.log("no touch sesskey");
37-
38-
const today = new Date();
39-
const year = today.getFullYear();
40-
const month = today.getMonth() + 1;
41-
const day = today.getDate();
42-
43-
const response = await fetch(
44-
`https://ecourse2.ccu.edu.tw/lib/ajax/service.php?sesskey=${sesskey}&info=core_calendar_get_calendar_monthly_view`,
45-
{
46-
method: "POST",
47-
headers: { "Content-Type": "application/json" },
48-
body: JSON.stringify([
49-
{
50-
index: 0,
51-
methodname: "core_calendar_get_calendar_monthly_view",
52-
args: { year, month, day },
53-
},
54-
]),
55-
credentials: "include",
44+
function setupEventListeners() {
45+
document.getElementById("exportBtn").addEventListener("click", async () => {
46+
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
47+
chrome.tabs.sendMessage(tabs[0].id, { action: "get_sesskey" }, async (res) => {
48+
const sesskey = res?.sesskey;
49+
if (!sesskey) {
50+
console.log("no touch sesskey");
51+
document.getElementById("result").textContent = "無法獲取 sesskey,請先登入 Moodle";
52+
return;
5653
}
57-
);
5854

59-
const raw_data = await response.json();
60-
console.log(raw_data);
61-
const data = raw_data[0]["data"]["weeks"]
62-
.flatMap((week) => week.days)
63-
.flatMap((day) => day.events)
64-
.map((event) => ({
65-
description: event.course.fullname,
66-
title: event.activityname,
67-
startDate: new Date(event.timestart * 1000 - 3600 * 1000),
68-
endDate: new Date(event.timestart * 1000),
69-
}));
70-
71-
downloadICS(data);
55+
try {
56+
const events = await fetchCalendarData(sesskey);
57+
downloadICS(events);
58+
document.getElementById("result").textContent = `成功匯出 ${events.length} 個行事曆事件`;
59+
} catch (error) {
60+
console.error(error);
61+
document.getElementById("result").textContent = "發生錯誤,請稍後再試";
62+
}
63+
});
7264
});
7365
});
66+
}
67+
68+
// Initialize when DOM is fully loaded
69+
document.addEventListener("DOMContentLoaded", () => {
70+
initializeInputs();
71+
setupEventListeners();
7472
});

src/js/utils.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
export function getCurrentYearMonth() {
2+
const today = new Date();
3+
return {
4+
year: today.getFullYear(),
5+
month: today.getMonth() + 1,
6+
day: today.getDate(),
7+
};
8+
}
9+
10+
export function formatDateForICS(date) {
11+
return date.toISOString().replace(/[-:]/g, "").split(".")[0] + "Z";
12+
}
13+
14+
export function downloadICS(events) {
15+
let icsContent = `BEGIN:VCALENDAR
16+
VERSION:2.0
17+
CALSCALE:GREGORIAN
18+
PRODID:-//Moodle to Calendar//EN
19+
`;
20+
21+
for (const event of events) {
22+
const { title, description, startDate, endDate } = event;
23+
const format = formatDateForICS;
24+
25+
icsContent += `BEGIN:VEVENT
26+
SUMMARY:${title}
27+
DESCRIPTION:${description || ""}
28+
DTSTART:${format(startDate)}
29+
DTEND:${format(endDate)}
30+
END:VEVENT
31+
`;
32+
}
33+
34+
icsContent += "END:VCALENDAR";
35+
36+
const blob = new Blob([icsContent], { type: "text/calendar" });
37+
const url = URL.createObjectURL(blob);
38+
const a = document.createElement("a");
39+
a.href = url;
40+
a.download = "moodle-homework.ics";
41+
a.click();
42+
URL.revokeObjectURL(url);
43+
}

src/popup.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
</head>
88
<body class="p-4 w-52 flex items-center justify-center flex-col bg-white shadow-md rounded-lg">
99
<h1 class="text-xl font-bold">Moodle Calendar</h1>
10+
<div class="my-2">
11+
<input type="number" id="yearInput" class="w-16 p-1 border rounded" />
12+
<input type="number" id="monthInput" class="w-12 p-1 border rounded" />
13+
</div>
1014
<button
1115
id="exportBtn"
1216
class="bg-violet-400 text-white px-4 py-2 my-2 rounded cursor-pointer hover:bg-violet-700"
@@ -15,6 +19,8 @@ <h1 class="text-xl font-bold">Moodle Calendar</h1>
1519
</button>
1620
<pre id="result" class="text-sm whitespace-pre-wrap"></pre>
1721
<div>This tool help you to export your Moodle calendar events to a .ics file.</div>
18-
<script src="./js/popup.js"></script>
22+
23+
<!-- Use type="module" for ES module support -->
24+
<script type="module" src="./js/popup.js"></script>
1925
</body>
2026
</html>

0 commit comments

Comments
 (0)