Added support for localisation

By switching from image-based translations to text-based translations, month names and weekday names can now be easily 'translated' with arrow (python lib). By using this method, a font was required that could display letters from a lot of languages. Since the current font was displaying 'Tofus', Google's Noto (No-Tofu->Noto) Sans font is now being used.
Unfortunately, support for chinese/taiwanese is temporary unavailable since even Noto can't display these correctly (at least for now).
This commit is contained in:
Ace 2019-05-12 12:29:06 +02:00 committed by GitHub
parent 6928dd9a35
commit 074c50312a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -38,9 +38,12 @@ from calibration import calibration
EPD_WIDTH = 640 EPD_WIDTH = 640
EPD_HEIGHT = 384 EPD_HEIGHT = 384
default = ImageFont.truetype(path+'Assistant-Regular.ttf', 18)
semi = ImageFont.truetype(path+'Assistant-SemiBold.ttf', 18) default = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensedLight.ttf', 18)
bold = ImageFont.truetype(path+'Assistant-Bold.ttf', 18) semi = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensed.ttf', 18)
bold = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensedMedium.ttf', 18)
month_font = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensedLight.ttf', 40)
im_open = Image.open im_open = Image.open
owm = pyowm.OWM(api_key) owm = pyowm.OWM(api_key)
@ -55,6 +58,7 @@ def main():
year = int(time.now().strftime('%Y')) year = int(time.now().strftime('%Y'))
mins = int(time.strftime("%M")) mins = int(time.strftime("%M"))
seconds = int(time.strftime("%S")) seconds = int(time.strftime("%S"))
now = arrow.now()
for i in range(1): for i in range(1):
print('_________Starting new loop___________'+'\n') print('_________Starting new loop___________'+'\n')
@ -86,11 +90,12 @@ def main():
x = int((box_width / 2) - (text_width / 2)) x = int((box_width / 2) - (text_width / 2))
if alignment is 'left': if alignment is 'left':
x = 0 x = 0
y = int((box_height / 2) - (text_height / 2)) y = int((box_height / 2) - (text_height / 1.7))
space = Image.new('RGB', (box_width, box_height), color='white') space = Image.new('RGB', (box_width, box_height), color='white')
ImageDraw.Draw(space).text((x, y), text, fill='black', font=font) ImageDraw.Draw(space).text((x, y), text, fill='black', font=font)
image.paste(space, tuple) image.paste(space, tuple)
"""Check if internet is available by trying to reach google"""
def internet_available(): def internet_available():
try: try:
urlopen('https://google.com',timeout=5) urlopen('https://google.com',timeout=5)
@ -100,73 +105,85 @@ def main():
"""Connect to Openweathermap API and fetch weather data""" """Connect to Openweathermap API and fetch weather data"""
if top_section is "Weather" and api_key != "" and owm.is_API_online() is True: if top_section is "Weather" and api_key != "" and owm.is_API_online() is True:
print("Connecting to Openweathermap API servers...") try:
observation = owm.weather_at_place(location) print("Connecting to Openweathermap API servers...")
print("weather data:") observation = owm.weather_at_place(location)
weather = observation.get_weather() print("weather data:")
weathericon = weather.get_weather_icon_name() weather = observation.get_weather()
Humidity = str(weather.get_humidity()) weathericon = weather.get_weather_icon_name()
cloudstatus = str(weather.get_clouds()) Humidity = str(weather.get_humidity())
weather_description = (str(weather.get_status())) cloudstatus = str(weather.get_clouds())
weather_description = (str(weather.get_status()))
if units is "metric": if units is "metric":
Temperature = str(int(weather.get_temperature(unit='celsius')['temp'])) Temperature = str(int(weather.get_temperature(unit='celsius')['temp']))
windspeed = str(int(weather.get_wind()['speed'])) windspeed = str(int(weather.get_wind()['speed']))
write_text(50, 35, Temperature + " °C", (334, 0)) write_text(50, 35, Temperature + " °C", (334, 0))
write_text(100, 35, windspeed+" km/h", (114, 0)) write_text(100, 35, windspeed+" km/h", (114, 0))
if units is "imperial": if units is "imperial":
Temperature = str(int(weather.get_temperature('fahrenheit')['temp'])) Temperature = str(int(weather.get_temperature('fahrenheit')['temp']))
windspeed = str(int(weather.get_wind()['speed']*0.621)) windspeed = str(int(weather.get_wind()['speed']*0.621))
write_text(50, 35, Temperature + " °F", (334, 0)) write_text(50, 35, Temperature + " °F", (334, 0))
write_text(100, 35, windspeed+" mph", (114, 0)) write_text(100, 35, windspeed+" mph", (114, 0))
if hours is "24": if hours is "24":
sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%-H:%M')) sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%-H:%M'))
sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%-H:%M')) sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%-H:%M'))
if hours is "12": if hours is "12":
sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%-I:%M')) sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%-I:%M'))
sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%-I:%M')) sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%-I:%M'))
"""Show the fetched weather data""" """Show the fetched weather data"""
print('Temperature: '+ Temperature+' °C') print('Temperature: '+ Temperature+' °C')
print('Humidity: '+ Humidity+'%') print('Humidity: '+ Humidity+'%')
print('weather-icon name: '+weathericons[weathericon]) print('weather-icon name: '+weathericons[weathericon])
print('Wind speed: '+ windspeed+'km/h') print('Wind speed: '+ windspeed+'km/h')
print('Sunrise-time: '+ sunrisetime) print('Sunrise-time: '+ sunrisetime)
print('Sunset time: '+ sunsettime) print('Sunset time: '+ sunsettime)
print('Cloudiness: ' + cloudstatus+'%') print('Cloudiness: ' + cloudstatus+'%')
print('Weather description: '+ weather_description+'\n') print('Weather description: '+ weather_description+'\n')
"""Add the weather icon at the top left corner""" """Add the weather icon at the top left corner"""
image.paste(im_open(wpath + weathericons[weathericon] +'.jpeg'), wiconplace) image.paste(im_open(wpath + weathericons[weathericon] +'.jpeg'), wiconplace)
"""Add the temperature icon at it's position""" """Add the temperature icon at it's position"""
image.paste(tempicon, tempplace) image.paste(tempicon, tempplace)
"""Add the humidity icon and display the humidity""" """Add the humidity icon and display the humidity"""
image.paste(humicon, humplace) image.paste(humicon, humplace)
write_text(50, 35, Humidity + " %", (334, 35)) write_text(50, 35, Humidity + " %", (334, 35))
"""Add the sunrise icon and display the sunrise time""" """Add the sunrise icon and display the sunrise time"""
image.paste(sunriseicon, sunriseplace) image.paste(sunriseicon, sunriseplace)
write_text(50, 35, sunrisetime, (249, 0)) write_text(50, 35, sunrisetime, (249, 0))
"""Add the sunset icon and display the sunrise time""" """Add the sunset icon and display the sunrise time"""
image.paste(sunseticon, sunsetplace) image.paste(sunseticon, sunsetplace)
write_text(50, 35, sunsettime, (249, 35)) write_text(50, 35, sunsettime, (249, 35))
"""Add the wind icon at it's position""" """Add the wind icon at it's position"""
image.paste(windicon, windiconspace) image.paste(windicon, windiconspace)
"""Add a short weather description""" """Add a short weather description"""
write_text(144, 35, weather_description, (70, 35)) write_text(144, 35, weather_description, (70, 35))
else: except Exception as e:
"""If no response was received from the openweathermap """If no response was received from the openweathermap
api server, add the cloud with question mark""" api server, add the cloud with question mark"""
image.paste(no_response, wiconplace) print('__________OWM-ERROR!__________'+'\n')
print('Reason: ',e+'\n')
image.paste(no_response, wiconplace)
pass
"""Set the Calendar to start on the day specified by the settings file """
if week_starts_on is "Monday":
calendar.setfirstweekday(calendar.MONDAY)
"""For those whose week starts on Sunday, change accordingly"""
if week_starts_on is "Sunday":
calendar.setfirstweekday(calendar.SUNDAY)
"""Using the built-in calendar to generate the monthly Calendar """Using the built-in calendar to generate the monthly Calendar
template""" template"""
@ -174,23 +191,27 @@ def main():
if middle_section is "Calendar": if middle_section is "Calendar":
"""Add the icon with the current month's name""" """Add the icon with the current month's name"""
image.paste(im_open(mpath+str(time.strftime("%B")+'.jpeg')), monthplace) write_text(384,60, now.format('MMMM',locale=language), monthplace, font=month_font)
"""Add the line seperating the weather and Calendar section""" """Add the line seperating the weather and Calendar section"""
image.paste(seperator, seperatorplace) image.paste(seperator, seperatorplace)
"""Add weekday-icons (Mon, Tue...) and draw a circle on the """Create a list containing the weekday abbrevations for the
current weekday""" chosen language"""
if (week_starts_on is "Monday"): if week_starts_on is "Monday":
calendar.setfirstweekday(calendar.MONDAY) prev_weekstart = now.replace(days = - now.weekday())
image.paste(weekmon, weekplace) image.paste(weekday, weekday_pos['pos'+str(now.weekday())], weekday)
image.paste(weekday, weekdaysmon[(time.strftime("%a"))], weekday) if week_starts_on is "Sunday":
prev_weekstart = now.replace(days = - now.isoweekday())
image.paste(weekday, weekday_pos['pos'+str(now.isoweekday())], weekday)
weekday_names_list = []
for i in range(7):
weekday_name = prev_weekstart.replace(days=+i)
weekday_names_list.append(weekday_name.format('ddd',locale=language))
"""For those whose week starts on Sunday, change accordingly""" for i in range(len(weekday_names_list)):
if (week_starts_on is "Sunday"): write_text(54, 28, weekday_names_list[i], weekday_pos['pos'+str(i)])
calendar.setfirstweekday(calendar.SUNDAY)
image.paste(weeksun, weekplace)
image.paste(weekday, weekdayssun[(time.strftime("%a"))], weekday)
"""Create the calendar template of the current month""" """Create the calendar template of the current month"""
for numbers in cal[0]: for numbers in cal[0]:
@ -224,6 +245,8 @@ def main():
"""Add rss-feeds at the bottom section of the Calendar""" """Add rss-feeds at the bottom section of the Calendar"""
if bottom_section is "RSS" and rss_feeds != []: if bottom_section is "RSS" and rss_feeds != []:
"""Custom function to display longer text into multiple lines (wrapping)"""
def multiline_text(text, max_width, font=default): def multiline_text(text, max_width, font=default):
lines = [] lines = []
if font.getsize(text)[0] <= max_width: if font.getsize(text)[0] <= max_width:
@ -287,7 +310,6 @@ def main():
iCalendar/s""" iCalendar/s"""
events_this_month = [] events_this_month = []
upcoming = [] upcoming = []
now = arrow.now()
today = time.today() today = time.today()
"""Create a time span using the events_max_range value (in days) """Create a time span using the events_max_range value (in days)
@ -307,7 +329,7 @@ def main():
decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:] decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:]
ical = Calendar(decode) ical = Calendar(decode)
for events in ical.events: for events in ical.events:
if events.begin.date().year == today.year and events.begin.date().month == today.month: if events.begin.date().year == today.year and events.begin.date().month is today.month:
if int((events.begin).format('D')) not in events_this_month: if int((events.begin).format('D')) not in events_this_month:
events_this_month.append(int((events.begin).format('D'))) events_this_month.append(int((events.begin).format('D')))
if middle_section is 'Agenda' and events in ical.timeline.included(now, agenda_max_days): if middle_section is 'Agenda' and events in ical.timeline.included(now, agenda_max_days):
@ -322,7 +344,7 @@ def main():
else: else:
print("Could not fetch events from your iCalendar.") print("Could not fetch events from your iCalendar.")
print("Either the internet connection is too slow or we're offline.") print("Either the internet connection is too weak or we're offline.")
if middle_section is 'Agenda': if middle_section is 'Agenda':
@ -333,14 +355,13 @@ def main():
agenda_list = [] agenda_list = []
for i in range(22): for i in range(22):
date = now.replace(days=+i) date = now.replace(days=+i)
agenda_list.append({'value':date.format('ddd D MMM YY'),'type':'date'}) agenda_list.append({'value':date.format('ddd D MMM YY', locale=language),'type':'date'})
for events in upcoming: for events in upcoming:
if events.begin.date().day == date.day: if events.begin.date().day == date.day:
if not events.all_day: if not events.all_day:
agenda_list.append({'value':events.begin.format('HH:mm')+ ' '+ str(events.name), 'type':'timed_event'}) agenda_list.append({'value':events.begin.format('HH:mm')+ ' '+ str(events.name), 'type':'timed_event'})
else: else:
agenda_list.append({'value':events.name, 'type':'full_day_event'}) agenda_list.append({'value':events.name, 'type':'full_day_event'})
if bottom_section is not "": if bottom_section is not "":
del agenda_list[16:] del agenda_list[16:]
image.paste(seperator2, agenda_view_lines['line17']) image.paste(seperator2, agenda_view_lines['line17'])
@ -351,7 +372,7 @@ def main():
for lines in range(len(agenda_list)): for lines in range(len(agenda_list)):
if agenda_list[lines]['type'] is 'date': if agenda_list[lines]['type'] is 'date':
write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)], font=bold, alignment='left') write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)], font=semi, alignment='left')
image.paste(seperator2, agenda_view_lines['line'+str(lines+1)]) image.paste(seperator2, agenda_view_lines['line'+str(lines+1)])
elif agenda_list[lines]['type'] is 'timed_event': elif agenda_list[lines]['type'] is 'timed_event':
write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)], alignment='left') write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)], alignment='left')
@ -418,9 +439,10 @@ def main():
print('______Powering off the E-Paper until the next loop______'+'\n') print('______Powering off the E-Paper until the next loop______'+'\n')
epd.sleep() epd.sleep()
#if middle_section is 'Calendar': if middle_section is 'Calendar':
del events_this_month del events_this_month
del upcoming del upcoming
del weekday_names_list
if bottom_section is 'RSS': if bottom_section is 'RSS':
del rss_feed del rss_feed
@ -435,7 +457,7 @@ def main():
gc.collect() gc.collect()
if calibration_countdown is 'initial': if calibration_countdown is 'initial':
calibration_countdown = 0 calibration_countdown = 0
calibration_countdown += 1 calibration_countdown += 1
for i in range(1): for i in range(1):