An automated Chrome extension that extracts course deadlines, quizzes, and exams from Canvas LMS into iCal (.ics) and Google Calendar (.csv) β built because freshman-year time management was chaotic.
When I first arrived at college, time management was an uphill battle. With multiple computer science, engineering, and math classes, assignments and exam dates were scattered everywhere: tucked inside syllabi PDFs, nested within Canvas module trees, buried in weekly announcements, or hidden across assignment tabs. Keeping track of what was due and when felt overwhelming without a unified, consolidated calendar view.
The idea behind ToCalendar was simple:
What if an extension could navigate through your enrolled course tabs, heuristically parse out every deadline, quiz, and midterm, and give you a one-click export into Apple Calendar or Google Calendar?
While building the extensionβwrestling with dynamic SPA rendering, complex DOM trees, and professors' wildly inconsistent date formatsβI stumbled across an unexpected discovery: Canvas already had a built-in calendar view and a hidden Webcal/iCal subscription feed URL in the sidebar!
Finding that out was both hilarious and humbling. Between that realization and the edge cases inherent in client-side heuristic web scraping, I paused active development on the extension. However, building it was a great hands-on journey in browser extension architecture, asynchronous BFS crawling, DOM parsing heuristics, and calendar formatting standards.
- π In-Tab Autonomous Crawler: Recursively explores course links on the same host up to a configurable depth to discover deadline information across modules and syllabus pages.
- π§ Heuristic Date & Category Detection:
- Automatically identifies coursework categories (Homework, Quizzes, Midterms, Exams, Labs, Projects).
- Extracts course codes (e.g.,
CSE 2231,ENGR 1181). - Robust regex patterns support multiple date formats (ISO, US standard
MM/DD/YYYY, and month-day strings).
- β‘ Composite Hash Deduplication: Prevents duplicate calendar events when assignments are linked repeatedly across course overview tables and module lists.
- π Dual Calendar Export Engine:
- iCalendar (
.ics): RFC 5545 compliant export with local floating time events for Apple Calendar, Google Calendar, and Microsoft Outlook. - Google Calendar CSV (
.csv): Formatted with standard Google Calendar import columns (Subject,Start Date,Start Time,End Date,End Time,Description,Location) and directly readable in Excel and Google Sheets.
- iCalendar (
- π¨ Minimal Popup Dashboard: Real-time progress telemetry (pages visited, queue size, items extracted) with responsive light and dark theme support.
ToCalendar Extension Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Popup Layer (UI) Background Service Worker β
β βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β
β β popup.html / style.css ββββββββΆβ background.js (Service Worker) β β
β β β’ Crawl triggers β β β’ BFS Crawl Queue Manager β β
β β β’ Live status telemetry β β β’ Headless Tab Navigation β β
β β β’ .ics / .csv Exporters β β β’ Script Injection Controller β β
β βββββββββββββββββββββββββββ ββββββββββββββββ¬ββββββββββββββββββ β
β β β β
β βΌ βΌ β
β βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β
β β chrome.storage.local βββββββββ content.js (Injected Scraper) β β
β β β’ Cached deadline rows β β β’ Text Node Heuristic Filter β β
β β β’ Deduplicated items β β β’ Date & Category Regex Engine β β
β βββββββββββββββββββββββββββ β β’ Link Discovery (Same-Origin) β β
β ββββββββββββββββ¬ββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββ
β Canvas LMS DOM β
β (Courses / Syllabi / HW)β
βββββββββββββββββββββββββββ
User opens extension popup on Canvas course page
β
ββββΆ popup.js triggers START_CRAWL with current tab URL
β β
β βΌ
ββββΆ background.js initializes BFS queue (maxPages: 30, maxDepth: 3)
β β
β βββ Spawns background tab on course domain
β βββ Injects content.js via chrome.scripting.executeScript
β β
β βΌ
ββββΆ content.js scans DOM for deadline indicators & date patterns
β β
β βββ Filters nodes matching DUE_HINT and DATE_REGEXES
β βββ Guesses item title, course code, and category
β βββ Collects next-page course links (assignments, quizzes, modules)
β β
β βΌ
ββββΆ background.js receives SCRAPE_PAGE response
β β
β βββ Dispatches CRAWL_PROGRESS events to popup UI
β βββ Deduplicates items via signature hash
β βββ Persists aggregated rows to chrome.storage.local
β
βΌ
User exports calendar
βββ "Export iCal (.ics)" βββΆ Generates RFC 5545 VCALENDAR blob
βββ "Export CSV (.csv)" βββΆ Generates Google Calendar CSV blob
| Pattern Name | Regular Expression | Example Match |
|---|---|---|
| Month Name + Day | \b(Jan|Feb|Mar...)\s+\d{1,2}(?:,\s*\d{4})?... |
Sep 15, 2025 11:59 PM |
| ISO 8601 | \b\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}(?::\d{2})?)?\b |
2025-10-24 23:59:00 |
| US Standard | \b\d{1,2}\/\d{1,2}\/\d{2,4}(?:\s+\d{1,2}:\d{2}\s*(AM|PM)?)?\b |
11/04/2025 5:00 PM |
| Verbose Syllabus | \b(Mon|Tue...),\s*\d{1,2}\s+(Jan|Feb...)\s+\d{4}...\b |
Mon, 03 Nov 2025 14:00 |
| Detected Category | Matched Keywords in Context |
|---|---|
| Homework | hw, homework |
| Quiz | quiz |
| Exam | exam, test, midterm |
| Project | project, lab, report, paper |
| Assignment | assignment (or fallback) |
To ensure identical deadlines posted across multiple module views do not clutter the calendar, items are deduplicated using a unique signature key:
const key = `${item.title}__${parts.year}-${parts.month}-${parts.day}__${parts.hour}:${parts.minute}`;| Chrome API | Purpose in ToCalendar |
|---|---|
chrome.tabs |
Queries active tab, spawns off-screen tabs for background crawling, and handles page updates |
chrome.scripting |
Injects content.js dynamically into course pages as the crawler navigates |
chrome.storage.local |
Caches discovered deadlines and maintains state between popup open/close cycles |
chrome.runtime |
Coordinates inter-script message passing (START_CRAWL, CRAWL_PROGRESS, CRAWL_DONE, SCRAPE_PAGE) |
| Layer | Technology | Purpose |
|---|---|---|
| Extension Platform | Chrome Manifest V3 | Extension framework, permissions, and service worker lifecycle |
| Language | Vanilla JavaScript (ES6+) | Dependency-free execution, zero build step required |
| User Interface | HTML5 / CSS3 | Clean popup interface with automatic dark/light mode |
| Calendar Standard | RFC 5545 (.ics) |
Standard iCalendar format for Apple Calendar, Outlook, and Google Calendar |
| Spreadsheet Standard | RFC 4180 (.csv) |
Standard Google Calendar import format and Excel/Sheets data |
ToCalendar/
βββ manifest.json # Manifest V3 extension configuration & permissions
βββ background.js # Service worker managing BFS crawl queue & tab navigation
βββ content.js # Injected scraper for DOM text nodes, heuristics, and links
βββ popup.html # Extension popup interface
βββ popup.js # Popup state manager, crawler listener, and export builders
βββ style.css # Popup styling with responsive dark mode support
βββ icons/ # Extension branding icons
β βββ Screenshot ...png # Extension icon asset
βββ .gitignore # Excludes macOS metadata, logs, and backup archives
βββ LICENSE # MIT License
βββ README.md # Project documentation & architecture overview
-
Clone the repository:
git clone https://github.com/KadyrovAkram/ToCalendar.git cd ToCalendar -
Open Chrome Extensions:
- Navigate to
chrome://extensionsin Google Chrome. - Toggle Developer mode on (top-right corner).
- Navigate to
-
Load the Extension:
- Click Load unpacked (top-left corner).
- Select the cloned
ToCalendarfolder.
-
Extract Deadlines:
- Navigate to your Canvas LMS portal (e.g., your course home page).
- Click the ToCalendar icon in your browser toolbar.
- The crawler will automatically begin scanning course tabs.
- Click Export iCal (.ics) or Export CSV (.csv) to download your deadlines.
- SPA Asynchronous Hydration: Single-page applications like Canvas dynamically mount components via client-side JavaScript. Scraping immediately upon page load often resulted in blank or partial reads, necessitating deliberate rendering delay pauses.
- Heuristic Specificity vs. Recall: Natural language dates in freeform syllabus pages lack consistent markup. Loose regex matching captured irrelevant dates (such as lecture release dates), while strict regex missed assignments formatted with non-standard abbreviations.
- Local Floating Time vs. UTC: Academic deadlines are tied to the local timezone of the institution. Exporting
.icstimestamps as "floating local time" (without hardcoded UTC offsets) ensured deadlines did not shift incorrectly across daylight saving time boundaries. - Native Feeds vs. Screen Scraping: This project served as a prime lesson in API designβwhile scraping was a great exercise, native calendar feeds (
webcal://) provide vastly superior reliability and real-time synchronization.
This project is licensed under the MIT License - see the LICENSE file for details.
Built with β by Ekremzhan Kadyrov