Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
webresh
GitHub Repository: webresh/drik-panchanga
Path: blob/master/gui.py
983 views
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
# generated by wxGlade 0.6.4 on Tue Jan 22 15:06:05 2013
4
5
# gui.py -- Displays a wxPython GUI for panchangam calculations
6
#
7
# Copyright (C) 2013 Satish BD <[email protected]>
8
# Downloaded from https://github.com/bdsatish/drik-panchanga
9
#
10
# This file is part of the "drik-panchanga" Python library
11
# for computing Hindu luni-solar calendar based on the Swiss ephemeris
12
#
13
# This program is free software: you can redistribute it and/or modify
14
# it under the terms of the GNU Affero General Public License as published by
15
# the Free Software Foundation, either version 3 of the License, or
16
# (at your option) any later version.
17
#
18
# This program is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
# GNU Affero General Public License for more details.
22
#
23
# You should have received a copy of the GNU Affero General Public License
24
# along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26
import wx
27
import json
28
29
from time import strptime
30
from pytz import timezone, utc
31
from datetime import datetime
32
from panchanga import *
33
import difflib
34
35
# begin wxGlade: extracode
36
# end wxGlade
37
38
format_time = lambda t: "%02d:%02d:%02d" % (t[0], t[1], t[2])
39
40
class Panchanga(wx.Frame):
41
def __init__(self, *args, **kwds):
42
# begin wxGlade: Panchanga.__init__
43
kwds["style"] = wx.DEFAULT_FRAME_STYLE
44
wx.Frame.__init__(self, *args, **kwds)
45
self.dateTxt = wx.TextCtrl(self, wx.ID_ANY, "23/01/2013")
46
self.searchBtn = wx.Button(self, wx.ID_ANY, "Search")
47
self.placeTxt = wx.TextCtrl(self, wx.ID_ANY, "Bangalore")
48
self.computeBtn = wx.Button(self, wx.ID_ANY, "Compute")
49
self.latTxt = wx.TextCtrl(self, wx.ID_ANY, "12.97194", style=wx.TE_PROCESS_TAB)
50
self.lonTxt = wx.TextCtrl(self, wx.ID_ANY, "77.59369", style=wx.TE_PROCESS_TAB)
51
self.tzTxt = wx.TextCtrl(self, wx.ID_ANY, "+5.5")
52
self.samvatTxt = wx.StaticText(self, wx.ID_ANY, "Nandana samvatsara")
53
self.masaTxt = wx.StaticText(self, wx.ID_ANY, u"Pu\u1e63ya m\u0101sa")
54
self.rituTxt = wx.StaticText(self, wx.ID_ANY, u"Hemanta \u1e5btu")
55
self.tithiTxt = wx.StaticText(self, wx.ID_ANY, u"\u015aukla pak\u1e63a dv\u0101da\u1e63\u012b ")
56
self.tithiTimeTxt = wx.StaticText(self, wx.ID_ANY, "28:43:28")
57
self.nakTxt = wx.StaticText(self, wx.ID_ANY, u"Rohi\u1e47\u012b")
58
self.nakTimeTxt = wx.StaticText(self, wx.ID_ANY, "06:57:56")
59
self.yogaTxt = wx.StaticText(self, wx.ID_ANY, "Brahma")
60
self.yogaTimeTxt = wx.StaticText(self, wx.ID_ANY, "08:32:02")
61
self.karanaTxt = wx.StaticText(self, wx.ID_ANY, "Bhava")
62
self.karanaTimeTxt = wx.StaticText(self, wx.ID_ANY, "15:27:47")
63
self.varaTxt = wx.StaticText(self, wx.ID_ANY, u"Budhav\u0101ra ")
64
self.aharTxt = wx.StaticText(self, wx.ID_ANY, "KaliDay 1867850")
65
self.sakaTxt = wx.StaticText(self, wx.ID_ANY, u"\u015a\u0101liv\u0101hana \u015baka 1934 ")
66
self.kaliTxt = wx.StaticText(self, wx.ID_ANY, "GataKali 5113")
67
self.sunriseTxt = wx.StaticText(self, wx.ID_ANY, "06:47:38")
68
self.sunsetTxt = wx.StaticText(self, wx.ID_ANY, "18:15:31")
69
self.duraTxt = wx.StaticText(self, wx.ID_ANY, "11:27:52")
70
self.sizer_1_staticbox = wx.StaticBox(self, wx.ID_ANY, "")
71
72
self.__set_properties()
73
self.__do_layout()
74
75
self.Bind(wx.EVT_TEXT_ENTER, self.calculate_panchanga, self.dateTxt)
76
self.Bind(wx.EVT_BUTTON, self.search_location, self.searchBtn)
77
self.Bind(wx.EVT_TEXT_ENTER, self.search_location, self.placeTxt)
78
self.Bind(wx.EVT_BUTTON, self.calculate_panchanga, self.computeBtn)
79
self.Bind(wx.EVT_TEXT_ENTER, self.set_place, self.latTxt)
80
self.Bind(wx.EVT_TEXT, self.set_place, self.latTxt)
81
self.Bind(wx.EVT_TEXT_ENTER, self.set_place, self.lonTxt)
82
self.Bind(wx.EVT_TEXT, self.set_place, self.lonTxt)
83
self.Bind(wx.EVT_TEXT_ENTER, self.set_place, self.tzTxt)
84
self.Bind(wx.EVT_TEXT, self.set_place, self.tzTxt)
85
# end wxGlade
86
87
now = datetime.now()
88
self.dateTxt.SetValue("%d/%d/%d" % (now.day, now.month, now.year))
89
self.init_db()
90
91
def __set_properties(self):
92
# begin wxGlade: Panchanga.__set_properties
93
self.SetTitle("Indian Calendar")
94
self.SetSize((625, 575))
95
self.SetToolTipString("Can also be entered as: 77d 35' 37\"")
96
self.dateTxt.SetToolTipString("Enter date and then Location below. Negative years are treated as per proleptic Gregorian calendar.")
97
self.dateTxt.SetFocus()
98
self.searchBtn.SetForegroundColour(wx.Colour(44, 44, 44))
99
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.")
100
self.latTxt.SetToolTipString("Can also be entered as: 12d 58' 19\"")
101
self.tzTxt.SetToolTipString("In hours. Positive values are east of UTC and negative, west of UTC.")
102
# end wxGlade
103
104
def __do_layout(self):
105
# begin wxGlade: Panchanga.__do_layout
106
self.sizer_1_staticbox.Lower()
107
sizer_1 = wx.StaticBoxSizer(self.sizer_1_staticbox, wx.HORIZONTAL)
108
grid_sizer_1 = wx.GridSizer(16, 3, 0, 0)
109
label_1 = wx.StaticText(self, wx.ID_ANY, "")
110
grid_sizer_1.Add(label_1, 0, 0, 0)
111
label_2 = wx.StaticText(self, wx.ID_ANY, u"D\u1e5bg-ga\u1e47ita Pa\xf1c\u0101\u1e45ga", style=wx.ALIGN_RIGHT | wx.ALIGN_CENTRE)
112
label_2.SetMinSize((319, 24))
113
label_2.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
114
grid_sizer_1.Add(label_2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
115
label_4 = wx.StaticText(self, wx.ID_ANY, "")
116
grid_sizer_1.Add(label_4, 0, 0, 0)
117
label_3 = wx.StaticText(self, wx.ID_ANY, "Date (DD/MM/YYYY)")
118
grid_sizer_1.Add(label_3, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
119
grid_sizer_1.Add(self.dateTxt, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 0)
120
grid_sizer_1.Add(self.searchBtn, 0, 0, 0)
121
label_6 = wx.StaticText(self, wx.ID_ANY, "Location")
122
grid_sizer_1.Add(label_6, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
123
grid_sizer_1.Add(self.placeTxt, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 0)
124
grid_sizer_1.Add(self.computeBtn, 0, 0, 0)
125
label_31 = wx.StaticText(self, wx.ID_ANY, "Latitude")
126
grid_sizer_1.Add(label_31, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 0)
127
label_32 = wx.StaticText(self, wx.ID_ANY, "Longitude")
128
grid_sizer_1.Add(label_32, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
129
label_33 = wx.StaticText(self, wx.ID_ANY, "Time zone")
130
grid_sizer_1.Add(label_33, 0, wx.ALIGN_CENTER_VERTICAL, 0)
131
grid_sizer_1.Add(self.latTxt, 0, wx.RIGHT | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 0)
132
grid_sizer_1.Add(self.lonTxt, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
133
grid_sizer_1.Add(self.tzTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
134
static_line_1 = wx.StaticLine(self, wx.ID_ANY)
135
grid_sizer_1.Add(static_line_1, 0, wx.EXPAND, 0)
136
static_line_2 = wx.StaticLine(self, wx.ID_ANY)
137
grid_sizer_1.Add(static_line_2, 0, wx.EXPAND, 0)
138
static_line_3 = wx.StaticLine(self, wx.ID_ANY)
139
grid_sizer_1.Add(static_line_3, 0, wx.EXPAND, 0)
140
grid_sizer_1.Add(self.samvatTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
141
grid_sizer_1.Add(self.masaTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
142
grid_sizer_1.Add(self.rituTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
143
label_7 = wx.StaticText(self, wx.ID_ANY, "Tithi")
144
grid_sizer_1.Add(label_7, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
145
grid_sizer_1.Add(self.tithiTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
146
grid_sizer_1.Add(self.tithiTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
147
label_13 = wx.StaticText(self, wx.ID_ANY, u"Nak\u1e63atra ")
148
grid_sizer_1.Add(label_13, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
149
grid_sizer_1.Add(self.nakTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
150
grid_sizer_1.Add(self.nakTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
151
label_16 = wx.StaticText(self, wx.ID_ANY, "Yoga")
152
grid_sizer_1.Add(label_16, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
153
grid_sizer_1.Add(self.yogaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
154
grid_sizer_1.Add(self.yogaTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
155
label_19 = wx.StaticText(self, wx.ID_ANY, u"Kara\u1e47a ")
156
grid_sizer_1.Add(label_19, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
157
grid_sizer_1.Add(self.karanaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
158
grid_sizer_1.Add(self.karanaTimeTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
159
label_22 = wx.StaticText(self, wx.ID_ANY, u"V\u0101ra ")
160
grid_sizer_1.Add(label_22, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
161
grid_sizer_1.Add(self.varaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
162
label_24 = wx.StaticText(self, wx.ID_ANY, "")
163
grid_sizer_1.Add(label_24, 0, 0, 0)
164
grid_sizer_1.Add(self.aharTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
165
grid_sizer_1.Add(self.sakaTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
166
grid_sizer_1.Add(self.kaliTxt, 0, wx.ALIGN_CENTER_VERTICAL, 0)
167
static_line_4 = wx.StaticLine(self, wx.ID_ANY)
168
grid_sizer_1.Add(static_line_4, 0, wx.EXPAND, 0)
169
static_line_5 = wx.StaticLine(self, wx.ID_ANY)
170
grid_sizer_1.Add(static_line_5, 0, wx.EXPAND, 0)
171
static_line_6 = wx.StaticLine(self, wx.ID_ANY)
172
grid_sizer_1.Add(static_line_6, 0, wx.EXPAND, 0)
173
label_34 = wx.StaticText(self, wx.ID_ANY, "Sunrise")
174
grid_sizer_1.Add(label_34, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
175
label_37 = wx.StaticText(self, wx.ID_ANY, "Sunset")
176
grid_sizer_1.Add(label_37, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
177
label_5 = wx.StaticText(self, wx.ID_ANY, "Day duration")
178
grid_sizer_1.Add(label_5, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
179
grid_sizer_1.Add(self.sunriseTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
180
grid_sizer_1.Add(self.sunsetTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
181
grid_sizer_1.Add(self.duraTxt, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
182
label_10 = wx.StaticText(self, wx.ID_ANY, "")
183
grid_sizer_1.Add(label_10, 0, 0, 0)
184
label_9 = wx.StaticText(self, wx.ID_ANY, "https://github.com/bdsatish/drik-panchanga")
185
grid_sizer_1.Add(label_9, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
186
sizer_1.Add(grid_sizer_1, 1, 0, 0)
187
self.SetSizer(sizer_1)
188
self.Layout()
189
# end wxGlade
190
191
def calculate_panchanga(self, event): # wxGlade: Panchanga.<event_handler>
192
jd = gregorian_to_jd(self.parse_date())
193
self.set_place(event)
194
place = self.place
195
196
ti = tithi(jd, place)
197
nak = nakshatra(jd, place)
198
yog = yoga(jd, place)
199
mas = masa(jd, place)
200
rtu = ritu(mas[0])
201
202
kar = karana(jd, place)
203
vara = vaara(jd)
204
srise = sunrise(jd, place)[1]
205
sset = sunset(jd, place)[1]
206
kday = ahargana(jd)
207
kyear, sakayr = elapsed_year(jd, mas[0])
208
samvat = samvatsara(jd, mas[0])
209
day_dur = day_duration(jd, place)[1]
210
211
# Update GUI one by one. First the easy ones
212
self.karanaTxt.SetLabel("%s" % self.karanas[str(kar[0])])
213
self.karanaTimeTxt.SetLabel(" -- ")
214
self.varaTxt.SetLabel("%s" % self.vaaras[str(vara)])
215
self.sunriseTxt.SetLabel(format_time(srise))
216
self.sunsetTxt.SetLabel(format_time(sset))
217
self.sakaTxt.SetLabel(u"Śālivāhana śaka %d" % (sakayr))
218
self.kaliTxt.SetLabel("GataKali %d" % (kyear))
219
self.aharTxt.SetLabel("KaliDay %d" % (kday))
220
self.rituTxt.SetLabel(u"%s ṛtu" % (self.ritus[str(rtu)]))
221
self.samvatTxt.SetLabel("%s samvatsara" % (self.samvats[str(samvat)]))
222
self.duraTxt.SetLabel(format_time(day_dur))
223
224
# Next update the complex ones
225
month_name = self.masas[str(mas[0])]
226
is_leap = mas[1]
227
if is_leap: month_name = "Adhika " + month_name.lower()
228
self.masaTxt.SetLabel(month_name + u" māsa")
229
230
name, hms = format_name_hms(yog, self.yogas)
231
self.yogaTxt.SetLabel(name)
232
self.yogaTimeTxt.SetLabel(hms)
233
234
name, hms = format_name_hms(ti, self.tithis)
235
self.tithiTxt.SetLabel(name)
236
self.tithiTimeTxt.SetLabel(hms)
237
238
name, hms = format_name_hms(nak, self.nakshatras)
239
self.nakTxt.SetLabel(name)
240
self.nakTimeTxt.SetLabel(hms)
241
242
event.Skip()
243
244
245
def search_location(self, event): # wxGlade: Panchanga.<event_handler>
246
city = self.placeTxt.Value.title() # Convert to title-case
247
if self.cities.has_key(city):
248
self.searchBtn.SetForegroundColour(wx.Colour(0x2C, 0x2C, 0x2C))
249
# self.searchBtn.SetLabel("Found!")
250
251
date = self.parse_date()
252
city = self.cities[city]
253
lat = city['latitude']
254
lon = city['longitude']
255
tzname = city['timezone']
256
self.tzone = timezone(tzname)
257
tz_offset = self.compute_timezone_offset()
258
self.place = Place(lat, lon, tz_offset)
259
260
# update coordinate textboxes
261
self.latTxt.SetValue("%.5f" % lat)
262
self.lonTxt.SetValue("%.5f" % lon)
263
self.tzTxt.SetValue("%+.2f" % tz_offset)
264
else:
265
# Find nearest match
266
nearest = difflib.get_close_matches(city, self.all_cities, 5)
267
all_matches = ""
268
for m in nearest:
269
all_matches += m + '\n'
270
msg = city + ' not found!\n\n' + 'Did you mean any of these?\n\n' + all_matches
271
wx.MessageBox(msg, 'Error', wx.OK | wx.ICON_ERROR)
272
273
event.Skip()
274
275
def parse_date(self):
276
date = self.dateTxt.Value
277
try:
278
dt = strptime(date, "%d/%m/%Y")
279
date = Date(dt.tm_year, dt.tm_mon, dt.tm_mday)
280
except ValueError:
281
# Probably the user entered negative year, strptime can't handle it.
282
day, month, year = map(int, date.split('/'))
283
date = Date(year, month, day)
284
return date
285
286
def init_db(self):
287
fp = open("cities.json")
288
self.cities = json.load(fp)
289
self.all_cities = self.cities.keys()
290
fp.close()
291
fp = open("sanskrit_names.json")
292
sktnames = json.load(fp)
293
fp.close()
294
self.tithis = sktnames["tithis"]
295
self.nakshatras = sktnames["nakshatras"]
296
self.vaaras = sktnames["varas"]
297
self.yogas = sktnames["yogas"]
298
self.karanas = sktnames["karanas"]
299
self.masas = sktnames["masas"]
300
self.samvats = sktnames["samvats"]
301
self.ritus = sktnames["ritus"]
302
303
304
def set_place(self, event): # wxGlade: Panchanga.<event_handler>
305
lat = float(self.latTxt.Value)
306
lon = float(self.lonTxt.Value)
307
tz = float(self.tzTxt.Value)
308
self.place = Place(lat, lon, tz)
309
event.Skip()
310
311
312
def compute_timezone_offset(self):
313
date = self.parse_date()
314
timezone = self.tzone
315
dt = datetime(date.year, date.month, date.day)
316
# offset from UTC (in hours). Needed especially for DST countries
317
tz_offset = timezone.utcoffset(dt, is_dst = True).total_seconds() / 3600.
318
return tz_offset
319
320
# end of class Panchanga
321
322
# Global functions
323
# Converts list [12, [23, 45, 50]] to lookup[12] and 23:45:50
324
def format_name_hms(nhms, lookup):
325
name_txt = lookup[str(nhms[0])]
326
time_txt = format_time(nhms[1])
327
if len(nhms) == 4:
328
name_txt += "\n" + lookup[str(nhms[2])]
329
time_txt += "\n" + format_time(nhms[3])
330
331
return name_txt, time_txt
332
333
334
if __name__ == "__main__":
335
app = wx.PySimpleApp(0)
336
wx.InitAllImageHandlers()
337
frame_1 = Panchanga(None, -1, "")
338
app.SetTopWindow(frame_1)
339
frame_1.Show()
340
app.MainLoop()
341
342