Salim Taous logoPrayer Time Calendar Scheduler
All projects
Native macOS desktop app

Prayer Time Calendar Scheduler

A native macOS desktop app that fetches Islamic prayer times for any city worldwide and writes them straight into Google Calendar, with smart deduplication, an Islamic visual identity, and a self-contained .app bundle.

PythonPySide6QtmacOSDesktop AppGoogle Calendar APIOAuth 2.0PyInstallerIslamic Design
Overview

Prayer Time Calendar Scheduler is a standalone macOS app that removes the manual work from maintaining a prayer schedule in Google Calendar. The user picks a city or coordinates, sets a date range, and the app fetches accurate prayer times from the Aladhan API, rounds them to clean 5-minute slots, deduplicates against existing calendar events, and writes Fajr, Dhuhr, Asr, Maghrib, and Isha as 30-minute events with reminders, a chosen color, and the correct local timezone, directly into the user's Google Calendar.

The app works for any city in the world. Location can be detected automatically via macOS GPS, looked up by city name from a global offline database, searched by place name, or entered as raw coordinates. A full year of prayer events across 5 prayers is created in a few minutes from a single run.

It ships as a self-contained .app bundle via PyInstaller. No Python install, no Terminal, no dependencies to manage. The user double-clicks it like any native macOS app.

Feature highlights

Worldwide prayer coverage

Aladhan API with the Muslim World League calculation method. Any city, any country, the same engine used across global Islamic apps.

Three location modes

Browse continent to country to major city offline, search any place name via OpenStreetMap, or enter raw coordinates. Auto-detect via macOS GPS with IP fallback.

Smart deduplication

Scans the calendar before writing. Exact matches are skipped, outdated events are replaced. Running the app twice is safe.

5-minute rounding

Prayer times are rounded to clean 5-minute slots with second-precision logic, keeping the calendar tidy and readable.

Reminders and colors

Seven reminder options and eleven Google Calendar event colors, applied consistently across all 5 prayers.

Self-contained .app

Packaged with PyInstaller into a double-clickable macOS bundle. No Python, no pip, no Terminal required.

Walkthrough: Google Calendar API setup

The one-time Google Cloud Console setup, walked through end-to-end: creating a project, enabling the Calendar API, configuring Google Auth Platform, adding a test user, creating a Desktop OAuth client, downloading credentials.json, and importing it into the app. This matches the 7-step onboarding checklist built directly into the app's setup screen.

How it works
01

Pick a location

Browse offline from continent to country to city, search any place via OpenStreetMap, type coordinates directly, or auto-detect via macOS GPS with IP geolocation as fallback.

02

Set a date range and preferences

Use the quick range chips (3, 6, or 12 months) or open the styled date picker. Pick a target calendar, a reminder offset, and an event color. Preview mode shows a full event count without touching the calendar.

03

Create or update events

The app fetches prayer times, rounds them, dedupes against existing entries, and writes Fajr, Dhuhr, Asr, Maghrib, and Isha in batches of 50 via the Google Calendar API. The activity log streams progress in real time.

Technical stack
Python 3.14PySide6 (Qt 6)PyInstaller (.app bundle, arm64)Aladhan REST APIGoogle Calendar API v3OAuth 2.0 Desktop flowOpenStreetMap NominatimmacOS CoreLocation (pyobjc)ipapi.co / ip-api.com fallbackgeonamescache offline databaseJSON local cacheQPainter custom drawingQThread async (Signal/Slot)
Notable details
  • Built as a single ~2,660 line Python file. No internal modules, no build pipeline beyond PyInstaller. Easy to audit, easy to rebuild.
  • Non-blocking async model. Every network call runs in a QThread with Signal callbacks. The UI never freezes and progress streams to the activity log in real time.
  • QStackedWidget navigation. Onboarding and the main app are two pages in a stack; the app transitions automatically once OAuth is verified.
  • Credentials live in ~/Library/Application Support/Prayer Time Calendar Scheduler/. Tokens auto-refresh on expiry. The build script wipes this folder so every fresh .app starts at onboarding.
  • Deduplication compares summary, start, end, timezone, color, and reminders. Exact matches are silently skipped, non-matching events are deleted before the new event is inserted.
  • Batch API operations. Events are created and deleted in batches of 50 via service.new_batch_http_request(), with a configurable delay to stay within Google's rate limits.
  • Midnight overflow fix. Prayer times at or after 23:57:30 would mathematically round past midnight; the rounding function caps output at 23:55:00 before adding to the base date.
  • Islamic geometric sidebar. A QLinearGradient midnight background is tiled with a repeating 8-pointed Islamic star pattern (rub el hizb) rendered in gold via QPolygonF, pure vector geometry, no image assets.
  • Arabic typography. Section headers carry Arabic counterparts (المكان, الجدول, التقويم, الإطلاق), the sidebar reads أوقات الصلاة, and workflow step badges use Eastern Arabic numerals (١ ٢ ٣ ٤).
  • Custom restyled calendar popup: gold gradient header, Islamic green selected-day highlight, warm terracotta weekend columns, no grid lines, ivory background.
  • PyInstaller spec collects PySide6, geonamescache, googleapiclient, certifi, and charset_normalizer; lists hidden imports for the Google auth stack and pyobjc; injects the icon and Info.plist keys including NSLocationWhenInUseUsageDescription.
  • 143 automated checks cover syntax, all self.* attribute wiring, every selftest string, logic functions (rounding, time cleaning, event construction, deduplication, cache), credential validation, spec completeness, and build script integrity.
What this demonstrates

Full-stack native app from scratch

Not a web app in a browser shell, a genuine native macOS desktop application with custom-painted UI components, async threading, OAuth authentication, and a packaged binary. The full stack from data fetching to platform packaging is owned.

Islamic design as a first-class requirement

The visual identity was designed to feel authentically Muslim, not generically styled. The geometric star pattern, Arabic labels, Eastern Arabic numerals, gold palette, and crescent branding were each deliberate choices and required custom implementation via QPainter, Unicode, and custom widgets.

Production-quality UX thinking

Onboarding checklist, drag-and-drop credential import, contextual error messages with specific fix instructions for Google's OAuth access_denied, preview mode, smart deduplication, and the fresh-start credential wipe all reflect what happens when a real person actually uses the tool.

Packaging and distribution

Solving PyInstaller packaging for PySide6, including collecting Qt plugins, pyobjc binaries, geonamescache data files, and Google API discovery documents, and producing a signed double-clickable .app that just works is a non-trivial engineering task on its own.