import wx
import json
from time import strptime
from pytz import timezone, utc
from datetime import datetime
from panchanga import *
import difflib
format_time = lambda t: "%02d:%02d:%02d" % (t[0], t[1], t[2])
class Panchanga(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.dateTxt = wx.TextCtrl(self, wx.ID_ANY, "23/01/2013")
self.searchBtn = wx.Button(self, wx.ID_ANY, "Search")
self.placeTxt = wx.TextCtrl(self, wx.ID_ANY, "Bangalore")
self.computeBtn = wx.Button(self, wx.ID_ANY, "Compute")
self.latTxt = wx.TextCtrl(self, wx.ID_ANY, "12.97194", style=wx.TE_PROCESS_TAB)
self.lonTxt = wx.TextCtrl(self, wx.ID_ANY, "77.59369", style=wx.TE_PROCESS_TAB)
self.tzTxt = wx.TextCtrl(self, wx.ID_ANY, "+5.5")
self.samvatTxt = wx.StaticText(self, wx.ID_ANY, "Nandana samvatsara")
self.masaTxt = wx.StaticText(self, wx.ID_ANY, u"Pu\u1e63ya m\u0101sa")
self.rituTxt = wx.StaticText(self, wx.ID_ANY, u"Hemanta \u1e5btu")
self.tithiTxt = wx.StaticText(self, wx.ID_ANY, u"\u015aukla pak\u1e63a dv\u0101da\u1e63\u012b ")
self.tithiTimeTxt = wx.StaticText(self, wx.ID_ANY, "28:43:28")
self.nakTxt = wx.StaticText(self, wx.ID_ANY, u"Rohi\u1e47\u012b")
self.nakTimeTxt = wx.StaticText(self, wx.ID_ANY, "06:57:56")
self.yogaTxt = wx.StaticText(self, wx.ID_ANY, "Brahma")
self.yogaTimeTxt = wx.StaticText(self, wx.ID_ANY, "08:32:02")
self.karanaTxt = wx.StaticText(self, wx.ID_ANY, "Bhava")
self.karanaTimeTxt = wx.StaticText(self, wx.ID_ANY, "15:27:47")
self.varaTxt = wx.StaticText(self, wx.ID_ANY, u"Budhav\u0101ra ")
self.aharTxt = wx.StaticText(self, wx.ID_ANY, "KaliDay 1867850")
self.sakaTxt = wx.StaticText(self, wx.ID_ANY, u"\u015a\u0101liv\u0101hana \u015baka 1934 ")
self.kaliTxt = wx.StaticText(self, wx.ID_ANY, "GataKali 5113")
self.sunriseTxt = wx.StaticText(self, wx.ID_ANY, "06:47:38")
self.sunsetTxt = wx.StaticText(self, wx.ID_ANY, "18:15:31")
self.duraTxt = wx.StaticText(self, wx.ID_ANY, "11:27:52")
self.sizer_1_staticbox = wx.StaticBox(self, wx.ID_ANY, "")
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_TEXT_ENTER, self.calculate_panchanga, self.dateTxt)
self.Bind(wx.EVT_BUTTON, self.search_location, self.searchBtn)
self.Bind(wx.EVT_TEXT_ENTER, self.search_location, self.placeTxt)
self.Bind(wx.EVT_BUTTON, self.calculate_panchanga, self.computeBtn)
self.Bind(wx.EVT_TEXT_ENTER, self.set_place, self.latTxt)
self.Bind(wx.EVT_TEXT, self.set_place, self.latTxt)
self.Bind(wx.EVT_TEXT_ENTER, self.set_place, self.lonTxt)
self.Bind(wx.EVT_TEXT, self.set_place, self.lonTxt)
self.Bind(wx.EVT_TEXT_ENTER, self.set_place, self.tzTxt)
self.Bind(wx.EVT_TEXT, self.set_place, self.tzTxt)
now = datetime.now()
self.dateTxt.SetValue("%d/%d/%d" % (now.day, now.month, now.year))
self.init_db()
def __set_properties(self):
self.SetTitle("Indian Calendar")
self.SetSize((625, 575))
self.SetToolTipString("Can also be entered as: 77d 35' 37\"")
self.dateTxt.SetToolTipString("Enter date and then Location below. Negative years are treated as per proleptic Gregorian calendar.")
self.dateTxt.SetFocus()
self.searchBtn.SetForegroundColour(wx.Colour(44, 44, 44))
self.placeTxt.SetToolTipString("Type location, click Search. If the search fails, enter Latitude, Longitude and Time zone directly below. Lastly, \"Compute\". Enter ASCII names only.")
self.latTxt.SetToolTipString("Can also be entered as: 12d 58' 19\"")
self.tzTxt.SetToolTipString("In hours. Positive values are east of UTC and negative, west of UTC.")
def __do_layout(self):
self.sizer_1_staticbox.Lower()
sizer_1 = wx.StaticBoxSizer(self.sizer_1_staticbox, wx.HORIZONTAL)
grid_sizer_1 = wx.GridSizer(16, 3, 0, 0)
label_1 = wx.StaticText(self, wx.ID_ANY, "")
grid_sizer_1.Add(label_1, 0, 0, 0)
label_2 = wx.StaticText(self, wx.ID_ANY, u"D\u1e5bg-ga\u1e47ita Pa\xf1c\u0101\u1e45ga", style=wx.ALIGN_RIGHT | wx.ALIGN_CENTRE)
label_2.SetMinSize((319, 24))
label_2.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
grid_sizer_1.Add(label_2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_4 = wx.StaticText(self, wx.ID_ANY, "")
grid_sizer_1.Add(label_4, 0, 0, 0)
label_3 = wx.StaticText(self, wx.ID_ANY, "Date (DD/MM/YYYY)")
grid_sizer_1.Add(label_3, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.dateTxt, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.searchBtn, 0, 0, 0)
label_6 = wx.StaticText(self, wx.ID_ANY, "Location")
grid_sizer_1.Add(label_6, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.placeTxt, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.computeBtn, 0, 0, 0)
label_31 = wx.StaticText(self, wx.ID_ANY, "Latitude")
grid_sizer_1.Add(label_31, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 0)
label_32 = wx.StaticText(self, wx.ID_ANY, "Longitude")
grid_sizer_1.Add(label_32, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
label_33 = wx.StaticText(self, wx.ID_ANY, "Time zone")
grid_sizer_1.Add(label_33, 0, wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.latTxt, 0, wx.RIGHT | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.lonTxt, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.tzTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
static_line_1 = wx.StaticLine(self, wx.ID_ANY)
grid_sizer_1.Add(static_line_1, 0, wx.EXPAND, 0)
static_line_2 = wx.StaticLine(self, wx.ID_ANY)
grid_sizer_1.Add(static_line_2, 0, wx.EXPAND, 0)
static_line_3 = wx.StaticLine(self, wx.ID_ANY)
grid_sizer_1.Add(static_line_3, 0, wx.EXPAND, 0)
grid_sizer_1.Add(self.samvatTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.masaTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.rituTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_7 = wx.StaticText(self, wx.ID_ANY, "Tithi")
grid_sizer_1.Add(label_7, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.tithiTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.tithiTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_13 = wx.StaticText(self, wx.ID_ANY, u"Nak\u1e63atra ")
grid_sizer_1.Add(label_13, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.nakTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.nakTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_16 = wx.StaticText(self, wx.ID_ANY, "Yoga")
grid_sizer_1.Add(label_16, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.yogaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.yogaTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_19 = wx.StaticText(self, wx.ID_ANY, u"Kara\u1e47a ")
grid_sizer_1.Add(label_19, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.karanaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.karanaTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_22 = wx.StaticText(self, wx.ID_ANY, u"V\u0101ra ")
grid_sizer_1.Add(label_22, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.varaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
label_24 = wx.StaticText(self, wx.ID_ANY, "")
grid_sizer_1.Add(label_24, 0, 0, 0)
grid_sizer_1.Add(self.aharTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.sakaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.kaliTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
static_line_4 = wx.StaticLine(self, wx.ID_ANY)
grid_sizer_1.Add(static_line_4, 0, wx.EXPAND, 0)
static_line_5 = wx.StaticLine(self, wx.ID_ANY)
grid_sizer_1.Add(static_line_5, 0, wx.EXPAND, 0)
static_line_6 = wx.StaticLine(self, wx.ID_ANY)
grid_sizer_1.Add(static_line_6, 0, wx.EXPAND, 0)
label_34 = wx.StaticText(self, wx.ID_ANY, "Sunrise")
grid_sizer_1.Add(label_34, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
label_37 = wx.StaticText(self, wx.ID_ANY, "Sunset")
grid_sizer_1.Add(label_37, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
label_5 = wx.StaticText(self, wx.ID_ANY, "Day duration")
grid_sizer_1.Add(label_5, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.sunriseTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.sunsetTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
grid_sizer_1.Add(self.duraTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
label_10 = wx.StaticText(self, wx.ID_ANY, "")
grid_sizer_1.Add(label_10, 0, 0, 0)
label_9 = wx.StaticText(self, wx.ID_ANY, "https://github.com/bdsatish/drik-panchanga")
grid_sizer_1.Add(label_9, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
sizer_1.Add(grid_sizer_1, 1, 0, 0)
self.SetSizer(sizer_1)
self.Layout()
def calculate_panchanga(self, event):
jd = gregorian_to_jd(self.parse_date())
self.set_place(event)
place = self.place
ti = tithi(jd, place)
nak = nakshatra(jd, place)
yog = yoga(jd, place)
mas = masa(jd, place)
rtu = ritu(mas[0])
kar = karana(jd, place)
vara = vaara(jd)
srise = sunrise(jd, place)[1]
sset = sunset(jd, place)[1]
kday = ahargana(jd)
kyear, sakayr = elapsed_year(jd, mas[0])
samvat = samvatsara(jd, mas[0])
day_dur = day_duration(jd, place)[1]
self.karanaTxt.SetLabel("%s" % self.karanas[str(kar[0])])
self.karanaTimeTxt.SetLabel(" -- ")
self.varaTxt.SetLabel("%s" % self.vaaras[str(vara)])
self.sunriseTxt.SetLabel(format_time(srise))
self.sunsetTxt.SetLabel(format_time(sset))
self.sakaTxt.SetLabel(u"Śālivāhana śaka %d" % (sakayr))
self.kaliTxt.SetLabel("GataKali %d" % (kyear))
self.aharTxt.SetLabel("KaliDay %d" % (kday))
self.rituTxt.SetLabel(u"%s ṛtu" % (self.ritus[str(rtu)]))
self.samvatTxt.SetLabel("%s samvatsara" % (self.samvats[str(samvat)]))
self.duraTxt.SetLabel(format_time(day_dur))
month_name = self.masas[str(mas[0])]
is_leap = mas[1]
if is_leap: month_name = "Adhika " + month_name.lower()
self.masaTxt.SetLabel(month_name + u" māsa")
name, hms = format_name_hms(yog, self.yogas)
self.yogaTxt.SetLabel(name)
self.yogaTimeTxt.SetLabel(hms)
name, hms = format_name_hms(ti, self.tithis)
self.tithiTxt.SetLabel(name)
self.tithiTimeTxt.SetLabel(hms)
name, hms = format_name_hms(nak, self.nakshatras)
self.nakTxt.SetLabel(name)
self.nakTimeTxt.SetLabel(hms)
event.Skip()
def search_location(self, event):
city = self.placeTxt.Value.title()
if self.cities.has_key(city):
self.searchBtn.SetForegroundColour(wx.Colour(0x2C, 0x2C, 0x2C))
date = self.parse_date()
city = self.cities[city]
lat = city['latitude']
lon = city['longitude']
tzname = city['timezone']
self.tzone = timezone(tzname)
tz_offset = self.compute_timezone_offset()
self.place = Place(lat, lon, tz_offset)
self.latTxt.SetValue("%.5f" % lat)
self.lonTxt.SetValue("%.5f" % lon)
self.tzTxt.SetValue("%+.2f" % tz_offset)
else:
nearest = difflib.get_close_matches(city, self.all_cities, 5)
all_matches = ""
for m in nearest:
all_matches += m + '\n'
msg = city + ' not found!\n\n' + 'Did you mean any of these?\n\n' + all_matches
wx.MessageBox(msg, 'Error', wx.OK | wx.ICON_ERROR)
event.Skip()
def parse_date(self):
date = self.dateTxt.Value
try:
dt = strptime(date, "%d/%m/%Y")
date = Date(dt.tm_year, dt.tm_mon, dt.tm_mday)
except ValueError:
day, month, year = map(int, date.split('/'))
date = Date(year, month, day)
return date
def init_db(self):
fp = open("cities.json")
self.cities = json.load(fp)
self.all_cities = self.cities.keys()
fp.close()
fp = open("sanskrit_names.json")
sktnames = json.load(fp)
fp.close()
self.tithis = sktnames["tithis"]
self.nakshatras = sktnames["nakshatras"]
self.vaaras = sktnames["varas"]
self.yogas = sktnames["yogas"]
self.karanas = sktnames["karanas"]
self.masas = sktnames["masas"]
self.samvats = sktnames["samvats"]
self.ritus = sktnames["ritus"]
def set_place(self, event):
lat = float(self.latTxt.Value)
lon = float(self.lonTxt.Value)
tz = float(self.tzTxt.Value)
self.place = Place(lat, lon, tz)
event.Skip()
def compute_timezone_offset(self):
date = self.parse_date()
timezone = self.tzone
dt = datetime(date.year, date.month, date.day)
tz_offset = timezone.utcoffset(dt, is_dst = True).total_seconds() / 3600.
return tz_offset
def format_name_hms(nhms, lookup):
name_txt = lookup[str(nhms[0])]
time_txt = format_time(nhms[1])
if len(nhms) == 4:
name_txt += "\n" + lookup[str(nhms[2])]
time_txt += "\n" + format_time(nhms[3])
return name_txt, time_txt
if __name__ == "__main__":
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frame_1 = Panchanga(None, -1, "")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()