Example #1
0
class TextPlug(BasePlugin, TextPlugUI):
    ## all options (except for "enable" and "show_date") will be saved in file confPath
    def __init__(self, enable=True, show_date=False):
        #print '----------- praytime TextPlug.__init__'
        #print 'From plugin: core.VERSION=%s'%api.get('core', 'VERSION')
        #print 'From plugin: core.aaa=%s'%api.get('core', 'aaa')
        BasePlugin.__init__(
            self,
            path=_mypath,
            mode='gregorian',
            desc=_('Islamic Pray Times'),
            enable=enable,
            show_date=show_date,
            last_day_merge=False,
        )
        self.external = True
        self.name = _('Islamic Pray Times')
        self.about = _('Islamic Pray Times') ## FIXME
        self.has_config = True
        ##############
        ## here load config ## FIXME
        locName = 'Tehran'
        lat = 35.705
        lng = 51.4216
        method = 'Tehran'
        imsak = 10 ## minutes before Fajr (Morning Azan)
        #asrMode=ASR_STANDARD
        #highLats='NightMiddle'
        #timeFormat='24h'
        shownTimeNames = ('fajr', 'sunrise', 'dhuhr', 'maghrib', 'midnight')
        sep = '     '
        ####
        if isfile(confPath):
            exec(open(confPath).read())
        #######
        self.locName = locName
        self.imsak = imsak
        self.ptObj = PrayTimes(lat, lng, methodName=method, imsak='%d min'%imsak)
        self.shownTimeNames = shownTimeNames
        self.sep = sep
        #######
        #PrayTimeEventRule.plug = self
        #######
        self.makeWidget()## FIXME
    def saveConfig(self):
        text = 'locName=%r\n'%self.locName
        text += 'lat=%r\n'%self.ptObj.lat
        text += 'lng=%r\n'%self.ptObj.lng
        text += 'method=%r\n'%self.ptObj.method.name
        text += 'shownTimeNames=%r\n'%self.shownTimeNames
        text += 'imsak=%r\n'%self.imsak
        text += 'sep=%r\n'%self.sep
        open(confPath, 'w').write(text)
    #def date_change_after(self, widget, year, month, day):
    #    self.dialog.menuCell.add(self.menuitem)
    #    self.menu_unmap_id = self.dialog.menuCell.connect('unmap', self.menu_unmap)
    #def menu_unmap(self, menu):
    #    menu.remove(self.menuitem)
    #    menu.disconnect(self.menu_unmap_id)
    def get_times_jd(self, jd):
        times = self.ptObj.getTimesByJd(
            jd,
            getTimeZoneByJd(jd)/3600.0,
        )
        return [(name, times[name]) for name in self.shownTimeNames]
    def getFormattedTime(self, tm):## tm is float hour
        try:
            (h, m, s) = floatHourToTime(float(tm))
        except ValueError:
            return tm
        else:
            return '%d:%.2d'%(h, m)
    def get_text_jd(self, jd):
        return self.sep.join([
            '%s: %s'%(_(name.capitalize()), self.getFormattedTime(tm))
            for name, tm in self.get_times_jd(jd)
        ])
    def get_text(self, year, month, day):## just for compatibity (usage by external programs)
        return self.get_text_jd(gregorian_to_jd(year, month, day))
    def update_cell(self, c):
        text = self.get_text_jd(c.jd)
        if text!='':
            if c.pluginsText!='':
                c.pluginsText += '\n'
            c.pluginsText += text
Example #2
0
class TextPlug(BasePlugin, TextPlugUI):
    ## all options (except for "enable" and "show_date") will be saved in file confPath
    azanTimeNamesAll = (
        'fajr',
        'dhuhr',
        'asr',
        'maghrib',
        'isha',
    )
    def __init__(self, enable=True, show_date=False):
        #print('----------- praytime TextPlug.__init__')
        #print('From plugin: core.VERSION=%s'%api.get('core', 'VERSION'))
        #print('From plugin: core.aaa=%s'%api.get('core', 'aaa'))
        BasePlugin.__init__(
            self,
            path=_mypath,
            mode='gregorian',
            desc=_('Islamic Pray Times'),
            enable=enable,
            show_date=show_date,
            last_day_merge=False,
        )
        self.external = True
        self.name = _('Islamic Pray Times')
        self.about = _('Islamic Pray Times') ## FIXME
        self.has_config = True
        self.cityData = readLocationData()
        ##############
        confNeedsSave = False
        ######
        locName, lat, lng = '', 0, 0
        method = ''
        #######
        imsak = 10 ## minutes before Fajr (Morning Azan)
        #asrMode=ASR_STANDARD
        #highLats='NightMiddle'
        #timeFormat='24h'
        shownTimeNames = ('fajr', 'sunrise', 'dhuhr', 'maghrib', 'midnight')
        ## FIXME rename shownTimeNames to activeTimeNames
        ## or add another list azanSoundTimeNames
        sep = '     '
        ##
        azanEnable = False
        azanFile = None
        ##
        preAzanEnable = False
        preAzanFile = None
        preAzanMinutes = 2.0
        ####
        if isfile(confPath):
            exec(open(confPath).read())
        else:
            confNeedsSave = True
        ####
        if not locName:
            confNeedsSave = True
            locName, lat, lng = guessLocation(self.cityData)
            method = 'Tehran'
            ## guess method from location FIXME
        #######
        self.locName = locName
        self.imsak = imsak
        self.backend = PrayTimes(lat, lng, methodName=method, imsak='%d min'%imsak)
        self.shownTimeNames = shownTimeNames
        self.sep = sep
        ####
        self.azanEnable = azanEnable
        self.azanFile = azanFile
        ##
        self.preAzanEnable = preAzanEnable
        self.preAzanFile = preAzanFile
        self.preAzanMinutes = preAzanMinutes
        ##
        self.preAzanMinutes = preAzanMinutes
        #######
        #PrayTimeEventRule.plug = self
        #######
        if confNeedsSave:
            self.saveConfig()
        #######
        self.makeWidget()## FIXME
        self.onCurrentDateChange(localtime()[:3])
        ###
        #self.doPlayPreAzan()
        #time.sleep(2)
        #self.doPlayAzan() ## for testing ## FIXME
    def saveConfig(self):
        text = ''
        text += 'lat=%r\n'%self.backend.lat
        text += 'lng=%r\n'%self.backend.lng
        text += 'method=%r\n'%self.backend.method.name
        for attr in (
            'locName',
            'shownTimeNames',
            'imsak',
            'sep',
            'azanEnable',
            'azanFile',
            'preAzanEnable',
            'preAzanFile',
            'preAzanMinutes',
        ):
            text += '%s=%r\n'%(
                attr,
                getattr(self, attr),
            )
        open(confPath, 'w').write(text)
    #def date_change_after(self, widget, year, month, day):
    #    self.dialog.menuCell.add(self.menuitem)
    #    self.menu_unmap_id = self.dialog.menuCell.connect('unmap', self.menu_unmap)
    #def menu_unmap(self, menu):
    #    menu.remove(self.menuitem)
    #    menu.disconnect(self.menu_unmap_id)
    def get_times_jd(self, jd):
        times = self.backend.getTimesByJd(
            jd,
            getUtcOffsetByJd(jd)/3600.0,
        )
        return [(name, times[name]) for name in self.shownTimeNames]
    def getFormattedTime(self, tm):## tm is float hour
        try:
            h, m, s = floatHourToTime(float(tm))
        except ValueError:
            return tm
        else:
            return '%d:%.2d'%(h, m)
    def get_text_jd(self, jd):
        return self.sep.join([
            '%s: %s'%(_(name.capitalize()), self.getFormattedTime(tm))
            for name, tm in self.get_times_jd(jd)
        ])
    def get_text(self, year, month, day):## just for compatibity (usage by external programs)
        return self.get_text_jd(gregorian_to_jd(year, month, day))
    def update_cell(self, c):
        text = self.get_text_jd(c.jd)
        if text!='':
            if c.pluginsText!='':
                c.pluginsText += '\n'
            c.pluginsText += text
    def killPrevSound(self):
        try:
            p = self.proc
        except AttributeError:
            pass
        else:
            print('killing %s'%p.pid)
            goodkill(p.pid, interval=0.01)
            #kill(p.pid, 15)
            #p.terminate()
    def doPlayAzan(self):## , tm
        if not self.azanEnable:
            return
        #dt = tm - now()
        #print('---------------------------- doPlayAzan, dt=%.1f'%dt)
        #if dt > 1:
        #    Timer(
        #        int(dt),
        #        self.doPlayAzan,
        #        #tm,
        #    ).start()
        #    return
        self.killPrevSound()
        self.proc = popenFile(self.azanFile)
    def doPlayPreAzan(self):## , tm
        if not self.preAzanEnable:
            return
        #dt = tm - now()
        #print('---------------------------- doPlayPreAzan, dt=%.1f'%dt)
        #if dt > 1:
        #    Timer(
        #        int(dt),
        #        self.doPlayPreAzan,
        #        #tm,
        #    ).start()
        #    return
        self.killPrevSound()
        self.proc = popenFile(self.preAzanFile)
    def onCurrentDateChange(self, gdate):
        print 'praytimes: onCurrentDateChange', gdate
        if not self.enable:
            return
        jd = gregorian_to_jd(*tuple(gdate))
        #print(getUtcOffsetByJd(jd)/3600.0, getUtcOffsetCurrent()/3600.0)
        #utcOffset = getUtcOffsetCurrent()
        utcOffset = getUtcOffsetByJd(jd)
        tmUtc = now()
        epochLocal = tmUtc + utcOffset
        secondsFromMidnight = epochLocal % (24*3600)
        midnightUtc = tmUtc - secondsFromMidnight
        #print('------- hours from midnight', secondsFromMidnight/3600.0)
        for timeName, azanHour in self.backend.getTimesByJd(
            jd,
            utcOffset/3600.0,
        ).items():
            if timeName not in self.azanTimeNamesAll:
                continue
            if timeName not in self.shownTimeNames:
                continue
            azanSec = azanHour * 3600.0
            #####
            toAzanSecs = int(azanSec - secondsFromMidnight)
            if toAzanSecs >= 0:
                preAzanSec = azanSec - self.preAzanMinutes * 60
                toPreAzanSec = max(
                    0,
                    int(preAzanSec - secondsFromMidnight)
                )
                print('toPreAzanSec=%.1f'%toPreAzanSec)
                Timer(
                    toPreAzanSec,
                    self.doPlayPreAzan,
                    #midnightUtc + preAzanSec,
                ).start()
                ###
                print('toAzanSecs=%.1f'%toAzanSecs)
                Timer(
                    toAzanSecs,
                    self.doPlayAzan,
                    #midnightUtc + azanSec,
                ).start()
Example #3
0
class TextPlugin(BaseJsonPlugin, TextPluginUI):
	name = "pray_times"
	# all options (except for "enable" and "show_date") will be
	# saved in file confPath
	confPath = join(confDir, "pray_times.json")
	confParams = (
		"lat",
		"lng",
		"method",
		"locName",
		"shownTimeNames",
		"imsak",
		"sep",
		"azanEnable",
		"azanFile",
		"preAzanEnable",
		"preAzanFile",
		"preAzanMinutes",
	)
	azanTimeNamesAll = (
		"fajr",
		"dhuhr",
		"asr",
		"maghrib",
		"isha",
	)

	def __init__(self, _file):
		#print("----------- praytime TextPlugin.__init__")
		#print("From plugin: core.VERSION=%s"%api.get("core", "VERSION"))
		#print("From plugin: core.aaa=%s"%api.get("core", "aaa"))
		BaseJsonPlugin.__init__(
			self,
			_file,
		)
		self.lastDayMerge = False
		self.cityData = readLocationData()
		##############
		confNeedsSave = False
		######
		self.locName, self.lat, self.lng = "", 0, 0
		method = ""
		#######
		self.imsak = 10 ## minutes before Fajr (Morning Azan)
		#self.asrMode=ASR_STANDARD
		#self.highLats="NightMiddle"
		#self.timeFormat="24h"
		self.shownTimeNames = (
			"fajr",
			"sunrise",
			"dhuhr",
			"maghrib",
			"midnight",
		)
		## FIXME rename shownTimeNames to activeTimeNames
		## or add another list azanSoundTimeNames
		self.sep = "     "
		##
		self.azanEnable = False
		self.azanFile = None
		##
		self.preAzanEnable = False
		self.preAzanFile = None
		self.preAzanMinutes = 2.0
		####
		loadModuleJsonConf(self)
		####
		if not isfile(self.confPath):
			confNeedsSave = True
		####
		if not self.locName:
			confNeedsSave = True
			self.locName, self.lat, self.lng = guessLocation(self.cityData)
			self.method = "Tehran"
			## guess method from location FIXME
		#######
		self.backend = PrayTimes(
			self.lat,
			self.lng,
			methodName=self.method,
			imsak="%d min" % self.imsak,
		)
		####
		#######
		#PrayTimeEventRule.plug = self
		#######
		if confNeedsSave:
			self.saveConfig()
		#######
		self.makeWidget()## FIXME
		#self.onCurrentDateChange(localtime()[:3])
		###
		#self.doPlayPreAzan()
		#time.sleep(2)
		#self.doPlayAzan() ## for testing ## FIXME

	def saveConfig(self):
		self.lat = self.backend.lat
		self.lng = self.backend.lng
		self.method = self.backend.method.name
		saveModuleJsonConf(self)

	#def date_change_after(self, widget, year, month, day):
	#	self.dialog.menuCell.add(self.menuitem)
	#	self.menu_unmap_id = self.dialog.menuCell.connect("unmap", self.menu_unmap)

	#def menu_unmap(self, menu):
	#	menu.remove(self.menuitem)
	#	menu.disconnect(self.menu_unmap_id)

	def get_times_jd(self, jd):
		times = self.backend.getTimesByJd(
			jd,
			getUtcOffsetByJd(jd, localTz) / 3600,
		)
		return [
			(name, times[name])
			for name in self.shownTimeNames
		]

	def getFormattedTime(self, tm):## tm is float hour
		try:
			h, m, s = floatHourToTime(float(tm))
		except ValueError:
			return tm
		else:
			return "%d:%.2d" % (h, m)

	def getTextByJd(self, jd):
		return self.sep.join([
			"%s: %s" % (
				_(name.capitalize()),
				self.getFormattedTime(tm),
			)
			for name, tm in self.get_times_jd(jd)
		])

	def updateCell(self, c):
		text = self.getTextByJd(c.jd)
		if text != "":
			if c.pluginsText != "":
				c.pluginsText += "\n"
			c.pluginsText += text

	def killPrevSound(self):
		try:
			p = self.proc
		except AttributeError:
			pass
		else:
			print("killing %s" % p.pid)
			goodkill(p.pid, interval=0.01)
			#kill(p.pid, 15)
			#p.terminate()

	def doPlayAzan(self):## , tm
		if not self.azanEnable:
			return
		#dt = tm - now()
		#print("---------------------------- doPlayAzan, dt=%.1f"%dt)
		#if dt > 1:
		#	Timer(
		#		int(dt),
		#		self.doPlayAzan,
		#		#tm,
		#	).start()
		#	return
		self.killPrevSound()
		self.proc = popenFile(self.azanFile)

	def doPlayPreAzan(self):## , tm
		if not self.preAzanEnable:
			return
		#dt = tm - now()
		#print("---------------------------- doPlayPreAzan, dt=%.1f"%dt)
		#if dt > 1:
		#	Timer(
		#		int(dt),
		#		self.doPlayPreAzan,
		#		#tm,
		#	).start()
		#	return
		self.killPrevSound()
		self.proc = popenFile(self.preAzanFile)

	def onCurrentDateChange(self, gdate):
		print("praytimes: onCurrentDateChange", gdate)
		if not self.enable:
			return
		jd = gregorian_to_jd(*tuple(gdate))
		#print(
		#	getUtcOffsetByJd(jd, localTz) / 3600,
		#	getUtcOffsetCurrent() / 3600,
		#)
		#utcOffset = getUtcOffsetCurrent()
		utcOffset = getUtcOffsetByJd(jd, localTz)
		tmUtc = now()
		epochLocal = tmUtc + utcOffset
		secondsFromMidnight = epochLocal % (24 * 3600)
		midnightUtc = tmUtc - secondsFromMidnight
		#print("------- hours from midnight", secondsFromMidnight/3600.0)
		for timeName, azanHour in self.backend.getTimesByJd(
			jd,
			utcOffset / 3600,
		).items():
			if timeName not in self.azanTimeNamesAll:
				continue
			if timeName not in self.shownTimeNames:
				continue
			azanSec = azanHour * 3600.0
			#####
			toAzanSecs = int(azanSec - secondsFromMidnight)
			if toAzanSecs >= 0:
				preAzanSec = azanSec - self.preAzanMinutes * 60
				toPreAzanSec = max(
					0,
					int(preAzanSec - secondsFromMidnight)
				)
				print("toPreAzanSec=%.1f" % toPreAzanSec)
				Timer(
					toPreAzanSec,
					self.doPlayPreAzan,
					#midnightUtc + preAzanSec,
				).start()
				###
				print("toAzanSecs=%.1f" % toAzanSecs)
				Timer(
					toAzanSecs,
					self.doPlayAzan,
					#midnightUtc + azanSec,
				).start()
Example #4
0
class TextPlugin(BaseJsonPlugin, TextPluginUI):
    name = 'pray_times'
    ## all options (except for "enable" and "show_date") will be saved in file confPath
    confPath = join(confDir, 'pray_times.json')
    confParams = (
        'lat',
        'lng',
        'method',
        'locName',
        'shownTimeNames',
        'imsak',
        'sep',
        'azanEnable',
        'azanFile',
        'preAzanEnable',
        'preAzanFile',
        'preAzanMinutes',
    )
    azanTimeNamesAll = (
        'fajr',
        'dhuhr',
        'asr',
        'maghrib',
        'isha',
    )

    def __init__(self, _file):
        #print('----------- praytime TextPlugin.__init__')
        #print('From plugin: core.VERSION=%s'%api.get('core', 'VERSION'))
        #print('From plugin: core.aaa=%s'%api.get('core', 'aaa'))
        BaseJsonPlugin.__init__(
            self,
            _file,
        )
        self.lastDayMerge = False
        self.cityData = readLocationData()
        ##############
        confNeedsSave = False
        ######
        self.locName, self.lat, self.lng = '', 0, 0
        method = ''
        #######
        self.imsak = 10  ## minutes before Fajr (Morning Azan)
        #self.asrMode=ASR_STANDARD
        #self.highLats='NightMiddle'
        #self.timeFormat='24h'
        self.shownTimeNames = (
            'fajr',
            'sunrise',
            'dhuhr',
            'maghrib',
            'midnight',
        )
        ## FIXME rename shownTimeNames to activeTimeNames
        ## or add another list azanSoundTimeNames
        self.sep = '     '
        ##
        self.azanEnable = False
        self.azanFile = None
        ##
        self.preAzanEnable = False
        self.preAzanFile = None
        self.preAzanMinutes = 2.0
        ####
        loadModuleJsonConf(self)
        ####
        if not isfile(self.confPath):
            confNeedsSave = True
        ####
        if not self.locName:
            confNeedsSave = True
            self.locName, self.lat, self.lng = guessLocation(self.cityData)
            self.method = 'Tehran'
            ## guess method from location FIXME
        #######
        self.backend = PrayTimes(
            self.lat,
            self.lng,
            methodName=self.method,
            imsak='%d min' % self.imsak,
        )
        ####
        #######
        #PrayTimeEventRule.plug = self
        #######
        if confNeedsSave:
            self.saveConfig()
        #######
        self.makeWidget()  ## FIXME
        #self.onCurrentDateChange(localtime()[:3])
        ###
        #self.doPlayPreAzan()
        #time.sleep(2)
        #self.doPlayAzan() ## for testing ## FIXME
    def saveConfig(self):
        self.lat = self.backend.lat
        self.lng = self.backend.lng
        self.method = self.backend.method.name
        saveModuleJsonConf(self)

    #def date_change_after(self, widget, year, month, day):
    #    self.dialog.menuCell.add(self.menuitem)
    #    self.menu_unmap_id = self.dialog.menuCell.connect('unmap', self.menu_unmap)
    #def menu_unmap(self, menu):
    #    menu.remove(self.menuitem)
    #    menu.disconnect(self.menu_unmap_id)
    def get_times_jd(self, jd):
        times = self.backend.getTimesByJd(
            jd,
            getUtcOffsetByJd(jd) / 3600.0,
        )
        return [(name, times[name]) for name in self.shownTimeNames]

    def getFormattedTime(self, tm):  ## tm is float hour
        try:
            h, m, s = floatHourToTime(float(tm))
        except ValueError:
            return tm
        else:
            return '%d:%.2d' % (h, m)

    def get_text_jd(self, jd):
        return self.sep.join([
            '%s: %s' % (_(name.capitalize()), self.getFormattedTime(tm))
            for name, tm in self.get_times_jd(jd)
        ])

    def get_text(self, year, month,
                 day):  ## just for compatibity (usage by external programs)
        return self.get_text_jd(gregorian_to_jd(year, month, day))

    def update_cell(self, c):
        text = self.get_text_jd(c.jd)
        if text != '':
            if c.pluginsText != '':
                c.pluginsText += '\n'
            c.pluginsText += text

    def killPrevSound(self):
        try:
            p = self.proc
        except AttributeError:
            pass
        else:
            print('killing %s' % p.pid)
            goodkill(p.pid, interval=0.01)
            #kill(p.pid, 15)
            #p.terminate()
    def doPlayAzan(self):  ## , tm
        if not self.azanEnable:
            return
        #dt = tm - now()
        #print('---------------------------- doPlayAzan, dt=%.1f'%dt)
        #if dt > 1:
        #    Timer(
        #        int(dt),
        #        self.doPlayAzan,
        #        #tm,
        #    ).start()
        #    return
        self.killPrevSound()
        self.proc = popenFile(self.azanFile)

    def doPlayPreAzan(self):  ## , tm
        if not self.preAzanEnable:
            return
        #dt = tm - now()
        #print('---------------------------- doPlayPreAzan, dt=%.1f'%dt)
        #if dt > 1:
        #    Timer(
        #        int(dt),
        #        self.doPlayPreAzan,
        #        #tm,
        #    ).start()
        #    return
        self.killPrevSound()
        self.proc = popenFile(self.preAzanFile)

    def onCurrentDateChange(self, gdate):
        print('praytimes: onCurrentDateChange', gdate)
        if not self.enable:
            return
        jd = gregorian_to_jd(*tuple(gdate))
        #print(getUtcOffsetByJd(jd)/3600.0, getUtcOffsetCurrent()/3600.0)
        #utcOffset = getUtcOffsetCurrent()
        utcOffset = getUtcOffsetByJd(jd)
        tmUtc = now()
        epochLocal = tmUtc + utcOffset
        secondsFromMidnight = epochLocal % (24 * 3600)
        midnightUtc = tmUtc - secondsFromMidnight
        #print('------- hours from midnight', secondsFromMidnight/3600.0)
        for timeName, azanHour in self.backend.getTimesByJd(
                jd,
                utcOffset / 3600.0,
        ).items():
            if timeName not in self.azanTimeNamesAll:
                continue
            if timeName not in self.shownTimeNames:
                continue
            azanSec = azanHour * 3600.0
            #####
            toAzanSecs = int(azanSec - secondsFromMidnight)
            if toAzanSecs >= 0:
                preAzanSec = azanSec - self.preAzanMinutes * 60
                toPreAzanSec = max(0, int(preAzanSec - secondsFromMidnight))
                print('toPreAzanSec=%.1f' % toPreAzanSec)
                Timer(
                    toPreAzanSec,
                    self.doPlayPreAzan,
                    #midnightUtc + preAzanSec,
                ).start()
                ###
                print('toAzanSecs=%.1f' % toAzanSecs)
                Timer(
                    toAzanSecs,
                    self.doPlayAzan,
                    #midnightUtc + azanSec,
                ).start()
Example #5
0
class TextPlugin(BaseJsonPlugin, TextPluginUI):
    name = "pray_times"
    # all options (except for "enable" and "show_date") will be
    # saved in file confPath
    confPath = join(confDir, "pray_times.json")
    confParams = (
        "lat",
        "lng",
        "method",
        "locName",
        "shownTimeNames",
        "imsak",
        "sep",
        "azanEnable",
        "azanFile",
        "preAzanEnable",
        "preAzanFile",
        "preAzanMinutes",
    )
    azanTimeNamesAll = (
        "fajr",
        "dhuhr",
        "asr",
        "maghrib",
        "isha",
    )

    def __init__(self, _file):
        #print("----------- praytime TextPlugin.__init__")
        #print("From plugin: core.VERSION=%s"%api.get("core", "VERSION"))
        #print("From plugin: core.aaa=%s"%api.get("core", "aaa"))
        BaseJsonPlugin.__init__(
            self,
            _file,
        )
        self.lastDayMerge = False
        self.cityData = readLocationData()
        ##############
        confNeedsSave = False
        ######
        self.locName, self.lat, self.lng = "", 0, 0
        method = ""
        #######
        self.imsak = 10  ## minutes before Fajr (Morning Azan)
        #self.asrMode=ASR_STANDARD
        #self.highLats="NightMiddle"
        #self.timeFormat="24h"
        self.shownTimeNames = (
            "fajr",
            "sunrise",
            "dhuhr",
            "maghrib",
            "midnight",
        )
        ## FIXME rename shownTimeNames to activeTimeNames
        ## or add another list azanSoundTimeNames
        self.sep = "     "
        ##
        self.azanEnable = False
        self.azanFile = None
        ##
        self.preAzanEnable = False
        self.preAzanFile = None
        self.preAzanMinutes = 2.0
        ####
        loadModuleJsonConf(self)
        ####
        if not isfile(self.confPath):
            confNeedsSave = True
        ####
        if not self.locName:
            confNeedsSave = True
            self.locName, self.lat, self.lng = guessLocation(self.cityData)
            self.method = "Tehran"
            ## guess method from location FIXME
        #######
        self.backend = PrayTimes(
            self.lat,
            self.lng,
            methodName=self.method,
            imsak="%d min" % self.imsak,
        )
        ####
        #######
        #PrayTimeEventRule.plug = self
        #######
        if confNeedsSave:
            self.saveConfig()
        #######
        self.makeWidget()  ## FIXME
        #self.onCurrentDateChange(localtime()[:3])
        ###
        #self.doPlayPreAzan()
        #time.sleep(2)
        #self.doPlayAzan() ## for testing ## FIXME

    def saveConfig(self):
        self.lat = self.backend.lat
        self.lng = self.backend.lng
        self.method = self.backend.method.name
        saveModuleJsonConf(self)

    #def date_change_after(self, widget, year, month, day):
    #	self.dialog.menuCell.add(self.menuitem)
    #	self.menu_unmap_id = self.dialog.menuCell.connect("unmap", self.menu_unmap)

    #def menu_unmap(self, menu):
    #	menu.remove(self.menuitem)
    #	menu.disconnect(self.menu_unmap_id)

    def get_times_jd(self, jd):
        times = self.backend.getTimesByJd(
            jd,
            getUtcOffsetByJd(jd, localTz) / 3600,
        )
        return [(name, times[name]) for name in self.shownTimeNames]

    def getFormattedTime(self, tm):  ## tm is float hour
        try:
            h, m, s = floatHourToTime(float(tm))
        except ValueError:
            return tm
        else:
            return "%d:%.2d" % (h, m)

    def getTextByJd(self, jd):
        return self.sep.join([
            "%s: %s" % (
                _(name.capitalize()),
                self.getFormattedTime(tm),
            ) for name, tm in self.get_times_jd(jd)
        ])

    def updateCell(self, c):
        text = self.getTextByJd(c.jd)
        if text != "":
            if c.pluginsText != "":
                c.pluginsText += "\n"
            c.pluginsText += text

    def killPrevSound(self):
        try:
            p = self.proc
        except AttributeError:
            pass
        else:
            print("killing %s" % p.pid)
            goodkill(p.pid, interval=0.01)
            #kill(p.pid, 15)
            #p.terminate()

    def doPlayAzan(self):  ## , tm
        if not self.azanEnable:
            return
        #dt = tm - now()
        #print("---------------------------- doPlayAzan, dt=%.1f"%dt)
        #if dt > 1:
        #	Timer(
        #		int(dt),
        #		self.doPlayAzan,
        #		#tm,
        #	).start()
        #	return
        self.killPrevSound()
        self.proc = popenFile(self.azanFile)

    def doPlayPreAzan(self):  ## , tm
        if not self.preAzanEnable:
            return
        #dt = tm - now()
        #print("---------------------------- doPlayPreAzan, dt=%.1f"%dt)
        #if dt > 1:
        #	Timer(
        #		int(dt),
        #		self.doPlayPreAzan,
        #		#tm,
        #	).start()
        #	return
        self.killPrevSound()
        self.proc = popenFile(self.preAzanFile)

    def onCurrentDateChange(self, gdate):
        print("praytimes: onCurrentDateChange", gdate)
        if not self.enable:
            return
        jd = gregorian_to_jd(*tuple(gdate))
        #print(
        #	getUtcOffsetByJd(jd, localTz) / 3600,
        #	getUtcOffsetCurrent() / 3600,
        #)
        #utcOffset = getUtcOffsetCurrent()
        utcOffset = getUtcOffsetByJd(jd, localTz)
        tmUtc = now()
        epochLocal = tmUtc + utcOffset
        secondsFromMidnight = epochLocal % (24 * 3600)
        midnightUtc = tmUtc - secondsFromMidnight
        #print("------- hours from midnight", secondsFromMidnight/3600.0)
        for timeName, azanHour in self.backend.getTimesByJd(
                jd,
                utcOffset / 3600,
        ).items():
            if timeName not in self.azanTimeNamesAll:
                continue
            if timeName not in self.shownTimeNames:
                continue
            azanSec = azanHour * 3600.0
            #####
            toAzanSecs = int(azanSec - secondsFromMidnight)
            if toAzanSecs >= 0:
                preAzanSec = azanSec - self.preAzanMinutes * 60
                toPreAzanSec = max(0, int(preAzanSec - secondsFromMidnight))
                print("toPreAzanSec=%.1f" % toPreAzanSec)
                Timer(
                    toPreAzanSec,
                    self.doPlayPreAzan,
                    #midnightUtc + preAzanSec,
                ).start()
                ###
                print("toAzanSecs=%.1f" % toAzanSecs)
                Timer(
                    toAzanSecs,
                    self.doPlayAzan,
                    #midnightUtc + azanSec,
                ).start()