Skip to content

Instantly share code, notes, and snippets.

@mq1n
Last active March 4, 2025 11:35
Show Gist options
  • Select an option

  • Save mq1n/bd31115a8769e9bb6e2b8a54634e0490 to your computer and use it in GitHub Desktop.

Select an option

Save mq1n/bd31115a8769e9bb6e2b8a54634e0490 to your computer and use it in GitHub Desktop.
Ramadan timer m2 script
import ui
import uiScriptLocale
import net
import app
import chat
import time
import math
import dbg
import constInfo
import grp
import json
import snd
# AlAdhan API base URL
ALADHAN_API_URL = "http://api.aladhan.com/v1/timingsByCity"
# Parameters for Turkey (Istanbul by default)
COUNTRY = "Turkey"
CITY = "Istanbul"
METHOD = 13 # 13 is for Diyanet method
# Turkish translations for prayer names with English characters
PRAYER_NAMES = {
"Fajr": "Imsak",
"Sunrise": "Gunes",
"Dhuhr": "Ogle",
"Asr": "Ikindi",
"Maghrib": "Aksam",
"Isha": "Yatsi"
}
# List of all 81 provinces (cities) in Turkey
TURKISH_CITIES = [
"Adana", "Adiyaman", "Afyonkarahisar", "Agri", "Aksaray", "Amasya", "Ankara", "Antalya",
"Ardahan", "Artvin", "Aydin", "Balikesir", "Bartin", "Batman", "Bayburt", "Bilecik",
"Bingol", "Bitlis", "Bolu", "Burdur", "Bursa", "Canakkale", "Cankiri", "Corum",
"Denizli", "Diyarbakir", "Duzce", "Edirne", "Elazig", "Erzincan", "Erzurum", "Eskisehir",
"Gaziantep", "Giresun", "Gumushane", "Hakkari", "Hatay", "Igdir", "Isparta", "Istanbul",
"Izmir", "Kahramanmaras", "Karabuk", "Karaman", "Kars", "Kastamonu", "Kayseri", "Kilis",
"Kirikkale", "Kirklareli", "Kirsehir", "Kocaeli", "Konya", "Kutahya", "Malatya", "Manisa",
"Mardin", "Mersin", "Mugla", "Mus", "Nevsehir", "Nigde", "Ordu", "Osmaniye",
"Rize", "Sakarya", "Samsun", "Sanliurfa", "Siirt", "Sinop", "Sirnak", "Sivas",
"Tekirdag", "Tokat", "Trabzon", "Tunceli", "Usak", "Van", "Yalova", "Yozgat", "Zonguldak"
]
# Prayer times
class PrayerTimes:
def __init__(self):
self.fajr = ""
self.sunrise = ""
self.dhuhr = ""
self.asr = ""
self.maghrib = ""
self.isha = ""
self.date = ""
self.hijri_date = ""
self.last_update = 0
self.next_prayer = ""
self.next_prayer_time = ""
self.seconds_to_next = 0
self.is_ramadan = False
class RamadanTimerWindow(ui.ScriptWindow):
def __init__(self):
ui.ScriptWindow.__init__(self)
self.isLoaded = False
self.prayerTimes = PrayerTimes()
self.city = CITY
self.country = COUNTRY
self.alarmEnabled = True
self.toolTip = None
# Timing variables
self.lastUpdateTime = 0
self.pendingAPIResponse = False
self.lastCountdownUpdate = 0
# Task flags
self.needPrayerTimesFetch = False
self.needProcessAPIResponse = False
self.apiResponseData = None
self.Initialize()
self.LoadWindow()
def __del__(self):
ui.ScriptWindow.__del__(self)
def Initialize(self):
self.childTexts = []
self.cityTextLine = None
self.dateTextLine = None
self.hijriDateTextLine = None
self.nextPrayerTextLine = None
self.countdownTextLine = None
self.fajrTextLine = None
self.sunriseTextLine = None
self.dhuhrTextLine = None
self.asrTextLine = None
self.maghribTextLine = None
self.ishaTextLine = None
self.refreshButton = None
self.alarmButton = None
self.cityListBox = None
self.searchBox = None
self.closeButton = None
def LoadWindow(self):
if self.isLoaded:
return
try:
self.LoadScript()
self.BindEvents()
self.isLoaded = True
# Schedule the initial prayer times fetch
self.needPrayerTimesFetch = True
except:
import exception
exception.Abort("RamadanTimerWindow.LoadWindow")
def LoadScript(self):
WINDOW_SIZE = (280, 410)
# Create the window
self.SetSize(WINDOW_SIZE[0], WINDOW_SIZE[1])
self.SetWindowName("RamadanTimerWindow")
self.SetCenterPosition()
self.SetTop()
self.AddFlag("movable")
self.AddFlag("float")
# Background Board
self.board = ui.BoardWithTitleBar()
self.board.SetParent(self)
self.board.SetSize(WINDOW_SIZE[0], WINDOW_SIZE[1])
self.board.SetPosition(0, 0)
self.board.SetTitleName("Namaz Vakitleri")
self.board.Show()
# City selection label
self.citySelectionLabel = ui.TextLine()
self.citySelectionLabel.SetParent(self.board)
self.citySelectionLabel.SetPosition(140, 38)
self.citySelectionLabel.SetHorizontalAlignCenter()
self.citySelectionLabel.SetText("Turkiye'de Sehir Secin")
self.citySelectionLabel.Show()
# Search Box
self.editSlot = ui.SlotBar()
self.editSlot.SetParent(self.board)
self.editSlot.SetPosition(70, 55)
self.editSlot.SetSize(140, 20)
self.editSlot.Show()
self.searchBox = ui.EditLine()
self.searchBox.SetParent(self.editSlot)
self.searchBox.SetPosition(3, 3)
self.searchBox.SetSize(140, 19)
self.searchBox.SetMax(30)
self.searchBox.SetFocus()
self.searchBox.SetReturnEvent(ui.__mem_func__(self.OnSearchReturn))
self.searchBox.SetEscapeEvent(ui.__mem_func__(self.OnSearchEscape))
self.searchBox.Show()
# City ListBox with ScrollBar
self.cityListBox = ui.ListBoxScroll()
self.cityListBox.SetParent(self.board)
self.cityListBox.SetPosition(70, 80)
self.cityListBox.SetSize(140, 80)
self.cityListBox.SetEvent(self.OnSelectCity)
# Add Turkish cities to the list
self.PopulateCityList()
self.cityListBox.Show()
# Current City and Date Information
self.cityTextLine = ui.TextLine()
self.cityTextLine.SetParent(self.board)
self.cityTextLine.SetPosition(140, 165)
self.cityTextLine.SetHorizontalAlignCenter()
self.cityTextLine.SetText("{0}, Turkiye".format(CITY))
self.cityTextLine.SetFontColor(0.8, 0.8, 1.0) # Light blue
self.cityTextLine.Show()
self.dateTextLine = ui.TextLine()
self.dateTextLine.SetParent(self.board)
self.dateTextLine.SetPosition(140, 180)
self.dateTextLine.SetHorizontalAlignCenter()
self.dateTextLine.SetText("Tarih yukleniyor...")
self.dateTextLine.Show()
self.hijriDateTextLine = ui.TextLine()
self.hijriDateTextLine.SetParent(self.board)
self.hijriDateTextLine.SetPosition(140, 195)
self.hijriDateTextLine.SetHorizontalAlignCenter()
self.hijriDateTextLine.SetText("Hicri tarih yukleniyor...")
self.hijriDateTextLine.Show()
# Section separator
self.separatorLine = ui.Line()
self.separatorLine.SetParent(self.board)
self.separatorLine.SetPosition(30, 212)
self.separatorLine.SetSize(220, 0)
self.separatorLine.Show()
# Next Prayer Information
self.nextPrayerTextLine = ui.TextLine()
self.nextPrayerTextLine.SetParent(self.board)
self.nextPrayerTextLine.SetPosition(140, 220)
self.nextPrayerTextLine.SetHorizontalAlignCenter()
self.nextPrayerTextLine.SetText("Sonraki Vakit: Yukleniyor...")
self.nextPrayerTextLine.SetFontColor(0.0, 1.0, 0.0) # Green
self.nextPrayerTextLine.Show()
self.countdownTextLine = ui.TextLine()
self.countdownTextLine.SetParent(self.board)
self.countdownTextLine.SetPosition(140, 235)
self.countdownTextLine.SetHorizontalAlignCenter()
self.countdownTextLine.SetText("Kalan Sure: --:--:--")
self.countdownTextLine.SetFontColor(1.0, 1.0, 1.0) # White
self.countdownTextLine.Show()
# Section Title
self.prayerTimesHeader = ui.TextLine()
self.prayerTimesHeader.SetParent(self.board)
self.prayerTimesHeader.SetPosition(140, 255)
self.prayerTimesHeader.SetHorizontalAlignCenter()
self.prayerTimesHeader.SetText("Gunluk Vakitler")
self.prayerTimesHeader.SetFontColor(1.0, 0.8, 0.0) # Gold color
self.prayerTimesHeader.Show()
# Prayer Times Display
yPos = 275
spacing = 16
self.CreatePrayerTimeTextLine("Fajr", "", yPos)
yPos += spacing
self.CreatePrayerTimeTextLine("Sunrise", "", yPos)
yPos += spacing
self.CreatePrayerTimeTextLine("Dhuhr", "", yPos)
yPos += spacing
self.CreatePrayerTimeTextLine("Asr", "", yPos)
yPos += spacing
self.CreatePrayerTimeTextLine("Maghrib", "", yPos)
yPos += spacing
self.CreatePrayerTimeTextLine("Isha", "", yPos)
# Buttons
buttonImagePath = {
"default": "d:/ymir work/ui/public/middle_button_01.sub",
"over": "d:/ymir work/ui/public/middle_button_02.sub",
"down": "d:/ymir work/ui/public/middle_button_03.sub"
}
# Refresh Button
self.refreshButton = ui.Button()
self.refreshButton.SetParent(self.board)
self.refreshButton.SetUpVisual(buttonImagePath["default"])
self.refreshButton.SetOverVisual(buttonImagePath["over"])
self.refreshButton.SetDownVisual(buttonImagePath["down"])
self.refreshButton.SetPosition(60, 380)
self.refreshButton.SetText("Yenile")
self.refreshButton.SetEvent(ui.__mem_func__(self.OnRefreshButtonClick))
self.refreshButton.Show()
# Alarm Button
self.alarmButton = ui.ToggleButton()
self.alarmButton.SetParent(self.board)
self.alarmButton.SetUpVisual(buttonImagePath["default"])
self.alarmButton.SetOverVisual(buttonImagePath["over"])
self.alarmButton.SetDownVisual(buttonImagePath["down"])
self.alarmButton.SetPosition(160, 380)
self.alarmButton.SetText("Alarm: ACIK")
self.alarmButton.SetToggleUpEvent(ui.__mem_func__(self.OnToggleAlarmOff))
self.alarmButton.SetToggleDownEvent(ui.__mem_func__(self.OnToggleAlarmOn))
self.alarmButton.Show()
# Set initial toggle state
if self.alarmEnabled:
self.alarmButton.Down()
else:
self.alarmButton.SetUp()
# Debug button for testing the alarm
self.debugButton = ui.Button()
self.debugButton.SetParent(self.board)
self.debugButton.SetPosition(230, 350)
self.debugButton.SetUpVisual("d:/ymir work/ui/public/small_button_01.sub")
self.debugButton.SetOverVisual("d:/ymir work/ui/public/small_button_02.sub")
self.debugButton.SetDownVisual("d:/ymir work/ui/public/small_button_03.sub")
self.debugButton.SetText("Test Alarm")
self.debugButton.SetEvent(ui.__mem_func__(self.TestAlarm))
if net.IsTest():
self.debugButton.Show()
else:
self.debugButton.Hide()
def PopulateCityList(self, filter_text=""):
"""Populate the city list, optionally filtering by the given text"""
# Clear current items
self.cityListBox.ClearItem()
# Add filtered cities
item_count = 0
for cityName in TURKISH_CITIES:
if filter_text.lower() in cityName.lower():
self.cityListBox.InsertItem(item_count, cityName)
item_count += 1
# If the search has no results, show a message
if item_count == 0:
self.cityListBox.InsertItem(0, "Sehir bulunamadi")
def OnSearchReturn(self):
"""Handle search box return event"""
search_text = self.searchBox.GetText()
self.PopulateCityList(search_text)
def OnSearchEscape(self):
"""Handle search box escape event"""
self.searchBox.SetText("")
self.PopulateCityList() # Reset to show all cities
def CreatePrayerTimeTextLine(self, name, description, yPos):
# Create prayer name text
nameText = ui.TextLine()
nameText.SetParent(self.board)
nameText.SetPosition(35, yPos) # Adjusted position further left
nameText.SetHorizontalAlignLeft()
nameText.SetText(PRAYER_NAMES.get(name, name) + ":")
nameText.SetFontColor(0.9, 0.9, 0.9) # Light grey
nameText.Show()
self.childTexts.append(nameText)
# Time text - adjusted position
timeText = ui.TextLine()
timeText.SetParent(self.board)
timeText.SetPosition(200, yPos) # Adjusted position
timeText.SetHorizontalAlignRight()
timeText.SetText("--:--")
timeText.SetFontColor(1.0, 1.0, 1.0) # White
timeText.Show()
if name == "Fajr":
self.fajrTextLine = timeText
elif name == "Sunrise":
self.sunriseTextLine = timeText
elif name == "Dhuhr":
self.dhuhrTextLine = timeText
elif name == "Asr":
self.asrTextLine = timeText
elif name == "Maghrib":
self.maghribTextLine = timeText
elif name == "Isha":
self.ishaTextLine = timeText
self.childTexts.append(timeText)
return timeText
def BindEvents(self):
# No need to explicitly start update cycle - it's handled by the window system
self.lastUpdateTime = app.GetTime()
self.lastCountdownUpdate = app.GetTime()
def OnUpdateEx(self):
# This is called every frame by the window system
currentTime = app.GetTime()
# Handle countdown update - update every second
if currentTime - self.lastCountdownUpdate >= 1.0:
self.UpdateCountdown()
self.lastCountdownUpdate = currentTime
# Check if it's prayer time and play alarm
if self.alarmEnabled and self.prayerTimes.seconds_to_next == 0:
self.PlayPrayerAlarm()
# Check if we need to refresh data (every 6 hours or at first load)
if currentTime - self.prayerTimes.last_update > 21600: # 6 hours = 21600 seconds
self.needPrayerTimesFetch = True
# Process any pending tasks
if self.needPrayerTimesFetch:
self.FetchPrayerTimes()
self.needPrayerTimesFetch = False
# Process API response if we have one
if self.needProcessAPIResponse and self.apiResponseData:
self.ProcessAPIResponse(self.apiResponseData)
self.apiResponseData = None
self.needProcessAPIResponse = False
def OnSelectCity(self, index, cityName):
self.city = cityName
self.cityTextLine.SetText("{0}, Turkiye".format(self.city))
chat.AppendChat(chat.CHAT_TYPE_INFO, "Secilen sehir: {0}".format(self.city))
# Fetch prayer times for the selected city
self.FetchPrayerTimes()
def OnRefreshButtonClick(self):
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakitleri yenileniyor...")
self.needPrayerTimesFetch = True
def OnToggleAlarmOff(self):
self.alarmEnabled = False
self.alarmButton.SetText("Alarm: KAPALI")
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakti alarmi simdi KAPALI")
def OnToggleAlarmOn(self):
self.alarmEnabled = True
self.alarmButton.SetText("Alarm: ACIK")
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakti alarmi simdi ACIK")
def FetchPrayerTimes(self):
"""Fetch prayer times from AlAdhan API"""
# Create request parameters
params = {
'city': self.city,
'country': self.country,
'method': METHOD
}
try:
# # URL encode the parameters
url = ALADHAN_API_URL + "?"
for key, value in params.items():
url += "{}={}&".format(key, value)
url = url[:-1]
# chat.AppendChat(chat.CHAT_TYPE_INFO, url)
chat.AppendChat(chat.CHAT_TYPE_INFO, "{0}, {1} icin namaz vakitleri aliniyor...".format(self.city, "Turkiye"))
# # Make the HTTP request
response = app.HttpRequest(url)
# Check if response is None or empty
if not response:
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakitleri alinamadi: Bos yanit")
return
# Check if response starts with '-' (error indicator)
if isinstance(response, str) and response.startswith("-"):
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakitleri alinirken hata: {}".format(response))
return
# dbg.TraceError("Response type: %s, First 50 chars: %s" % (type(response), str(response)[:50]))
# Store the data for processing in next frame
self.apiResponseData = response
self.needProcessAPIResponse = True
except Exception as e:
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakitleri alinirken hata: {0}".format(str(e)))
chat.AppendChat(chat.CHAT_TYPE_INFO, "Simule edilmis namaz vakitleri kullaniliyor...")
# Use fallback method directly
self.OnPrayerTimesFetched()
def ProcessAPIResponse(self, data):
"""Handle the API response data"""
try:
# If data is bytes, decode it safely
if isinstance(data, bytes):
data = data.decode('latin-1') # latin-1 can handle any byte value
# Parse the JSON data
json_data = json.loads(data)
# Check if the request was successful
if json_data.get('code') == 200 and json_data.get('status') == 'OK':
# Extract prayer times from response
timings = json_data.get('data', {}).get('timings', {})
date = json_data.get('data', {}).get('date', {})
# Update prayer times - ensure all strings are ASCII compatible
self.prayerTimes.fajr = self._safe_str(timings.get('Fajr', ''))
self.prayerTimes.sunrise = self._safe_str(timings.get('Sunrise', ''))
self.prayerTimes.dhuhr = self._safe_str(timings.get('Dhuhr', ''))
self.prayerTimes.asr = self._safe_str(timings.get('Asr', ''))
self.prayerTimes.maghrib = self._safe_str(timings.get('Maghrib', ''))
self.prayerTimes.isha = self._safe_str(timings.get('Isha', ''))
# Update date information - also ensure ASCII compatibility
gregorian_date = date.get('gregorian', {})
hijri_date = date.get('hijri', {})
# Format date strings safely
self.prayerTimes.date = "{0} {1} {2}".format(
self._safe_str(gregorian_date.get('day', '')),
self._safe_str(gregorian_date.get('month', {}).get('en', '')),
self._safe_str(gregorian_date.get('year', ''))
)
# Create ASCII-safe hijri date
# Use a safe mapping for Islamic month names
# Islamic month names without diacritical marks
hijri_month_names = {
1: "Muharram",
2: "Safar",
3: "Rabi al-Awwal",
4: "Rabi al-Thani",
5: "Jumada al-Awwal",
6: "Jumada al-Thani",
7: "Rajab",
8: "Shaban",
9: "Ramadan",
10: "Shawwal",
11: "Dhu al-Qadah",
12: "Dhu al-Hijjah"
}
# Get numeric month value
hijri_month_num = int(hijri_date.get("month", {}).get("number", 0))
# Get month name using our ASCII-safe mapping
hijri_month_name = hijri_month_names.get(hijri_month_num, "Unknown")
self.prayerTimes.hijri_date = "{0} {1} {2}".format(
hijri_date.get("day", ""),
hijri_month_name,
hijri_date.get("year", "")
)
# Check if it's Ramadan
self.prayerTimes.is_ramadan = (hijri_month_num == 9)
# Update last update timestamp
self.prayerTimes.last_update = app.GetTime()
# Update UI
self.UpdateUI()
# Notify user
chat.AppendChat(chat.CHAT_TYPE_INFO, "Namaz vakitleri guncellendi!")
# If it's Ramadan, show a special message
if self.prayerTimes.is_ramadan:
chat.AppendChat(chat.CHAT_TYPE_INFO, "Ramazan Mubarek! Allah tuttugunuz oruclari ve kildiginiz namazlari kabul etsin.")
else:
error_msg = json_data.get('data', '')
chat.AppendChat(chat.CHAT_TYPE_INFO, "API Hatasi: {0}".format(error_msg))
# Fall back to simulated times
self.OnPrayerTimesFetched()
except Exception as e:
chat.AppendChat(chat.CHAT_TYPE_INFO, "API yaniti islenirken hata: {0}".format(str(e)))
dbg.TraceError("API Response processing failed: {0}".format(str(e)))
# Fall back to simulated times
self.OnPrayerTimesFetched()
def _safe_str(self, text):
"""Convert any string to ASCII-safe string"""
if not text:
return ""
# If we're in Python 2, handle unicode conversion
if isinstance(text, unicode):
# Replace non-ASCII characters with their closest ASCII equivalents
return text.encode('ascii', 'replace')
# If it's already a string, make sure it's ASCII-compatible
try:
# Try to encode as ASCII to check
if isinstance(text, str):
text.encode('ascii')
return text
# If it's something else, convert to string
return str(text)
except UnicodeError:
# If ASCII encoding fails, replace problematic characters
if isinstance(text, str):
# For Python 2, decode to unicode first
return text.decode('utf-8', 'replace').encode('ascii', 'replace')
# Fallback
return str(text).encode('ascii', 'replace')
def OnPrayerTimesFetched(self):
"""Fallback method for when API calls fail - uses simulated data based on city"""
# Get current date and time
current_time = time.localtime()
year = current_time.tm_year
month = current_time.tm_mon
day = current_time.tm_mday
# City-specific prayer time adjustments (approximations for simulation)
# Each city gets a different offset to create realistic variations based on geographic location
city_adjustments = {
# Istanbul (reference city - no adjustment)
"Istanbul": {"fajr": 0, "sunrise": 0, "dhuhr": 0, "asr": 0, "maghrib": 0, "isha": 0},
# Cities in the Marmara Region
"Balikesir": {"fajr": -4, "sunrise": -4, "dhuhr": -2, "asr": -3, "maghrib": -4, "isha": -6},
"Bilecik": {"fajr": 2, "sunrise": 2, "dhuhr": 1, "asr": 1, "maghrib": 2, "isha": 2},
"Bursa": {"fajr": -2, "sunrise": -2, "dhuhr": -1, "asr": -1, "maghrib": -3, "isha": -3},
"Canakkale": {"fajr": -7, "sunrise": -7, "dhuhr": -4, "asr": -5, "maghrib": -7, "isha": -9},
"Edirne": {"fajr": -3, "sunrise": -3, "dhuhr": -2, "asr": -2, "maghrib": -5, "isha": -5},
"Kirklareli": {"fajr": -4, "sunrise": -4, "dhuhr": -2, "asr": -3, "maghrib": -5, "isha": -5},
"Kocaeli": {"fajr": 1, "sunrise": 1, "dhuhr": 0, "asr": 0, "maghrib": 1, "isha": 1},
"Sakarya": {"fajr": 2, "sunrise": 2, "dhuhr": 1, "asr": 1, "maghrib": 2, "isha": 2},
"Tekirdag": {"fajr": -5, "sunrise": -5, "dhuhr": -3, "asr": -4, "maghrib": -5, "isha": -7},
"Yalova": {"fajr": 0, "sunrise": 0, "dhuhr": 0, "asr": 0, "maghrib": 0, "isha": 0},
# Cities in the Aegean Region
"Afyonkarahisar": {"fajr": -5, "sunrise": -5, "dhuhr": -3, "asr": -4, "maghrib": -6, "isha": -7},
"Aydin": {"fajr": -8, "sunrise": -8, "dhuhr": -4, "asr": -5, "maghrib": -8, "isha": -10},
"Denizli": {"fajr": -7, "sunrise": -7, "dhuhr": -3, "asr": -4, "maghrib": -7, "isha": -9},
"Izmir": {"fajr": -5, "sunrise": -5, "dhuhr": -2, "asr": -3, "maghrib": -8, "isha": -8},
"Kutahya": {"fajr": -3, "sunrise": -3, "dhuhr": -2, "asr": -2, "maghrib": -4, "isha": -5},
"Manisa": {"fajr": -6, "sunrise": -6, "dhuhr": -3, "asr": -4, "maghrib": -6, "isha": -8},
"Mugla": {"fajr": -9, "sunrise": -9, "dhuhr": -5, "asr": -6, "maghrib": -9, "isha": -11},
"Usak": {"fajr": -6, "sunrise": -6, "dhuhr": -3, "asr": -4, "maghrib": -7, "isha": -8},
# Cities in the Mediterranean Region
"Adana": {"fajr": -12, "sunrise": -12, "dhuhr": -5, "asr": -6, "maghrib": -12, "isha": -15},
"Antalya": {"fajr": -10, "sunrise": -10, "dhuhr": -5, "asr": -7, "maghrib": -10, "isha": -12},
"Burdur": {"fajr": -7, "sunrise": -7, "dhuhr": -4, "asr": -5, "maghrib": -8, "isha": -9},
"Hatay": {"fajr": -15, "sunrise": -15, "dhuhr": -8, "asr": -10, "maghrib": -15, "isha": -17},
"Isparta": {"fajr": -7, "sunrise": -7, "dhuhr": -4, "asr": -5, "maghrib": -8, "isha": -9},
"Kahramanmaras": {"fajr": -14, "sunrise": -14, "dhuhr": -7, "asr": -9, "maghrib": -14, "isha": -16},
"Mersin": {"fajr": -13, "sunrise": -13, "dhuhr": -7, "asr": -8, "maghrib": -13, "isha": -15},
"Osmaniye": {"fajr": -13, "sunrise": -13, "dhuhr": -6, "asr": -8, "maghrib": -13, "isha": -15},
# Cities in the Central Anatolia Region
"Aksaray": {"fajr": -6, "sunrise": -6, "dhuhr": -3, "asr": -4, "maghrib": -6, "isha": -8},
"Ankara": {"fajr": 5, "sunrise": 5, "dhuhr": 2, "asr": 3, "maghrib": 5, "isha": 5},
"Cankiri": {"fajr": 7, "sunrise": 7, "dhuhr": 3, "asr": 4, "maghrib": 6, "isha": 8},
"Eskisehir": {"fajr": 0, "sunrise": 0, "dhuhr": 0, "asr": 0, "maghrib": -2, "isha": -2},
"Karaman": {"fajr": -8, "sunrise": -8, "dhuhr": -4, "asr": -5, "maghrib": -8, "isha": -10},
"Kayseri": {"fajr": -5, "sunrise": -5, "dhuhr": 0, "asr": -2, "maghrib": -5, "isha": -7},
"Kirikkale": {"fajr": 4, "sunrise": 4, "dhuhr": 2, "asr": 2, "maghrib": 4, "isha": 5},
"Kirsehir": {"fajr": 3, "sunrise": 3, "dhuhr": 1, "asr": 2, "maghrib": 3, "isha": 4},
"Konya": {"fajr": -3, "sunrise": -2, "dhuhr": 0, "asr": 0, "maghrib": -3, "isha": -5},
"Nevsehir": {"fajr": -4, "sunrise": -4, "dhuhr": -2, "asr": -3, "maghrib": -4, "isha": -6},
"Nigde": {"fajr": -6, "sunrise": -6, "dhuhr": -3, "asr": -4, "maghrib": -6, "isha": -8},
"Sivas": {"fajr": 0, "sunrise": 0, "dhuhr": 0, "asr": 0, "maghrib": 0, "isha": 0},
"Yozgat": {"fajr": 2, "sunrise": 2, "dhuhr": 1, "asr": 1, "maghrib": 2, "isha": 3},
# Cities in the Black Sea Region
"Amasya": {"fajr": 5, "sunrise": 5, "dhuhr": 3, "asr": 3, "maghrib": 5, "isha": 7},
"Artvin": {"fajr": 20, "sunrise": 20, "dhuhr": 10, "asr": 12, "maghrib": 20, "isha": 22},
"Bartin": {"fajr": 6, "sunrise": 6, "dhuhr": 3, "asr": 4, "maghrib": 6, "isha": 8},
"Bayburt": {"fajr": 10, "sunrise": 10, "dhuhr": 5, "asr": 7, "maghrib": 10, "isha": 12},
"Bolu": {"fajr": 3, "sunrise": 3, "dhuhr": 1, "asr": 2, "maghrib": 3, "isha": 4},
"Corum": {"fajr": 5, "sunrise": 5, "dhuhr": 2, "asr": 3, "maghrib": 5, "isha": 6},
"Duzce": {"fajr": 3, "sunrise": 3, "dhuhr": 1, "asr": 2, "maghrib": 3, "isha": 4},
"Giresun": {"fajr": 12, "sunrise": 12, "dhuhr": 6, "asr": 8, "maghrib": 12, "isha": 14},
"Gumushane": {"fajr": 10, "sunrise": 10, "dhuhr": 5, "asr": 7, "maghrib": 10, "isha": 12},
"Karabuk": {"fajr": 5, "sunrise": 5, "dhuhr": 2, "asr": 3, "maghrib": 5, "isha": 6},
"Kastamonu": {"fajr": 7, "sunrise": 7, "dhuhr": 3, "asr": 4, "maghrib": 7, "isha": 9},
"Ordu": {"fajr": 10, "sunrise": 10, "dhuhr": 5, "asr": 7, "maghrib": 10, "isha": 12},
"Rize": {"fajr": 18, "sunrise": 18, "dhuhr": 9, "asr": 11, "maghrib": 18, "isha": 20},
"Samsun": {"fajr": 8, "sunrise": 8, "dhuhr": 5, "asr": 5, "maghrib": 8, "isha": 10},
"Sinop": {"fajr": 9, "sunrise": 9, "dhuhr": 4, "asr": 6, "maghrib": 9, "isha": 11},
"Tokat": {"fajr": 5, "sunrise": 5, "dhuhr": 3, "asr": 3, "maghrib": 5, "isha": 7},
"Trabzon": {"fajr": 15, "sunrise": 15, "dhuhr": 8, "asr": 10, "maghrib": 15, "isha": 17},
"Zonguldak": {"fajr": 6, "sunrise": 6, "dhuhr": 3, "asr": 4, "maghrib": 6, "isha": 8},
# Cities in the Southeastern Anatolia Region
"Adiyaman": {"fajr": -15, "sunrise": -15, "dhuhr": -8, "asr": -10, "maghrib": -15, "isha": -17},
"Batman": {"fajr": -22, "sunrise": -22, "dhuhr": -12, "asr": -14, "maghrib": -22, "isha": -24},
"Diyarbakir": {"fajr": -20, "sunrise": -20, "dhuhr": -10, "asr": -12, "maghrib": -20, "isha": -22},
"Gaziantep": {"fajr": -15, "sunrise": -15, "dhuhr": -8, "asr": -10, "maghrib": -15, "isha": -18},
"Kilis": {"fajr": -16, "sunrise": -16, "dhuhr": -8, "asr": -10, "maghrib": -16, "isha": -18},
"Mardin": {"fajr": -22, "sunrise": -22, "dhuhr": -12, "asr": -14, "maghrib": -22, "isha": -24},
"Sanliurfa": {"fajr": -18, "sunrise": -18, "dhuhr": -10, "asr": -12, "maghrib": -18, "isha": -20},
"Siirt": {"fajr": -24, "sunrise": -24, "dhuhr": -13, "asr": -15, "maghrib": -24, "isha": -26},
"Sirnak": {"fajr": -25, "sunrise": -25, "dhuhr": -13, "asr": -16, "maghrib": -25, "isha": -27},
# Cities in the Eastern Anatolia Region
"Agri": {"fajr": -18, "sunrise": -18, "dhuhr": -9, "asr": -11, "maghrib": -18, "isha": -20},
"Ardahan": {"fajr": 15, "sunrise": 15, "dhuhr": 8, "asr": 10, "maghrib": 15, "isha": 17},
"Bingol": {"fajr": -15, "sunrise": -15, "dhuhr": -8, "asr": -10, "maghrib": -15, "isha": -17},
"Bitlis": {"fajr": -20, "sunrise": -20, "dhuhr": -10, "asr": -12, "maghrib": -20, "isha": -22},
"Elazig": {"fajr": -15, "sunrise": -15, "dhuhr": -8, "asr": -10, "maghrib": -15, "isha": -17},
"Erzincan": {"fajr": -8, "sunrise": -8, "dhuhr": -4, "asr": -5, "maghrib": -8, "isha": -10},
"Erzurum": {"fajr": -10, "sunrise": -10, "dhuhr": -5, "asr": -6, "maghrib": -10, "isha": -12},
"Hakkari": {"fajr": -28, "sunrise": -28, "dhuhr": -15, "asr": -18, "maghrib": -28, "isha": -30},
"Igdir": {"fajr": -15, "sunrise": -15, "dhuhr": -8, "asr": -10, "maghrib": -15, "isha": -17},
"Kars": {"fajr": -12, "sunrise": -12, "dhuhr": -6, "asr": -8, "maghrib": -12, "isha": -14},
"Malatya": {"fajr": -12, "sunrise": -12, "dhuhr": -6, "asr": -8, "maghrib": -12, "isha": -14},
"Mus": {"fajr": -18, "sunrise": -18, "dhuhr": -9, "asr": -11, "maghrib": -18, "isha": -20},
"Tunceli": {"fajr": -12, "sunrise": -12, "dhuhr": -6, "asr": -8, "maghrib": -12, "isha": -14},
"Van": {"fajr": -25, "sunrise": -25, "dhuhr": -15, "asr": -17, "maghrib": -25, "isha": -27}
}
# Get adjustments for the current city or default to Istanbul if not found
adjustments = city_adjustments.get(self.city, city_adjustments["Istanbul"])
# Base times for Istanbul (in minutes since midnight)
base_times = {
"fajr": 270, # 04:30
"sunrise": 360, # 06:00
"dhuhr": 795, # 13:15
"asr": 1005, # 16:45
"maghrib": 1205, # 20:05
"isha": 1305 # 21:45
}
# Apply adjustments and convert to HH:MM format
self.prayerTimes.fajr = self.MinutesToTime(base_times["fajr"] + adjustments["fajr"])
self.prayerTimes.sunrise = self.MinutesToTime(base_times["sunrise"] + adjustments["sunrise"])
self.prayerTimes.dhuhr = self.MinutesToTime(base_times["dhuhr"] + adjustments["dhuhr"])
self.prayerTimes.asr = self.MinutesToTime(base_times["asr"] + adjustments["asr"])
self.prayerTimes.maghrib = self.MinutesToTime(base_times["maghrib"] + adjustments["maghrib"])
self.prayerTimes.isha = self.MinutesToTime(base_times["isha"] + adjustments["isha"])
# If it's Ramadan (assuming March 11 - April 2024 is Ramadan)
is_ramadan = (month == 4 and year == 2024) or (month == 3 and year == 2024 and day >= 11)
# Set date information
self.prayerTimes.date = time.strftime("%d %B %Y", current_time)
# Simulate Hijri date based on Gregorian
if is_ramadan:
# Calculate an approximate Ramadan day (for demonstration)
ramadan_day = 1
if month == 3:
ramadan_day = day - 10
elif month == 4:
ramadan_day = day + 21
if ramadan_day > 30:
ramadan_day = 30
self.prayerTimes.hijri_date = "{0} Ramadan 1445".format(ramadan_day)
else:
# Just a placeholder for non-Ramadan dates
hijri_months = ["Muharram", "Safar", "Rabi al-Awwal", "Rabi al-Thani",
"Jumada al-Awwal", "Jumada al-Thani", "Rajab", "Sha'ban",
"Ramadan", "Shawwal", "Dhu al-Qadah", "Dhu al-Hijjah"]
# Simplified conversion - not accurate
hijri_month = hijri_months[(month + 1) % 12]
hijri_year = 1445 if month >= 7 else 1446
self.prayerTimes.hijri_date = "{0} {1} {2}".format(day, hijri_month, hijri_year)
# Set Ramadan flag
self.prayerTimes.is_ramadan = "Ramadan" in self.prayerTimes.hijri_date
# Update last update timestamp
self.prayerTimes.last_update = app.GetTime()
# Update UI
self.UpdateUI()
# Notify user
chat.AppendChat(chat.CHAT_TYPE_INFO, "Simule edilmis namaz vakitleri kullaniliyor.")
def MinutesToTime(self, minutes):
"""Convert minutes since midnight to HH:MM format"""
# Handle overflow/underflow
while minutes < 0:
minutes += 1440 # Add a full day (24*60)
while minutes >= 1440:
minutes -= 1440 # Subtract a full day
hours = minutes // 60
mins = minutes % 60
return "{0:02d}:{1:02d}".format(hours, mins)
def UpdateUI(self):
"""Update the UI with the fetched prayer times"""
self.dateTextLine.SetText(self.prayerTimes.date)
self.hijriDateTextLine.SetText(self.prayerTimes.hijri_date)
# Update prayer time displays
self.fajrTextLine.SetText(self.prayerTimes.fajr)
self.sunriseTextLine.SetText(self.prayerTimes.sunrise)
self.dhuhrTextLine.SetText(self.prayerTimes.dhuhr)
self.asrTextLine.SetText(self.prayerTimes.asr)
self.maghribTextLine.SetText(self.prayerTimes.maghrib)
self.ishaTextLine.SetText(self.prayerTimes.isha)
# Highlight if it's Ramadan
if self.prayerTimes.is_ramadan:
self.hijriDateTextLine.SetFontColor(1.0, 0.5, 0.0) # Orange color for Ramadan
else:
self.hijriDateTextLine.SetFontColor(1.0, 1.0, 1.0) # White color otherwise
# Update next prayer and countdown
self.UpdateNextPrayer()
self.UpdateCountdown()
def UpdateNextPrayer(self):
"""Determine which prayer is next"""
if not self.prayerTimes.fajr: # No data loaded yet
return
current_time = time.localtime()
current_hour = current_time.tm_hour
current_minute = current_time.tm_min
current_time_str = "{0:02d}:{1:02d}".format(current_hour, current_minute)
# Convert prayer times to comparable format (hours * 60 + minutes)
current_minutes = current_hour * 60 + current_minute
prayer_times = {
"Fajr": self.TimeToMinutes(self.prayerTimes.fajr),
"Sunrise": self.TimeToMinutes(self.prayerTimes.sunrise),
"Dhuhr": self.TimeToMinutes(self.prayerTimes.dhuhr),
"Asr": self.TimeToMinutes(self.prayerTimes.asr),
"Maghrib": self.TimeToMinutes(self.prayerTimes.maghrib),
"Isha": self.TimeToMinutes(self.prayerTimes.isha)
}
# Find the next prayer
next_prayer = None
min_diff = 24 * 60 # Maximum difference (24 hours)
for prayer, time_in_minutes in prayer_times.items():
diff = time_in_minutes - current_minutes
if diff < 0:
diff += 24 * 60 # Add a day if the prayer is tomorrow
if diff < min_diff:
min_diff = diff
next_prayer = prayer
# Update next prayer information
self.prayerTimes.next_prayer = next_prayer
self.prayerTimes.seconds_to_next = min_diff * 60 # Convert minutes to seconds
# Get the actual time of the next prayer
if next_prayer == "Fajr":
self.prayerTimes.next_prayer_time = self.prayerTimes.fajr
elif next_prayer == "Sunrise":
self.prayerTimes.next_prayer_time = self.prayerTimes.sunrise
elif next_prayer == "Dhuhr":
self.prayerTimes.next_prayer_time = self.prayerTimes.dhuhr
elif next_prayer == "Asr":
self.prayerTimes.next_prayer_time = self.prayerTimes.asr
elif next_prayer == "Maghrib":
self.prayerTimes.next_prayer_time = self.prayerTimes.maghrib
elif next_prayer == "Isha":
self.prayerTimes.next_prayer_time = self.prayerTimes.isha
# Update UI
turkish_prayer_name = PRAYER_NAMES.get(next_prayer, next_prayer)
self.nextPrayerTextLine.SetText("Sonraki Vakit: {0} ({1})".format(turkish_prayer_name, self.prayerTimes.next_prayer_time))
# Highlight next prayer in the list
self.ResetPrayerHighlights()
self.HighlightNextPrayer(next_prayer)
def ResetPrayerHighlights(self):
"""Reset all prayer time highlights"""
self.fajrTextLine.SetFontColor(1.0, 1.0, 1.0)
self.sunriseTextLine.SetFontColor(1.0, 1.0, 1.0)
self.dhuhrTextLine.SetFontColor(1.0, 1.0, 1.0)
self.asrTextLine.SetFontColor(1.0, 1.0, 1.0)
self.maghribTextLine.SetFontColor(1.0, 1.0, 1.0)
self.ishaTextLine.SetFontColor(1.0, 1.0, 1.0)
def HighlightNextPrayer(self, prayer):
"""Highlight the next prayer in the list"""
highlight_color = (0.0, 1.0, 0.0) # Green
if prayer == "Fajr":
self.fajrTextLine.SetFontColor(*highlight_color)
elif prayer == "Sunrise":
self.sunriseTextLine.SetFontColor(*highlight_color)
elif prayer == "Dhuhr":
self.dhuhrTextLine.SetFontColor(*highlight_color)
elif prayer == "Asr":
self.asrTextLine.SetFontColor(*highlight_color)
elif prayer == "Maghrib":
self.maghribTextLine.SetFontColor(*highlight_color)
elif prayer == "Isha":
self.ishaTextLine.SetFontColor(*highlight_color)
def UpdateCountdown(self):
"""Update the countdown timer to the next prayer"""
if not self.prayerTimes.next_prayer: # No data loaded yet
return
seconds = self.prayerTimes.seconds_to_next
if seconds <= 0:
# Time for prayer, update to the next one
self.UpdateNextPrayer()
seconds = self.prayerTimes.seconds_to_next
# Format the remaining time
hours = seconds // 3600
minutes = (seconds % 3600) // 60
secs = seconds % 60
countdown = "{0:02d}:{1:02d}:{2:02d}".format(hours, minutes, secs)
self.countdownTextLine.SetText("Kalan Sure: {0}".format(countdown))
# Decrement the countdown
self.prayerTimes.seconds_to_next -= 1
# Change color based on time remaining
if hours == 0 and minutes < 10: # Less than 10 minutes
self.countdownTextLine.SetFontColor(1.0, 0.0, 0.0) # Red
else:
self.countdownTextLine.SetFontColor(1.0, 1.0, 1.0) # White
def TimeToMinutes(self, time_str):
"""Convert time string (HH:MM) to minutes since midnight"""
if ":" not in time_str:
return 0
hours, minutes = map(int, time_str.split(":"))
return hours * 60 + minutes
def PlayPrayerAlarm(self):
"""Play a sound to alert the player that it's prayer time"""
if not self.alarmEnabled:
return
# Ignore except Maghrib and Fajr
prayer = self.prayerTimes.next_prayer
if prayer not in ["Maghrib", "Fajr"]:
return
# Play a sound effect
snd.PlaySound("sound/ui/money.wav")
# Display a notification
turkish_prayer_name = PRAYER_NAMES.get(prayer, prayer)
chat.AppendChat(chat.CHAT_TYPE_INFO, "{0} vakti geldi!".format(turkish_prayer_name))
notificationMessage = ""
# Special message if it's time to break the fast
if prayer == "Maghrib" and self.prayerTimes.is_ramadan:
notificationMessage = "Iftar vakti geldi! Allah kabul etsin, afiyet olsun!"
# Special message for Fajr during Ramadan
if prayer == "Fajr" and self.prayerTimes.is_ramadan:
notificationMessage = "Sahur ve Imsak vakti! Allah orucunuzu kabul etsin!"
app.Beep(1000, 1000)
chat.AppendChat(chat.CHAT_TYPE_BIG_NOTICE, notificationMessage)
app.ShowTrayNotification("Warning", notificationMessage, 5000, app.NOTIFICATION_ICON_WARNING)
def TestAlarm(self, delay=5):
"""Debug function to trigger the alarm for testing purposes"""
chat.AppendChat(chat.CHAT_TYPE_INFO, "Alarm test started, will trigger in {0} seconds".format(delay))
# Make sure alarm is enabled
self.alarmEnabled = True
self.alarmButton.SetText("Alarm: ON")
self.alarmButton.SetEvent(ui.__mem_func__(self.OnToggleAlarmOff))
# Set to Maghrib for testing (one of the prayers that triggers alarm)
self.prayerTimes.next_prayer = "Maghrib"
self.prayerTimes.is_ramadan = True # Set this to True for full test
if delay <= 0:
# Trigger immediately
self.prayerTimes.seconds_to_next = 0
self.PlayPrayerAlarm()
else:
# Set countdown to specified seconds
self.prayerTimes.seconds_to_next = delay
chat.AppendChat(chat.CHAT_TYPE_INFO, "Countdown set to {0} seconds".format(delay))
def Close(self):
# No need to cancel timers - window system handles it
self.Hide()
def Destroy(self):
# Clear all UI elements
self.ClearDictionary()
self.cityTextLine = None
self.dateTextLine = None
self.hijriDateTextLine = None
self.nextPrayerTextLine = None
self.countdownTextLine = None
self.fajrTextLine = None
self.sunriseTextLine = None
self.dhuhrTextLine = None
self.asrTextLine = None
self.maghribTextLine = None
self.ishaTextLine = None
self.refreshButton = None
self.alarmButton = None
self.cityListBox = None
self.searchBox = None
self.citySelectionLabel = None
self.board = None
self.closeButton = None
# Clear prayer times data
self.prayerTimes = None
def ScheduleFetchPrayerTimes(self):
# Set the flag to fetch prayer times in the next update
self.needPrayerTimesFetch = True
def OnPressEscapeKey(self):
self.Close()
return True
def Toggle(self):
if self.IsShow():
self.Hide()
else:
self.Show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment