From 1ca91c69e022b152406623cc93abc69f4423848c Mon Sep 17 00:00:00 2001 From: roe-dl Date: Thu, 18 Mar 2021 18:04:40 +0100 Subject: [PATCH 01/30] file hash additionally to file time for skip upload decision --- bin/weeutil/ftpupload.py | 54 ++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/bin/weeutil/ftpupload.py b/bin/weeutil/ftpupload.py index 1626f874..1c85b082 100644 --- a/bin/weeutil/ftpupload.py +++ b/bin/weeutil/ftpupload.py @@ -17,6 +17,12 @@ import time from six.moves import cPickle +try: + import hashlib + has_hashlib=True +except ImportError: + has_hashlib=False + log = logging.getLogger(__name__) @@ -86,7 +92,7 @@ class FtpUpload(object): returns: the number of files uploaded.""" # Get the timestamp and members of the last upload: - timestamp, fileset = self.get_last_upload() + timestamp, fileset, hashdict = self.get_last_upload() n_uploaded = 0 @@ -151,13 +157,22 @@ class FtpUpload(object): for filename in filenames: full_local_path = os.path.join(dirpath, filename) + + # calculate hash + if has_hashlib: + filehash=sha256sum(full_local_path) + else: + filehash=None + # See if this file can be skipped: - if _skip_this_file(timestamp, fileset, full_local_path): + if _skip_this_file(timestamp, fileset, hashdict, full_local_path, filehash): continue full_remote_path = os.path.join(remote_dir_path, filename) stor_cmd = "STOR %s" % full_remote_path + log.debug("%s %s/%s %s" % (n_uploaded,local_rel_dir_path,filename,filehash)) + with open(full_local_path, 'rb') as fd: try: ftp_server.storbinary(stor_cmd, fd) @@ -169,6 +184,7 @@ class FtpUpload(object): # Success. n_uploaded += 1 fileset.add(full_local_path) + hashdict[full_local_path]=filehash log.debug("Uploaded file %s to %s", full_local_path, full_remote_path) finally: try: @@ -177,7 +193,7 @@ class FtpUpload(object): pass timestamp = time.time() - self.save_last_upload(timestamp, fileset) + self.save_last_upload(timestamp, fileset, hashdict) return n_uploaded def get_last_upload(self): @@ -192,9 +208,11 @@ class FtpUpload(object): with open(timestamp_file_path, "rb") as f: timestamp = cPickle.load(f) fileset = cPickle.load(f) + hashdict = cPickle.load(f) except (IOError, EOFError, cPickle.PickleError, AttributeError): timestamp = 0 fileset = set() + hashdict = {} # Either the file does not exist, or it is garbled. # Either way, it's safe to remove it. try: @@ -202,17 +220,18 @@ class FtpUpload(object): except OSError: pass - return timestamp, fileset + return timestamp, fileset, hashdict - def save_last_upload(self, timestamp, fileset): + def save_last_upload(self, timestamp, fileset, hashdict): """Saves the time and members of the last upload in the local root.""" timestamp_file_path = os.path.join(self.local_root, "#%s.last" % self.name) with open(timestamp_file_path, "wb") as f: cPickle.dump(timestamp, f) cPickle.dump(fileset, f) + cPickle.dump(hashdict, f) -def _skip_this_file(timestamp, fileset, full_local_path): +def _skip_this_file(timestamp, fileset, hashdict, full_local_path, filehash): """Determine whether to skip a specific file.""" filename = os.path.basename(full_local_path) @@ -222,8 +241,16 @@ def _skip_this_file(timestamp, fileset, full_local_path): if full_local_path not in fileset: return False - if os.stat(full_local_path).st_mtime > timestamp: - return False + if has_hashlib and filehash is not None: + # use hash if available + if full_local_path not in hashdict: + return False + if hashdict[full_local_path]!=filehash: + return False + else: + # otherwise use file time + if os.stat(full_local_path).st_mtime > timestamp: + return False # Filename is in the set, and is up to date. return True @@ -254,3 +281,14 @@ def _make_remote_dir(ftp_server, remote_dir_path): raise log.debug("Made directory %s", remote_dir_path) + +# from https://stackoverflow.com/questions/22058048/hashing-a-file-in-python + +def sha256sum(filename): + h = hashlib.sha256() + b = bytearray(128*1024) + mv = memoryview(b) + with open(filename, 'rb', buffering=0) as f: + for n in iter(lambda : f.readinto(mv), 0): + h.update(mv[:n]) + return h.hexdigest() From 8137b671bdb1bcdcec63f7e9a750e6fc6d3885c0 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 17 Apr 2021 10:52:28 +0200 Subject: [PATCH 02/30] added localization support by localization files --- bin/weewx/reportengine.py | 45 ++++++++++++++ skins/Seasons/about.inc | 2 +- skins/Seasons/celestial.html.tmpl | 2 +- skins/Seasons/celestial.inc | 2 +- skins/Seasons/current.inc | 2 +- skins/Seasons/hilo.inc | 11 ++-- skins/Seasons/index.html.tmpl | 10 +-- skins/Seasons/lang/de.conf | 98 ++++++++++++++++++++++++++++++ skins/Seasons/lang/en.conf | 98 ++++++++++++++++++++++++++++++ skins/Seasons/sensors.inc | 2 +- skins/Seasons/statistics.html.tmpl | 2 +- skins/Seasons/statistics.inc | 12 ++-- skins/Seasons/sunmoon.inc | 2 +- skins/Seasons/tabular.html.tmpl | 2 +- skins/Seasons/telemetry.html.tmpl | 2 +- skins/Seasons/titlebar.inc | 8 +-- weewx.conf | 1 + 17 files changed, 272 insertions(+), 29 deletions(-) create mode 100644 skins/Seasons/lang/de.conf create mode 100644 skins/Seasons/lang/en.conf diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index c3b45977..c2563d6a 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -254,6 +254,51 @@ class StdReportEngine(threading.Thread): for scalar in self.config_dict['StdReport'].scalars: skin_dict[scalar] = self.config_dict['StdReport'][scalar] + ####################################################################### + # localization support + + # If a localization is defined, get it. + if 'lang_file' in self.config_dict['StdReport'][report]: + # 'lang_file' defines the file name directly + lang_config = self.config_dict['StdReport'][report]['lang_file'] + elif 'lang' in self.config_dict['StdReport'][report]: + # 'lang' defines a language code like 'en' or 'de' + # The file is located in subdirectory 'lang' of the skin directory then. + lang_config = "lang/%s.conf" % self.config_dict['StdReport'][report]['lang'] + else: + # No localization defined. Use defaults. + lang_config = None + + # If a localization file could be determined, read it. + if lang_config: + + # Now add the options in the report's localization file. Start by figuring where it is located. + lang_config_path = os.path.join( + self.config_dict['WEEWX_ROOT'], + self.config_dict['StdReport']['SKIN_ROOT'], + self.config_dict['StdReport'][report].get('skin', ''), + lang_config) + + # Now retrieve the language dictionary for the skin. Wrap it in a try block in case we fail. It is ok if + # there is no file - everything for a skin might be defined in the weewx configuration. + try: + merge_dict = configobj.ConfigObj(lang_config_path, file_error=True, encoding='utf-8') + log.debug("Found localization file %s for report '%s'", lang_config_path, report) + # Merge the skin config file in: + weeutil.config.merge_config(skin_dict, merge_dict) + if self.first_run: + log.info("Using localization file %s for report '%s'" % + (lang_config_path, report)) + except IOError as e: + log.debug("Cannot read localization file %s for report '%s': %s", + lang_config_path, report, e) + except SyntaxError as e: + log.error("Failed to read localization file %s for report '%s': %s", + lang_config_path, report, e) + raise + + ####################################################################### + # Finally, inject any overrides for this specific report. Because this is the last merge, it will have the # final say. weeutil.config.merge_config(skin_dict, self.config_dict['StdReport'][report]) diff --git a/skins/Seasons/about.inc b/skins/Seasons/about.inc index 424ab377..532981b7 100644 --- a/skins/Seasons/about.inc +++ b/skins/Seasons/about.inc @@ -6,7 +6,7 @@
- About this weather station + $obs.label.about_title
diff --git a/skins/Seasons/celestial.html.tmpl b/skins/Seasons/celestial.html.tmpl index 08cfc3f2..0b442a07 100644 --- a/skins/Seasons/celestial.html.tmpl +++ b/skins/Seasons/celestial.html.tmpl @@ -31,7 +31,7 @@ #include "titlebar.inc"
-

❰ Current Conditions

+

❰ $obs.label.current_conditions_title

#include "celestial.inc" diff --git a/skins/Seasons/celestial.inc b/skins/Seasons/celestial.inc index 9cf96faa..68cc2592 100644 --- a/skins/Seasons/celestial.inc +++ b/skins/Seasons/celestial.inc @@ -49,7 +49,7 @@
- Celestial + $obs.label.celestial_title
#if $almanac.hasExtras diff --git a/skins/Seasons/current.inc b/skins/Seasons/current.inc index 3f31d5c1..ea051a85 100644 --- a/skins/Seasons/current.inc +++ b/skins/Seasons/current.inc @@ -6,7 +6,7 @@
- Current Conditions + $obs.label.current_conditions_title
diff --git a/skins/Seasons/hilo.inc b/skins/Seasons/hilo.inc index 18ba85ab..d3e5988d 100644 --- a/skins/Seasons/hilo.inc +++ b/skins/Seasons/hilo.inc @@ -8,7 +8,7 @@
@@ -18,11 +18,12 @@ -  
Today -  
Week -  
Month +  
$obs.label.hilo_today +  
$obs.label.hilo_week +  
$obs.label.hilo_month -         
Year
+         
$obs.label.hilo_year
Rain
Year
diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index b4c95aab..a998c467 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -33,15 +33,15 @@
-
History:   +
$obs.label.history_title:   Day + onclick="choose_history('day')">$obs.label.history_day Week + onclick="choose_history('week')">$obs.label.history_week Month + onclick="choose_history('month')">$obs.label.history_month Year + onclick="choose_history('year')">$obs.label.history_year
$obs.label.barometer diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf new file mode 100644 index 00000000..8acfbcde --- /dev/null +++ b/skins/Seasons/lang/de.conf @@ -0,0 +1,98 @@ +############################################################################### +# Language Configuration File # +# German # +############################################################################### + +[Units] + + # The following section overrides the label used for each type of unit + [[Labels]] + meter = " m", " m" # You may prefer "metre". + day = " Tag", " Tage" + hour = " Stunde", " Stunden" + minute = " Minute", " Minuten" + second = " Sekunde", " Sekunden" + NONE = "" + + [[Ordinates]] + + # Ordinal directions. The last one is for no wind direction + directions = N, NNO, NO, ONO, O, OSO, SO, SSO, S, SSW, SW, WSW, W, WNW, NW, NNW, N/A + +[Labels] + + # Set to hemisphere abbreviations suitable for your location: + hemispheres = N, S, O, W + + # Generic labels, keyed by an observation type. + [[Generic]] + barometer = Luftdruck + pressure = abs. Luftdruck + dewpoint = Taupunkt + ET = ET + heatindex = Hitzeindex + inHumidity = Raumluftfeuchtigkeit + inTemp = Raumtemperatur + outHumidity = Luftfeuchtigkeit + outTemp = Außentemperatur + radiation = Sonnenstrahlung + rain = Regen + rainRate = Regen-Rate + UV = UV-Index + windDir = Windrichtung + windGust = Böen Geschwindigkeit + windGustDir = Böen Richtung + windSpeed = Windgeschwindigkeit + windchill = Windchill + windgustvec = Böen-Vektor + windvec = Wind-Vektor + extraTemp1 = Temperatur1 + extraTemp2 = Temperatur2 + extraTemp3 = Temperatur3 + + # Sensor status indicators + + rxCheckPercent = Signalqualität + txBatteryStatus = Übertragerbatteriestatus + windBatteryStatus = Anemometerbatteriestatus + rainBatteryStatus = Regenmesserbatteriestatus + outTempBatteryStatus = Außentemperatursensorbatteriestatus + inTempBatteryStatus = Innentemperatursensorbatteriestatus + consBatteryVoltage = Konsolenbatteriestatus + heatingVoltage = Heizungsspannung + supplyVoltage = Versorgungsspannung + referenceVoltage = Referenzspannung + + # History + history_title = Diagramme + history_day = Tag + history_week = Woche + history_month = Monat + history_year = Jahr + + # Section Titles + current_conditions_title = Aktuelle Werte + celestial_title = Sonne und Mond + hilo_title = "Höchst- und Tiefstwerte" + sensor_status_title = "Sensorenstatus" + about_title = "Über diese Wetterstation" + statistics_title = "Statistik" + + # Reports + monthly_reports = "Monatswerte" + yearly_reports = "Jahreswerte" + select_month = "Monat wählen" + select_year = "Jahr wählen" + + # High/Low + hilo_today = Heute + hilo_week = Woche + hilo_month = Monat + hilo_year = Jahr + hilo_rainyear = Regenjahr + + +[Almanac] + + # The labels to be used for the phases of the moon: + moon_phases = Neumond, zunehmend, Halbmond, zunehmend, Vollmond, abnehmend, Halbmond, abnehmend diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf new file mode 100644 index 00000000..799e71ab --- /dev/null +++ b/skins/Seasons/lang/en.conf @@ -0,0 +1,98 @@ +############################################################################### +# Language Configuration File # +# English # +############################################################################### + +[Units] + + [[Labels]] + + day = " day", " days" + hour = " hour", " hours" + minute = " minute", " minutes" + second = " second", " seconds" + + [[Ordinates]] + + # Ordinal directions. The last one should be for no wind direction + directions = N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW, N/A + +[Labels] + + # Set to hemisphere abbreviations suitable for your location: + hemispheres = N, S, E, W + + # Generic labels, keyed by an observation type. + [[Generic]] + barometer = Barometer + barometerRate = Barometer Change Rate + dewpoint = Dew Point + ET = ET + heatindex = Heat Index + inHumidity = Inside Humidity + inTemp = Inside Temperature + outHumidity = Humidity + outTemp = Outside Temperature + radiation = Radiation + rain = Rain + rainRate = Rain Rate + UV = UV Index + windDir = Wind Direction + windGust = Gust Speed + windGustDir = Gust Direction + windSpeed = Wind Speed + windchill = Wind Chill + windgustvec = Gust Vector + windvec = Wind Vector + windrun = Wind Run + extraTemp1 = Temperature1 + extraTemp2 = Temperature2 + extraTemp3 = Temperature3 + lightning_distance = Lightning Distance + lightning_strike_count = Lightning Strikes + + # Sensor status indicators + + rxCheckPercent = Signal Quality + txBatteryStatus = Transmitter Battery + windBatteryStatus = Wind Battery + rainBatteryStatus = Rain Battery + outTempBatteryStatus = Outside Temperature Battery + inTempBatteryStatus = Inside Temperature Battery + consBatteryVoltage = Console Battery + heatingVoltage = Heating Battery + supplyVoltage = Supply Voltage + referenceVoltage = Reference Voltage + + # History + history_title = History + history_day = Day + history_week = Week + history_month = Month + history_year = Year + + # Section Titles + current_conditions_title = Current Conditions + celestial_title = Celestial + hilo_title = "High/Low" + sensor_status_title = "Sensor Status" + about_title = "About this weather station" + statistics_title = "Statistics" + + # Reports + monthly_reports = "Monthly Reports" + yearly_reports = "Yearly Reports" + select_month = "Select Month" + select_year = "Select Year" + + # High/Low + hilo_today = Today + hilo_week = Week + hilo_month = Month + hilo_year = Year + hilo_rainyear = Rain Year + +[Almanac] + + # The labels to be used for the phases of the moon: + moon_phases = New, Waxing crescent, First quarter, Waxing gibbous, Full, Waning gibbous, Last quarter, Waning crescent diff --git a/skins/Seasons/sensors.inc b/skins/Seasons/sensors.inc index f6fced07..f93ebacc 100644 --- a/skins/Seasons/sensors.inc +++ b/skins/Seasons/sensors.inc @@ -45,7 +45,7 @@ #if $have_conn or $have_battery_status or $have_voltage
diff --git a/skins/Seasons/statistics.html.tmpl b/skins/Seasons/statistics.html.tmpl index a2e7e279..f1ffc9e9 100644 --- a/skins/Seasons/statistics.html.tmpl +++ b/skins/Seasons/statistics.html.tmpl @@ -39,7 +39,7 @@ #include "titlebar.inc"
-

❰ Current Conditions

+

❰ $obs.label.current_conditions_title

#include "statistics.inc" diff --git a/skins/Seasons/statistics.inc b/skins/Seasons/statistics.inc index cea477e3..30ed3bc1 100644 --- a/skins/Seasons/statistics.inc +++ b/skins/Seasons/statistics.inc @@ -8,7 +8,7 @@
- Statistics + $obs.label.statistics_title
@@ -17,11 +17,11 @@ - Today - Week - Month - Year - Rain year + $obs.label.hilo_today + $obs.label.hilo_week + $obs.label.hilo_month + $obs.label.hilo_year + $obs.label.hilo_rainyear $obs.label.outTemp diff --git a/skins/Seasons/sunmoon.inc b/skins/Seasons/sunmoon.inc index 0e51609a..8cc16e1c 100644 --- a/skins/Seasons/sunmoon.inc +++ b/skins/Seasons/sunmoon.inc @@ -27,7 +27,7 @@
diff --git a/skins/Seasons/tabular.html.tmpl b/skins/Seasons/tabular.html.tmpl index 87695a45..aabfe729 100644 --- a/skins/Seasons/tabular.html.tmpl +++ b/skins/Seasons/tabular.html.tmpl @@ -23,7 +23,7 @@ #include "titlebar.inc" diff --git a/skins/Seasons/telemetry.html.tmpl b/skins/Seasons/telemetry.html.tmpl index fcbf2864..ca6afe11 100644 --- a/skins/Seasons/telemetry.html.tmpl +++ b/skins/Seasons/telemetry.html.tmpl @@ -31,7 +31,7 @@ #include "titlebar.inc"
-

❰ Current Conditions

+

❰ $obs.label.current_conditions_title

#include "sensors.inc" diff --git a/skins/Seasons/titlebar.inc b/skins/Seasons/titlebar.inc index 12c9d664..e94c0fd7 100644 --- a/skins/Seasons/titlebar.inc +++ b/skins/Seasons/titlebar.inc @@ -11,20 +11,20 @@
- Monthly Reports: + $obs.label.monthly_reports:
- Yearly Reports: + $obs.label.yearly_reports:
diff --git a/weewx.conf b/weewx.conf index 87f65185..ffadb58b 100644 --- a/weewx.conf +++ b/weewx.conf @@ -158,6 +158,7 @@ version = 4.5.1 # The SeasonsReport uses the 'Seasons' skin, which contains the # images, templates and plots for the report. skin = Seasons + lang = en enable = true [[SmartphoneReport]] From 2a73e9a2f3a8ef6724bae366537efc5487863966 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 17 Apr 2021 21:54:49 +0200 Subject: [PATCH 03/30] localization with $gettext() --- bin/weewx/cheetahgenerator.py | 16 ++-- bin/weewx/gettext.py | 135 ++++++++++++++++++++++++++++++++++ bin/weewx/reportengine.py | 6 +- skins/Seasons/celestial.inc | 6 +- skins/Seasons/current.inc | 2 +- skins/Seasons/hilo.inc | 2 +- skins/Seasons/identifier.inc | 6 +- skins/Seasons/lang/de.conf | 33 ++++++++- skins/Seasons/lang/en.conf | 31 +++++++- skins/Seasons/statistics.inc | 2 +- 10 files changed, 217 insertions(+), 22 deletions(-) create mode 100644 bin/weewx/gettext.py diff --git a/bin/weewx/cheetahgenerator.py b/bin/weewx/cheetahgenerator.py index b6078010..0f600b7f 100644 --- a/bin/weewx/cheetahgenerator.py +++ b/bin/weewx/cheetahgenerator.py @@ -90,7 +90,8 @@ default_search_list = [ "weewx.cheetahgenerator.Stats", "weewx.cheetahgenerator.UnitInfo", "weewx.cheetahgenerator.Extras", - "weewx.cheetahgenerator.JSONHelpers"] + "weewx.cheetahgenerator.JSONHelpers", + "weewx.gettext.Gettext"] # ============================================================================= @@ -149,7 +150,7 @@ class CheetahGenerator(weewx.reportengine.ReportGenerator): self.initExtensions(gen_dict[section_name]) # Generate any templates in the given dictionary: - ngen = self.generate(gen_dict[section_name], self.gen_ts) + ngen = self.generate(gen_dict[section_name], section_name, self.gen_ts) self.teardown() @@ -198,7 +199,7 @@ class CheetahGenerator(weewx.reportengine.ReportGenerator): while len(self.search_list_objs): del self.search_list_objs[-1] - def generate(self, section, gen_ts): + def generate(self, section, section_name, gen_ts): """Generate one or more reports for the indicated section. Each section in a period is a report. A report has one or more templates. @@ -219,7 +220,7 @@ class CheetahGenerator(weewx.reportengine.ReportGenerator): if subsection in CheetahGenerator.generator_dict: section[subsection]['summarize_by'] = subsection # Call recursively, to generate any templates in this subsection - ngen += self.generate(section[subsection], gen_ts) + ngen += self.generate(section[subsection], subsection, gen_ts) # We have finished recursively processing any subsections in this # section. Time to do the section itself. If there is no option @@ -308,7 +309,7 @@ class CheetahGenerator(weewx.reportengine.ReportGenerator): pass searchList = self._getSearchList(encoding, timespan, - default_binding) + default_binding, section_name) tmpname = _fullname + '.tmp' try: @@ -369,14 +370,15 @@ class CheetahGenerator(weewx.reportengine.ReportGenerator): return ngen - def _getSearchList(self, encoding, timespan, default_binding): + def _getSearchList(self, encoding, timespan, default_binding, section_name): """Get the complete search list to be used by Cheetah.""" # Get the basic search list timespan_start_tt = time.localtime(timespan.start) searchList = [{'month_name' : time.strftime("%b", timespan_start_tt), 'year_name' : timespan_start_tt[0], - 'encoding' : encoding}, + 'encoding' : encoding, + 'page' : section_name}, self.outputted_dict] # Bind to the default_binding: diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py new file mode 100644 index 00000000..c35f4517 --- /dev/null +++ b/bin/weewx/gettext.py @@ -0,0 +1,135 @@ +# Simple localization for WeeWX +# Copyright (C) 2021 Johanna Roedenbeck + +from weewx.cheetahgenerator import SearchList +from weewx.units import ValueTuple,ValueHelper +import configobj +import weeutil.weeutil +import weeutil.config +import os +import os.path + +try: + # Test for new-style weewx v4 logging by trying to import weeutil.logger + import weeutil.logger + import logging + + log = logging.getLogger(__name__) + + def logdbg(msg): + log.debug(msg) + + def loginf(msg): + log.info(msg) + + def logerr(msg): + log.error(msg) + +except ImportError: + # Old-style weewx logging + import syslog + + def logmsg(level, msg): + syslog.syslog(level, 'gettext: %s' % msg) + + def logdbg(msg): + logmsg(syslog.LOG_DEBUG, msg) + + def loginf(msg): + logmsg(syslog.LOG_INFO, msg) + + def logerr(msg): + logmsg(syslog.LOG_ERR, msg) + + +class Gettext(SearchList): + + def __init__(self,generator): + """Create an instance of the class""" + super(Gettext,self).__init__(generator) + + + def get_extension_list(self,timespan,db_lookup): + + def locale_label(key='',page=''): + """ $gettext() + + key: key to look up for + page: section name + + """ + d=self.generator.skin_dict + + # get the appropriate section for page + try: + if 'Templates' in d: + sec = 'Templates' + elif 'Texts' in d: + sec = 'Texts' + else: + raise KeyError + if page: + d = d[sec][page] + if not isinstance(d,dict): + d={page:d} + else: + d = d[sec] + except (KeyError,IndexError,ValueError,TypeError): + d = {} + + if key: + + if key in d: + val = d[key] + else: + val = key + + return val + + if page: + cheetah_dict={} + if 'CheetahGenerator' in self.generator.skin_dict: + if page in self.generator.skin_dict['CheetahGenerator']: + cheetah_dict = self.generator.skin_dict['CheetahGenerator'][page] + + # + return FilesBinder(page,d,self.generator.skin_dict['Labels']['Generic'] if 'Generic' in self.generator.skin_dict else {},cheetah_dict) + + return [{'gettext':locale_label}] + + +class FilesBinder(object): + """ special labels for a specific page to be created by Cheetah """ + + def __init__(self,page,lang_files_dict,skin_labels_dict,cheetah_dict): + self.page=page + self.lang_files_dict=lang_files_dict + self.skin_labels_dict=skin_labels_dict + self.cheetah_dict=cheetah_dict + + def __getattr__(self,attr): + if attr in self.lang_files_dict: + # entry found in localization file + return self.lang_files_dict[attr] + elif attr in self.cheetah_dict: + # entry found [CheetahGenerator] subsection + return self.cheetah_dict[attr] + elif attr=='nav': + # if $locale(file='xxx').nav not in localization file, try + # nav_xxx in [Labels][[Generic]] section of skin.conf + if 'nav_'+self.page in self.skin_labels_dict: + return self.skin_labels_dict['nav_'+self.page] + elif attr=='page_header': + # if $locale(file='xxx').page_header not in localization file, + # try xxx_page_header in [Labels][[Generic]] section of skin.conf + x=self.page+'_page_header' + if x in self.skin_labels_dict: + return self.skin_labels_dict[x] + elif attr in self.skin_labels_dict: + # finally look in [Labels][[Generic]] section if skin.conf + #if attr=='html_description': + # loginf("html_description: %s" % self.skin_labels_dict[attr]) + return str(self.skin_labels_dict[attr]) + return '$%s.%s' % (self.page,attr) + + diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index c2563d6a..02eba18d 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -255,9 +255,9 @@ class StdReportEngine(threading.Thread): skin_dict[scalar] = self.config_dict['StdReport'][scalar] ####################################################################### - # localization support + # internationalization support - # If a localization is defined, get it. + # If an localization file is defined, get it. if 'lang_file' in self.config_dict['StdReport'][report]: # 'lang_file' defines the file name directly lang_config = self.config_dict['StdReport'][report]['lang_file'] @@ -269,7 +269,7 @@ class StdReportEngine(threading.Thread): # No localization defined. Use defaults. lang_config = None - # If a localization file could be determined, read it. + # If an localization file could be determined, read it. if lang_config: # Now add the options in the report's localization file. Start by figuring where it is located. diff --git a/skins/Seasons/celestial.inc b/skins/Seasons/celestial.inc index 68cc2592..47b5552b 100644 --- a/skins/Seasons/celestial.inc +++ b/skins/Seasons/celestial.inc @@ -49,14 +49,14 @@
- $obs.label.celestial_title + $gettext("Title",$page)
#if $almanac.hasExtras
- + @@ -122,7 +122,7 @@
☀ Sun
☀ $gettext("Sun",$page)
Start civil twilight $almanac(horizon=-6).sun(use_center=1).rise
- + diff --git a/skins/Seasons/current.inc b/skins/Seasons/current.inc index ea051a85..87a5149a 100644 --- a/skins/Seasons/current.inc +++ b/skins/Seasons/current.inc @@ -6,7 +6,7 @@
- $obs.label.current_conditions_title + $gettext("Current Conditions")
diff --git a/skins/Seasons/hilo.inc b/skins/Seasons/hilo.inc index d3e5988d..817378a5 100644 --- a/skins/Seasons/hilo.inc +++ b/skins/Seasons/hilo.inc @@ -8,7 +8,7 @@
diff --git a/skins/Seasons/identifier.inc b/skins/Seasons/identifier.inc index 1473ada4..c8a5a82e 100644 --- a/skins/Seasons/identifier.inc +++ b/skins/Seasons/identifier.inc @@ -10,15 +10,15 @@
☽ Moon
☽ $gettext("Moon",$page)
  
Rise
- + - + - + diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf index 8acfbcde..04dbac34 100644 --- a/skins/Seasons/lang/de.conf +++ b/skins/Seasons/lang/de.conf @@ -1,13 +1,16 @@ ############################################################################### -# Language Configuration File # +# Localization File # # German # +# Copyright (c) 2018-2021 Tom Keffer and Matthew Wall # +# Copyright (c) 2021 Johanna Karen Roedenbeck # +# See the file LICENSE.txt for your rights. # ############################################################################### [Units] # The following section overrides the label used for each type of unit [[Labels]] - meter = " m", " m" # You may prefer "metre". + meter = " m", " m" day = " Tag", " Tage" hour = " Stunde", " Stunden" minute = " Minute", " Minuten" @@ -96,3 +99,29 @@ # The labels to be used for the phases of the moon: moon_phases = Neumond, zunehmend, Halbmond, zunehmend, Vollmond, abnehmend, Halbmond, abnehmend + +[Texts] + + # Section Titles + "Current Conditions" = Aktuelle Werte + "Celestial" = Sonne und Mond + "HiLo" = "Höchst- und Tiefstwerte" + "Sensor Status" = "Sensorenstatus" + "About" = "Stationsdaten" + "Statistics" = "Statistik" + + # identifier.inc + "Latitude" = "geogr. Breite" + "Longitude" = "geogr. Länge" + "Altitude" = "Höhe" + + [[statistics]] + + "Title" = "Statistik" + + + [[celestial]] + + "Title" = "Sonne und Mond" + "Sun" = Sonne + "Moon" = Mond diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index 799e71ab..9550112c 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -1,6 +1,9 @@ ############################################################################### -# Language Configuration File # +# Localization File # # English # +# Copyright (c) 2018-2021 Tom Keffer and Matthew Wall # +# Copyright (c) 2021 Johanna Karen Roedenbeck # +# See the file LICENSE.txt for your rights. # ############################################################################### [Units] @@ -96,3 +99,29 @@ # The labels to be used for the phases of the moon: moon_phases = New, Waxing crescent, First quarter, Waxing gibbous, Full, Waning gibbous, Last quarter, Waning crescent + +[Texts] + + # Section Titles + "Current Conditions" = Current Conditions + "Celestial" = Celestial + "HiLo" = "High/Low" + "Sensor Status" = "Sensor Status" + "About" = "About this weather station" + "Statistics" = "Statistics" + + # identifier.inc + "Latitude" = "Latitude" + "Longitude" = "Longitude" + "Altitude" = "Altitude" + + + [[statistics]] + + "Title" = "Statiscs" + + [[celestial]] + + "Title" = "Celestial" + "Sun" = "Sun" + "Moon" = "Moon" diff --git a/skins/Seasons/statistics.inc b/skins/Seasons/statistics.inc index 30ed3bc1..f0cbcbc4 100644 --- a/skins/Seasons/statistics.inc +++ b/skins/Seasons/statistics.inc @@ -8,7 +8,7 @@
- $obs.label.statistics_title + $gettext("Title",$page)
From a93c09bea94dabeed7d7a5201c0d1f65bbb9f172 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 18 Apr 2021 11:44:05 +0200 Subject: [PATCH 04/30] adapted Seasons skin to $gettext --- skins/Seasons/about.inc | 8 +-- skins/Seasons/celestial.html.tmpl | 2 +- skins/Seasons/celestial.inc | 26 ++++----- skins/Seasons/hilo.inc | 10 ++-- skins/Seasons/identifier.inc | 2 +- skins/Seasons/index.html.tmpl | 10 ++-- skins/Seasons/lang/de.conf | 89 +++++++++++++++--------------- skins/Seasons/lang/en.conf | 82 +++++++++++++-------------- skins/Seasons/sensors.inc | 2 +- skins/Seasons/statistics.html.tmpl | 2 +- skins/Seasons/statistics.inc | 10 ++-- skins/Seasons/sunmoon.inc | 12 ++-- skins/Seasons/tabular.html.tmpl | 2 +- skins/Seasons/telemetry.html.tmpl | 10 ++-- skins/Seasons/titlebar.inc | 8 +-- 15 files changed, 139 insertions(+), 136 deletions(-) diff --git a/skins/Seasons/about.inc b/skins/Seasons/about.inc index 532981b7..55a872d8 100644 --- a/skins/Seasons/about.inc +++ b/skins/Seasons/about.inc @@ -6,7 +6,7 @@
- $obs.label.about_title + $gettext("About")
@@ -17,15 +17,15 @@
- + - + - + diff --git a/skins/Seasons/celestial.html.tmpl b/skins/Seasons/celestial.html.tmpl index 0b442a07..9b728422 100644 --- a/skins/Seasons/celestial.html.tmpl +++ b/skins/Seasons/celestial.html.tmpl @@ -31,7 +31,7 @@ #include "titlebar.inc"
-

❰ $obs.label.current_conditions_title

+

❰ $gettext("Current Conditions")

#include "celestial.inc" diff --git a/skins/Seasons/celestial.inc b/skins/Seasons/celestial.inc index 47b5552b..9b127228 100644 --- a/skins/Seasons/celestial.inc +++ b/skins/Seasons/celestial.inc @@ -62,7 +62,7 @@
- + @@ -70,7 +70,7 @@ - + @@ -78,19 +78,19 @@ - + - + - + - + #if $almanac.next_equinox.raw < $almanac.next_solstice.raw @@ -115,7 +115,7 @@ #end if - +
Latitude$gettext("Latitude") $station.latitude[0]° $station.latitude[1]' $station.latitude[2]
Longitude$gettext("Longitude") $station.longitude[0]° $station.longitude[1]' $station.longitude[2]
Altitude$gettext("Altitude") $station.altitude
$station.hardware
Latitude$gettext("Latitude") $station.latitude[0]° $station.latitude[1]' $station.latitude[2]
Longitude$gettext("Longitude") $station.longitude[0]° $station.longitude[1]' $station.longitude[2]
Altitude$gettext("GeoAltitude") $station.altitude
$almanac(horizon=-6).sun(use_center=1).rise
Rise$gettext("Rise",$page) $almanac.sun.rise.format(None_string=$sun_None)
$almanac.sun.transit
Set$gettext("Set",$page) $almanac.sun.set.format(None_string=$sun_None)
$almanac(horizon=-6).sun(use_center=1).set
Azimuth$gettext("Azimuth",$page) $("%.1f°" % $almanac.sun.az)
Altitude$gettext("AstroAltitude",$page) $("%.1f°" % $sun_altitude)
Right ascension$gettext("Right ascension",$page) $("%.1f°" % $almanac.sun.ra)
Declination$gettext("Declination",$page) $("%.1f°" % $almanac.sun.dec)
Total daylight$gettext("Daylight",$page) $daylight_str
@@ -125,7 +125,7 @@ ☽ $gettext("Moon",$page)    - Rise + $gettext("Rise",$page) $almanac.moon.rise @@ -133,24 +133,24 @@ $almanac.moon.transit - Set + $gettext("Set",$page) $almanac.moon.set    - Azimuth + $gettext("Azimuth",$page) $("%.1f°" % $almanac.moon.az) - Altitude + $gettext("AstroAltitude",$page) $("%.1f°" % $almanac.moon.alt) - Right ascension + $gettext("Right ascension",$page) $("%.1f°" % $almanac.moon.ra) - Declination + $gettext("Declination",$page) $("%.1f°" % $almanac.moon.dec) #if $almanac.next_full_moon.raw < $almanac.next_new_moon.raw diff --git a/skins/Seasons/hilo.inc b/skins/Seasons/hilo.inc index 817378a5..719c3921 100644 --- a/skins/Seasons/hilo.inc +++ b/skins/Seasons/hilo.inc @@ -18,15 +18,15 @@ -  
$obs.label.hilo_today -  
$obs.label.hilo_week -  
$obs.label.hilo_month +  
$gettext("Today") +  
$gettext("Week") +  
$gettext("Month")         
$obs.label.hilo_year
+ onclick="toggle_rainyear()">        
$gettext("Year") - Rain
Year
+ $gettext("Rainyear1")
$gettext("Rainyear2")
diff --git a/skins/Seasons/identifier.inc b/skins/Seasons/identifier.inc index c8a5a82e..fe1395e0 100644 --- a/skins/Seasons/identifier.inc +++ b/skins/Seasons/identifier.inc @@ -18,7 +18,7 @@ $station.longitude[0]° $station.longitude[1]' $station.longitude[2] - $gettext("Altitude") + $gettext("GeoAltitude") $station.altitude diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index a998c467..15e2bd0a 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -33,15 +33,15 @@
-
$obs.label.history_title:   +
$gettext("Plots",$page):   $obs.label.history_day + onclick="choose_history('day')">$gettext("Day") $obs.label.history_week + onclick="choose_history('week')">$gettext("Week") $obs.label.history_month + onclick="choose_history('month')">$gettext("Month") $obs.label.history_year + onclick="choose_history('year')">$gettext("Year")
$obs.label.barometer diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf index 04dbac34..e46fbeea 100644 --- a/skins/Seasons/lang/de.conf +++ b/skins/Seasons/lang/de.conf @@ -34,9 +34,9 @@ dewpoint = Taupunkt ET = ET heatindex = Hitzeindex - inHumidity = Raumluftfeuchtigkeit + inHumidity = Raumluftfeuchte inTemp = Raumtemperatur - outHumidity = Luftfeuchtigkeit + outHumidity = Luftfeuchte outTemp = Außentemperatur radiation = Sonnenstrahlung rain = Regen @@ -66,34 +66,6 @@ supplyVoltage = Versorgungsspannung referenceVoltage = Referenzspannung - # History - history_title = Diagramme - history_day = Tag - history_week = Woche - history_month = Monat - history_year = Jahr - - # Section Titles - current_conditions_title = Aktuelle Werte - celestial_title = Sonne und Mond - hilo_title = "Höchst- und Tiefstwerte" - sensor_status_title = "Sensorenstatus" - about_title = "Über diese Wetterstation" - statistics_title = "Statistik" - - # Reports - monthly_reports = "Monatswerte" - yearly_reports = "Jahreswerte" - select_month = "Monat wählen" - select_year = "Jahr wählen" - - # High/Low - hilo_today = Heute - hilo_week = Woche - hilo_month = Monat - hilo_year = Jahr - hilo_rainyear = Regenjahr - [Almanac] @@ -103,25 +75,54 @@ [Texts] # Section Titles - "Current Conditions" = Aktuelle Werte - "Celestial" = Sonne und Mond - "HiLo" = "Höchst- und Tiefstwerte" - "Sensor Status" = "Sensorenstatus" - "About" = "Stationsdaten" - "Statistics" = "Statistik" + "Current Conditions" = Aktuelle Werte + "Celestial" = Sonne und Mond + "HiLo" = "Höchst- und Tiefstwerte" + "Sensor Status" = "Sensorenstatus" + "About" = "Stationsdaten" + "Statistics" = "Statistik" + + # titlebar.inc + "Monthly Reports" = "Monatswerte" + "Yearly Reports" = "Jahreswerte" + "select month" = "Monat wählen" + "select year" = "Jahr wählen" # identifier.inc - "Latitude" = "geogr. Breite" - "Longitude" = "geogr. Länge" - "Altitude" = "Höhe" + "Latitude" = "geogr. Breite" + "Longitude" = "geogr. Länge" + "GeoAltitude" = "Höhe ü. NN" # geographisch + + # time spans + "Today" = Heute + "Day" = Tag + "Week" = Woche + "Month" = Monat + "Year" = Jahr + "Rainyear" = Regenjahr + "Rainyear1" = "Regen-" + "Rainyear2" = "jahr" + + [[index]] + + "Plots" = Diagramme + "Daylight" = "Tageslicht" [[statistics]] - "Title" = "Statistik" - + "Title" = "Statistik" [[celestial]] - "Title" = "Sonne und Mond" - "Sun" = Sonne - "Moon" = Mond + "Title" = "Sonne und Mond" + + "Sun" = Sonne + "Moon" = Mond + "Rise" = Aufgang + "Set" = Untergang + "Daylight" = Tageslicht gesamt + + "Azimuth" = Azimut + "AstroAltitude" = Höhe # astronomisch + "Right ascension" = Rektaszension + "Declination" = Deklination diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index 9550112c..de662450 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -67,33 +67,6 @@ supplyVoltage = Supply Voltage referenceVoltage = Reference Voltage - # History - history_title = History - history_day = Day - history_week = Week - history_month = Month - history_year = Year - - # Section Titles - current_conditions_title = Current Conditions - celestial_title = Celestial - hilo_title = "High/Low" - sensor_status_title = "Sensor Status" - about_title = "About this weather station" - statistics_title = "Statistics" - - # Reports - monthly_reports = "Monthly Reports" - yearly_reports = "Yearly Reports" - select_month = "Select Month" - select_year = "Select Year" - - # High/Low - hilo_today = Today - hilo_week = Week - hilo_month = Month - hilo_year = Year - hilo_rainyear = Rain Year [Almanac] @@ -103,25 +76,54 @@ [Texts] # Section Titles - "Current Conditions" = Current Conditions - "Celestial" = Celestial - "HiLo" = "High/Low" - "Sensor Status" = "Sensor Status" - "About" = "About this weather station" - "Statistics" = "Statistics" + "Current Conditions" = Current Conditions + "Celestial" = Celestial + "HiLo" = "High/Low" + "Sensor Status" = "Sensor Status" + "About" = "About this weather station" + "Statistics" = "Statistics" + + # titlebar.inc + "Monthly Reports" = "Monthly Reports" + "Yearly Reports" = "Yearly Reports" + "select month" = "Select Month" + "select year" = "Select Year" # identifier.inc - "Latitude" = "Latitude" - "Longitude" = "Longitude" - "Altitude" = "Altitude" + "Latitude" = "Latitude" + "Longitude" = "Longitude" + "GeoAltitude" = "Altitude" # geographic + # time spans + "Today" = Today + "Day" = Day + "Week" = Week + "Month" = Month + "Year" = Year + "Rainyear" = Rain Year + "Rainyear1" = "Rain" + "Rainyear2" = "Year" + + [[index]] + + "Plots" = History + "Daylight" = Daylight [[statistics]] - "Title" = "Statiscs" + "Title" = "Statiscs" [[celestial]] - "Title" = "Celestial" - "Sun" = "Sun" - "Moon" = "Moon" + "Title" = "Celestial" + "Sun" = "Sun" + "Moon" = "Moon" + "Rise" = Rise + "Set" = Set + "Daylight" = Total daylight + + "Azimuth" = Azimuth + "AstroAltitude" = Altitude # astronomical + "Right ascension" = Right ascension + "Declination" = Declination + diff --git a/skins/Seasons/sensors.inc b/skins/Seasons/sensors.inc index f93ebacc..df0fb47d 100644 --- a/skins/Seasons/sensors.inc +++ b/skins/Seasons/sensors.inc @@ -45,7 +45,7 @@ #if $have_conn or $have_battery_status or $have_voltage
diff --git a/skins/Seasons/statistics.html.tmpl b/skins/Seasons/statistics.html.tmpl index f1ffc9e9..79acb99e 100644 --- a/skins/Seasons/statistics.html.tmpl +++ b/skins/Seasons/statistics.html.tmpl @@ -39,7 +39,7 @@ #include "titlebar.inc"
-

❰ $obs.label.current_conditions_title

+

❰ $gettext("Current Conditions")

#include "statistics.inc" diff --git a/skins/Seasons/statistics.inc b/skins/Seasons/statistics.inc index f0cbcbc4..be03bd24 100644 --- a/skins/Seasons/statistics.inc +++ b/skins/Seasons/statistics.inc @@ -17,11 +17,11 @@ - $obs.label.hilo_today - $obs.label.hilo_week - $obs.label.hilo_month - $obs.label.hilo_year - $obs.label.hilo_rainyear + $gettext("Today") + $gettext("Week") + $gettext("Month") + $gettext("Year") + $gettext("Rainyear") $obs.label.outTemp diff --git a/skins/Seasons/sunmoon.inc b/skins/Seasons/sunmoon.inc index 8cc16e1c..36c51bdc 100644 --- a/skins/Seasons/sunmoon.inc +++ b/skins/Seasons/sunmoon.inc @@ -27,7 +27,7 @@
@@ -37,21 +37,21 @@ - + - + - + - + - + diff --git a/skins/Seasons/tabular.html.tmpl b/skins/Seasons/tabular.html.tmpl index aabfe729..6e940b17 100644 --- a/skins/Seasons/tabular.html.tmpl +++ b/skins/Seasons/tabular.html.tmpl @@ -23,7 +23,7 @@ #include "titlebar.inc" diff --git a/skins/Seasons/telemetry.html.tmpl b/skins/Seasons/telemetry.html.tmpl index ca6afe11..0484d17a 100644 --- a/skins/Seasons/telemetry.html.tmpl +++ b/skins/Seasons/telemetry.html.tmpl @@ -31,7 +31,7 @@ #include "titlebar.inc"
-

❰ $obs.label.current_conditions_title

+

❰ $gettext("Current Conditions")

#include "sensors.inc" @@ -41,13 +41,13 @@
Telemetry:   Day + onclick="choose_history('day')">$gettext("Day") Week + onclick="choose_history('week')">$gettext("Week") Month + onclick="choose_history('month')">$gettext("Month") Year + onclick="choose_history('year')">$gettext("Year")
$period_plots($day, 'day') diff --git a/skins/Seasons/titlebar.inc b/skins/Seasons/titlebar.inc index e94c0fd7..508c4dbe 100644 --- a/skins/Seasons/titlebar.inc +++ b/skins/Seasons/titlebar.inc @@ -11,20 +11,20 @@
- $obs.label.monthly_reports: + $gettext("Monthly Reports"):
- $obs.label.yearly_reports: + $gettext("Yearly Reports"):
From e6fcd789c46d553ec0c7ebacd357b196a295373b Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 18 Apr 2021 22:17:13 +0200 Subject: [PATCH 05/30] some documentation and case of empty key --- bin/weewx/gettext.py | 95 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 10 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index c35f4517..2c4b9773 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -1,6 +1,52 @@ # Simple localization for WeeWX # Copyright (C) 2021 Johanna Roedenbeck +# See the file LICENSE.txt for your full rights. + +""" + provides tag $gettext(key, page) + + Language dependent texts are stored in special localization files. + The are merged into skin_dict in reportengine.py according to the + language the user chooses in weewx.conf for the given report. + Different reports can be in different languages. + + The file defines language dependent label texts as well as other + texts used in skins. + + The values provided by $gettext(key, page) are found in the file + in the [Texts] section. Subsections in the [Texts] section can + provide special texts for certain templates. To get values from + subsections $gettext() is called with special tag $page for the + parameter page. That is especially useful in include files that + are included in multiple templates. + + Examples: + + Assume the localization file to be: + + [Texts] + Key1 = Text1 + [[index]] + Title = Text2 + [[othertemplate]] + Title = Text3 + + With that file is: + + $gettext("Key1") ==> Text1 + + $gettext("Title",$page) ==> is Text2 if included in template "index" + and Text3 if included in template + "othertemplate" + + $gettext(page=$page).Title ==> same as before + + You can use "speaking" key names. If they contain whitespace they need + to be enclosed in quotes in the localization file + +""" + from weewx.cheetahgenerator import SearchList from weewx.units import ValueTuple,ValueHelper import configobj @@ -69,33 +115,62 @@ class Gettext(SearchList): else: raise KeyError if page: + # page is specified --> get subsection "page" d = d[sec][page] if not isinstance(d,dict): d={page:d} else: + # otherwise get root section d = d[sec] - except (KeyError,IndexError,ValueError,TypeError): + except (KeyError,IndexError,ValueError,TypeError) as e: + # in case of errors get an empty dict + logerr("could not read %s %s: %s" % (sec,page,e)) d = {} - + + # if key is not empty, get the value for key if key: if key in d: + # key is in dict d --> return value of key val = d[key] else: + # otherwise return key as value val = key return val + # if key is empty but page is not return further class instance if page: cheetah_dict={} - if 'CheetahGenerator' in self.generator.skin_dict: - if page in self.generator.skin_dict['CheetahGenerator']: - cheetah_dict = self.generator.skin_dict['CheetahGenerator'][page] + cheetah_dict_key = 'CheetahGenerator' + if "FileGenerator" in self.generator.skin_dict and 'CheetahGenerator' not in self.generator.skin_dict: + cheetah_dict_key = "FileGenerator" + if cheetah_dict_key in self.generator.skin_dict: + cheetah_dict = _get_cheetah_dict(self.generator.skin_dict[cheetah_dict_key],page) + + labels_dict={} + if 'Labels' in self.generator.skin_dict: + if 'Generic' in self.generator.skin_dict['Labels']: + labels_dict = self.generator.skin_dict['Labels']['Generic'] # - return FilesBinder(page,d,self.generator.skin_dict['Labels']['Generic'] if 'Generic' in self.generator.skin_dict else {},cheetah_dict) + return FilesBinder(page,d,labels_dict,cheetah_dict) + # if key as well as page are empty + return FilesBinder('N/A',d,{},{}) + return [{'gettext':locale_label}] + + def _get_cheetah_dict(cheetah_dict,page): + """ find section page in cheetah_dict recursively """ + + for ii in cheetah_dict.sections: + jj = _get_cheetah_dict(cheetah_dict[ii],page) + if jj is not None: + return jj + if page in cheetah_dict: + return cheetah_dict[page] + return None class FilesBinder(object): @@ -115,20 +190,20 @@ class FilesBinder(object): # entry found [CheetahGenerator] subsection return self.cheetah_dict[attr] elif attr=='nav': - # if $locale(file='xxx').nav not in localization file, try + # if $gettext(page='xxx').nav not in localization file, try # nav_xxx in [Labels][[Generic]] section of skin.conf + # helpful for extending Belchertown skin if 'nav_'+self.page in self.skin_labels_dict: return self.skin_labels_dict['nav_'+self.page] elif attr=='page_header': - # if $locale(file='xxx').page_header not in localization file, + # if $gettext(page='xxx').page_header not in localization file, # try xxx_page_header in [Labels][[Generic]] section of skin.conf + # helpful for extending Belchertown skin x=self.page+'_page_header' if x in self.skin_labels_dict: return self.skin_labels_dict[x] elif attr in self.skin_labels_dict: # finally look in [Labels][[Generic]] section if skin.conf - #if attr=='html_description': - # loginf("html_description: %s" % self.skin_labels_dict[attr]) return str(self.skin_labels_dict[attr]) return '$%s.%s' % (self.page,attr) From e9281b272559b779c15c5cce7df9d0f0e6a02645 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Mon, 19 Apr 2021 20:06:30 +0200 Subject: [PATCH 06/30] $_ as alias for $gettext --- bin/weewx/gettext.py | 2 +- skins/Seasons/index.html.tmpl | 8 ++-- skins/Seasons/lang/de.conf | 83 ++++++++++++++++++++--------------- skins/Seasons/lang/en.conf | 81 +++++++++++++++++++--------------- 4 files changed, 99 insertions(+), 75 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 2c4b9773..1317372b 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -159,7 +159,7 @@ class Gettext(SearchList): # if key as well as page are empty return FilesBinder('N/A',d,{},{}) - return [{'gettext':locale_label}] + return [{'gettext':locale_label,'text':locale_label,'_':locale_label}] def _get_cheetah_dict(cheetah_dict,page): """ find section page in cheetah_dict recursively """ diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index 15e2bd0a..a2115dd9 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -35,13 +35,13 @@
$gettext("Plots",$page):   $gettext("Day") + onclick="choose_history('day')">$_("Day") $gettext("Week") + onclick="choose_history('week')">$_.Week $gettext("Month") + onclick="choose_history('month')">$_.Month $gettext("Year") + onclick="choose_history('year')">$_("Year")
$obs.label.barometer diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf index e46fbeea..80cd96ab 100644 --- a/skins/Seasons/lang/de.conf +++ b/skins/Seasons/lang/de.conf @@ -29,42 +29,55 @@ # Generic labels, keyed by an observation type. [[Generic]] - barometer = Luftdruck - pressure = abs. Luftdruck - dewpoint = Taupunkt - ET = ET - heatindex = Hitzeindex - inHumidity = Raumluftfeuchte - inTemp = Raumtemperatur - outHumidity = Luftfeuchte - outTemp = Außentemperatur - radiation = Sonnenstrahlung - rain = Regen - rainRate = Regen-Rate - UV = UV-Index - windDir = Windrichtung - windGust = Böen Geschwindigkeit - windGustDir = Böen Richtung - windSpeed = Windgeschwindigkeit - windchill = Windchill - windgustvec = Böen-Vektor - windvec = Wind-Vektor - extraTemp1 = Temperatur1 - extraTemp2 = Temperatur2 - extraTemp3 = Temperatur3 - + altimeter = Luftdruck (QNH) # QNH + altimeterRate = Luftdruckänderung + barometer = Luftdruck # QFF + barometerRate = Luftdruckänderung + pressure = abs. Luftdruck # QFE + pressureRate = Luftdruckänderung + dewpoint = Taupunkt + ET = ET + heatindex = Hitzeindex + inHumidity = Raumluftfeuchte + inTemp = Raumtemperatur + inDewpoint = Raumtaupunkt + outHumidity = Luftfeuchte + outTemp = Außentemperatur + radiation = Sonnenstrahlung + rain = Regen + rainRate = Regen-Rate + UV = UV-Index + windDir = Windrichtung + windGust = Böen Geschwindigkeit + windGustDir = Böen Richtung + windSpeed = Windgeschwindigkeit + windchill = Windchill + windgustvec = Böen-Vektor + windvec = Wind-Vektor + extraTemp1 = Temperatur1 + extraTemp2 = Temperatur2 + extraTemp3 = Temperatur3 + appTemp = gefühlte Temperatur + appTemp1 = gefühlte Temperatur + THSW = THSW-Index + lightning_distance = Blitzentfernung + lightning_strike_count = Blitzanzahl + cloudbase = Wolkenuntergrenze + + # used in Seasons skin but not defined + feel = gefühlte Temperatur + # Sensor status indicators - - rxCheckPercent = Signalqualität - txBatteryStatus = Übertragerbatteriestatus - windBatteryStatus = Anemometerbatteriestatus - rainBatteryStatus = Regenmesserbatteriestatus - outTempBatteryStatus = Außentemperatursensorbatteriestatus - inTempBatteryStatus = Innentemperatursensorbatteriestatus - consBatteryVoltage = Konsolenbatteriestatus - heatingVoltage = Heizungsspannung - supplyVoltage = Versorgungsspannung - referenceVoltage = Referenzspannung + rxCheckPercent = Signalqualität + txBatteryStatus = Übertragerbatteriestatus + windBatteryStatus = Anemometerbatteriestatus + rainBatteryStatus = Regenmesserbatteriestatus + outTempBatteryStatus = Außentemperatursensorbatteriestatus + inTempBatteryStatus = Innentemperatursensorbatteriestatus + consBatteryVoltage = Konsolenbatteriestatus + heatingVoltage = Heizungsspannung + supplyVoltage = Versorgungsspannung + referenceVoltage = Referenzspannung [Almanac] diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index de662450..90693812 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -27,45 +27,56 @@ # Generic labels, keyed by an observation type. [[Generic]] - barometer = Barometer - barometerRate = Barometer Change Rate - dewpoint = Dew Point - ET = ET - heatindex = Heat Index - inHumidity = Inside Humidity - inTemp = Inside Temperature - outHumidity = Humidity - outTemp = Outside Temperature - radiation = Radiation - rain = Rain - rainRate = Rain Rate - UV = UV Index - windDir = Wind Direction - windGust = Gust Speed - windGustDir = Gust Direction - windSpeed = Wind Speed - windchill = Wind Chill - windgustvec = Gust Vector - windvec = Wind Vector - windrun = Wind Run - extraTemp1 = Temperature1 - extraTemp2 = Temperature2 - extraTemp3 = Temperature3 + altimeter = Altimeter # QNH + altimeterRate = Altimeter Change Rate + barometer = Barometer # QFF + barometerRate = Barometer Change Rate + pressure = Pressure # QFE + pressureRate = Pressure Change Rate + dewpoint = Dew Point + ET = ET + heatindex = Heat Index + inHumidity = Inside Humidity + inTemp = Inside Temperature + inDewpoint = Inside Dew Point + outHumidity = Humidity + outTemp = Outside Temperature + radiation = Radiation + rain = Rain + rainRate = Rain Rate + UV = UV Index + windDir = Wind Direction + windGust = Gust Speed + windGustDir = Gust Direction + windSpeed = Wind Speed + windchill = Wind Chill + windgustvec = Gust Vector + windvec = Wind Vector + windrun = Wind Run + extraTemp1 = Temperature1 + extraTemp2 = Temperature2 + extraTemp3 = Temperature3 + appTemp = Apparent Temperature + appTemp1 = Apparent Temperature + THSW = THSW Index lightning_distance = Lightning Distance lightning_strike_count = Lightning Strikes + cloudbase = Cloud Base + + # used in Seasons skin, but not defined + feel = apparent temperature # Sensor status indicators - - rxCheckPercent = Signal Quality - txBatteryStatus = Transmitter Battery - windBatteryStatus = Wind Battery - rainBatteryStatus = Rain Battery - outTempBatteryStatus = Outside Temperature Battery - inTempBatteryStatus = Inside Temperature Battery - consBatteryVoltage = Console Battery - heatingVoltage = Heating Battery - supplyVoltage = Supply Voltage - referenceVoltage = Reference Voltage + rxCheckPercent = Signal Quality + txBatteryStatus = Transmitter Battery + windBatteryStatus = Wind Battery + rainBatteryStatus = Rain Battery + outTempBatteryStatus = Outside Temperature Battery + inTempBatteryStatus = Inside Temperature Battery + consBatteryVoltage = Console Battery + heatingVoltage = Heating Battery + supplyVoltage = Supply Voltage + referenceVoltage = Reference Voltage [Almanac] From 7d68f2861b835203e5a216e75ac778ba8af6c46f Mon Sep 17 00:00:00 2001 From: roe-dl Date: Tue, 20 Apr 2021 18:00:43 +0200 Subject: [PATCH 07/30] point 2+3: 'lang_file' removed, get 'lang' from skin_dict if not in config_dict --- bin/weewx/gettext.py | 10 +++++----- bin/weewx/reportengine.py | 27 ++++++++++++++++++--------- skins/Seasons/index.html.tmpl | 8 ++++---- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 1317372b..23f03da5 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -108,11 +108,11 @@ class Gettext(SearchList): # get the appropriate section for page try: - if 'Templates' in d: + if 'Templates' in d and 'Texts' not in d: sec = 'Templates' - elif 'Texts' in d: - sec = 'Texts' else: + sec = 'Texts' + if sec not in d: raise KeyError if page: # page is specified --> get subsection "page" @@ -124,7 +124,7 @@ class Gettext(SearchList): d = d[sec] except (KeyError,IndexError,ValueError,TypeError) as e: # in case of errors get an empty dict - logerr("could not read %s %s: %s" % (sec,page,e)) + logerr("could not read [%s] [[%s]]: %s" % (sec,page,e)) d = {} # if key is not empty, get the value for key @@ -159,7 +159,7 @@ class Gettext(SearchList): # if key as well as page are empty return FilesBinder('N/A',d,{},{}) - return [{'gettext':locale_label,'text':locale_label,'_':locale_label}] + return [{'gettext':locale_label,'text':locale_label}] def _get_cheetah_dict(cheetah_dict,page): """ find section page in cheetah_dict recursively """ diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index 02eba18d..7ba3a747 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -257,19 +257,27 @@ class StdReportEngine(threading.Thread): ####################################################################### # internationalization support - # If an localization file is defined, get it. - if 'lang_file' in self.config_dict['StdReport'][report]: - # 'lang_file' defines the file name directly - lang_config = self.config_dict['StdReport'][report]['lang_file'] - elif 'lang' in self.config_dict['StdReport'][report]: - # 'lang' defines a language code like 'en' or 'de' - # The file is located in subdirectory 'lang' of the skin directory then. - lang_config = "lang/%s.conf" % self.config_dict['StdReport'][report]['lang'] + # The key 'lang' defines a language code like 'en' or 'de'. It is + # used as a file name for a language file that is located in the + # 'lang' subdirectory of the skin directory. Like it is with the + # other path settings, a complete path overwrites the skin + # directory setting. + + # If an localization file is defined, determine the path. + # As config_dict is not merged into skin_dict so far, we + # need to check both. config_dict (weewx.conf) has the final say, + # so check it first. + if 'lang' in self.config_dict['StdReport'][report]: + # 'lang' is set in weewx.conf + lang_config = "%s.conf" % self.config_dict['StdReport'][report]['lang'] + elif 'lang' in self.skin_dict: + # 'lang' is set in skin.conf + lang_config = "%s.conf" % self.skin_dict['lang'] else: # No localization defined. Use defaults. lang_config = None - # If an localization file could be determined, read it. + # If an localization file name could be determined, read the file. if lang_config: # Now add the options in the report's localization file. Start by figuring where it is located. @@ -277,6 +285,7 @@ class StdReportEngine(threading.Thread): self.config_dict['WEEWX_ROOT'], self.config_dict['StdReport']['SKIN_ROOT'], self.config_dict['StdReport'][report].get('skin', ''), + 'lang', lang_config) # Now retrieve the language dictionary for the skin. Wrap it in a try block in case we fail. It is ok if diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index a2115dd9..15e2bd0a 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -35,13 +35,13 @@
$gettext("Plots",$page):   $_("Day") + onclick="choose_history('day')">$gettext("Day") $_.Week + onclick="choose_history('week')">$gettext("Week") $_.Month + onclick="choose_history('month')">$gettext("Month") $_("Year") + onclick="choose_history('year')">$gettext("Year")
$obs.label.barometer From 6e5cf961f0823110492e6db16bd8ee1395f8c620 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Tue, 20 Apr 2021 19:34:25 +0200 Subject: [PATCH 08/30] skin_dict, not self.skin_dict in _build_skin_dict() --- bin/weewx/reportengine.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index 7ba3a747..f95d4b9a 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -270,12 +270,15 @@ class StdReportEngine(threading.Thread): if 'lang' in self.config_dict['StdReport'][report]: # 'lang' is set in weewx.conf lang_config = "%s.conf" % self.config_dict['StdReport'][report]['lang'] - elif 'lang' in self.skin_dict: + log.debug("config_dict lang_config=%s for report %s" % (lang_config,report)) + elif 'lang' in skin_dict: # 'lang' is set in skin.conf - lang_config = "%s.conf" % self.skin_dict['lang'] + lang_config = "%s.conf" % skin_dict['lang'] + log.debug("skin_dict lang_config=%s for report" % (lang_config,report)) else: # No localization defined. Use defaults. lang_config = None + log.debug("no language defined for report %s" % report) # If an localization file name could be determined, read the file. if lang_config: From 8b59c633a73181d1ca8b66b47c9c180089144310 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Tue, 20 Apr 2021 21:57:25 +0200 Subject: [PATCH 09/30] some bugfixes --- bin/weewx/gettext.py | 57 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 23f03da5..cfa7fa06 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -94,7 +94,29 @@ class Gettext(SearchList): """Create an instance of the class""" super(Gettext,self).__init__(generator) + self.lang = self.generator.skin_dict.get('lang','undefined') + _idx = self.lang.rfind('/') + if _idx>=0: + self.lang = self.lang[_idx+1:] + _idx = self.lang.rfind('.conf') + if _idx>=0: + self.lang = self.lang[:_idx] + + self.labels_dict={} + if 'Labels' in self.generator.skin_dict: + if 'Generic' in self.generator.skin_dict['Labels']: + self.labels_dict = self.generator.skin_dict['Labels']['Generic'] + d=self.generator.skin_dict + if 'Texts' in d: + self.text_dict = d['Texts'] + elif 'Templates' in d: + self.text_dict = d['Templates'] + else: + self.text_dict = {} + if not isinstance(self.text_dict,dict): + self.text_dict = {} + def get_extension_list(self,timespan,db_lookup): def locale_label(key='',page=''): @@ -104,27 +126,18 @@ class Gettext(SearchList): page: section name """ - d=self.generator.skin_dict + d=self.text_dict - # get the appropriate section for page + # get the appropriate section for page if defined try: - if 'Templates' in d and 'Texts' not in d: - sec = 'Templates' - else: - sec = 'Texts' - if sec not in d: - raise KeyError if page: # page is specified --> get subsection "page" - d = d[sec][page] + d = d[page] if not isinstance(d,dict): d={page:d} - else: - # otherwise get root section - d = d[sec] except (KeyError,IndexError,ValueError,TypeError) as e: # in case of errors get an empty dict - logerr("could not read [%s] [[%s]]: %s" % (sec,page,e)) + logerr("could not read [[%s]]: %s" % (page,e)) d = {} # if key is not empty, get the value for key @@ -146,26 +159,20 @@ class Gettext(SearchList): if "FileGenerator" in self.generator.skin_dict and 'CheetahGenerator' not in self.generator.skin_dict: cheetah_dict_key = "FileGenerator" if cheetah_dict_key in self.generator.skin_dict: - cheetah_dict = _get_cheetah_dict(self.generator.skin_dict[cheetah_dict_key],page) - - labels_dict={} - if 'Labels' in self.generator.skin_dict: - if 'Generic' in self.generator.skin_dict['Labels']: - labels_dict = self.generator.skin_dict['Labels']['Generic'] - - # - return FilesBinder(page,d,labels_dict,cheetah_dict) + cheetah_dict = Gettext._get_cheetah_dict(self.generator.skin_dict[cheetah_dict_key],page) + return FilesBinder(page,d,self.labels_dict,cheetah_dict) # if key as well as page are empty - return FilesBinder('N/A',d,{},{}) + return FilesBinder('N/A',d,{},{'lang':self.lang}) return [{'gettext':locale_label,'text':locale_label}] - + + @staticmethod def _get_cheetah_dict(cheetah_dict,page): """ find section page in cheetah_dict recursively """ for ii in cheetah_dict.sections: - jj = _get_cheetah_dict(cheetah_dict[ii],page) + jj = Gettext._get_cheetah_dict(cheetah_dict[ii],page) if jj is not None: return jj if page in cheetah_dict: From a98b55aa3400fde8df0048b1d6acd300c5d4ef4f Mon Sep 17 00:00:00 2001 From: roe-dl Date: Wed, 21 Apr 2021 07:02:06 +0200 Subject: [PATCH 10/30] $text() removed, point 1 done with that --- bin/weewx/gettext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index cfa7fa06..561ac1ff 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -165,7 +165,7 @@ class Gettext(SearchList): # if key as well as page are empty return FilesBinder('N/A',d,{},{'lang':self.lang}) - return [{'gettext':locale_label,'text':locale_label}] + return [{'gettext':locale_label}] @staticmethod def _get_cheetah_dict(cheetah_dict,page): From fdd69b40b5807cc8dc920f5753e6c82d21e0c160 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Fri, 23 Apr 2021 06:34:59 +0200 Subject: [PATCH 11/30] --- skins/Seasons/celestial.html.tmpl | 2 +- skins/Seasons/index.html.tmpl | 5 ++--- skins/Seasons/lang/de.conf | 23 +++++++++++++++++++++++ skins/Seasons/lang/en.conf | 22 ++++++++++++++++++++++ skins/Seasons/statistics.html.tmpl | 2 +- skins/Seasons/tabular.html.tmpl | 2 +- skins/Seasons/telemetry.html.tmpl | 2 +- 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/skins/Seasons/celestial.html.tmpl b/skins/Seasons/celestial.html.tmpl index 9b728422..d48c5f67 100644 --- a/skins/Seasons/celestial.html.tmpl +++ b/skins/Seasons/celestial.html.tmpl @@ -3,7 +3,7 @@ #errorCatcher Echo #encoding UTF-8 - + $station.location Celestial Details diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index 15e2bd0a..1707763a 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -6,7 +6,7 @@ #encoding UTF-8 ## - + ## This choice should match the #encoding directive above @@ -160,8 +160,7 @@

- This station is controlled by WeeWX, an - experimental weather software system written in Python. + $gettext("footnote1")WeeWX$gettext("footnote2")

#include "analytics.inc" diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf index 80cd96ab..640747bc 100644 --- a/skins/Seasons/lang/de.conf +++ b/skins/Seasons/lang/de.conf @@ -29,6 +29,8 @@ # Generic labels, keyed by an observation type. [[Generic]] + dateTime = "Datum/Zeit" + interval = Intervall altimeter = Luftdruck (QNH) # QNH altimeterRate = Luftdruckänderung barometer = Luftdruck # QFF @@ -47,6 +49,7 @@ rain = Regen rainRate = Regen-Rate UV = UV-Index + wind = Wind windDir = Windrichtung windGust = Böen Geschwindigkeit windGustDir = Böen Richtung @@ -116,6 +119,10 @@ "Rainyear1" = "Regen-" "Rainyear2" = "jahr" + # footnote + "footnote1" = "Diese Station wird von " + "footnote2" = " gesteuert, einer experimentellen Wetter-Software, geschrieben in Python." + [[index]] "Plots" = Diagramme @@ -132,10 +139,26 @@ "Sun" = Sonne "Moon" = Mond "Rise" = Aufgang + "Transit" = Transit "Set" = Untergang + "Start civil twilight" = Dämmerungsbeginn + "End civil twilight" = Dämmerungsende "Daylight" = Tageslicht gesamt "Azimuth" = Azimut "AstroAltitude" = Höhe # astronomisch "Right ascension" = Rektaszension "Declination" = Deklination + + "Solstice" = Sonnenwende # Solstitium + "Equinox" = Tagundnachtgleiche # Äquinoktium + + "Full moon" = Vollmond + "New moon" = Neumond + "Phase" = Phase + + [[RSS]] + + "Weather Conditions" = Wetterbedingungen + "description" = "Aktuelle Werte und Tages-, Monats- und Jahreszusammenfassung" + "from" = aus diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index 90693812..e22793bb 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -27,6 +27,8 @@ # Generic labels, keyed by an observation type. [[Generic]] + dateTime = Time + interval = Interval altimeter = Altimeter # QNH altimeterRate = Altimeter Change Rate barometer = Barometer # QFF @@ -45,6 +47,7 @@ rain = Rain rainRate = Rain Rate UV = UV Index + wind = Wind windDir = Wind Direction windGust = Gust Speed windGustDir = Gust Direction @@ -115,6 +118,10 @@ "Rainyear1" = "Rain" "Rainyear2" = "Year" + # footnote + "footnote1" = "This station is controlled by " + "footnote2" = ", an experimental weather software system written in Python." + [[index]] "Plots" = History @@ -130,7 +137,10 @@ "Sun" = "Sun" "Moon" = "Moon" "Rise" = Rise + "Transit" = Transit "Set" = Set + "Start civil twilight" = Start civil twilight + "End civil twilight" = End civil twilight "Daylight" = Total daylight "Azimuth" = Azimuth @@ -138,3 +148,15 @@ "Right ascension" = Right ascension "Declination" = Declination + "Solstice" = Solstice + "Equinox" = Equinox + + "Full moon" = Full moon + "New moon" = New moon + "Phase" = Phase + + [[RSS]] + + "Weather Conditions" = Weather Conditions + "description" = Current conditions, and daily, monthly, and yearly summaries + "from" = from diff --git a/skins/Seasons/statistics.html.tmpl b/skins/Seasons/statistics.html.tmpl index 79acb99e..6b5bbd90 100644 --- a/skins/Seasons/statistics.html.tmpl +++ b/skins/Seasons/statistics.html.tmpl @@ -3,7 +3,7 @@ #errorCatcher Echo #encoding UTF-8 - + $station.location Statistics diff --git a/skins/Seasons/tabular.html.tmpl b/skins/Seasons/tabular.html.tmpl index 6e940b17..6898b2af 100644 --- a/skins/Seasons/tabular.html.tmpl +++ b/skins/Seasons/tabular.html.tmpl @@ -4,7 +4,7 @@ #encoding UTF-8 - + $station.location diff --git a/skins/Seasons/telemetry.html.tmpl b/skins/Seasons/telemetry.html.tmpl index 0484d17a..ce204897 100644 --- a/skins/Seasons/telemetry.html.tmpl +++ b/skins/Seasons/telemetry.html.tmpl @@ -18,7 +18,7 @@ #end def - + $station.location Telemetry From 4cd7a7ce13105663509bc4249fe5705c7aedd6a9 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Fri, 23 Apr 2021 20:58:13 +0200 Subject: [PATCH 12/30] changed user's guide to reflect the new features --- docs/usersguide.htm | 57 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/usersguide.htm b/docs/usersguide.htm index 0ff42c25..e00b5fc4 100644 --- a/docs/usersguide.htm +++ b/docs/usersguide.htm @@ -47,7 +47,7 @@

-Version: 4.5 +Version: 4.6
User's Guide to WeeWX
@@ -2264,7 +2264,9 @@ longitude = -77.0366

These are the four reports that actually generate HTML files and plots. They all ship in the standard WeeWX distribution. They all use US Customary units by default, but this can be changed by editing section [Defaults]. + href="#Section_Defaults">[Defaults] + or by the option target_unit/unit_system.

They all have the following options in common.

@@ -2274,6 +2276,57 @@ longitude = -77.0366 the directory should be any templates used by the skin and a skin configuration file, skin.conf.

+

lang

+

+ Which language to display the skin. + The value to this option is a two-character language code as defined in ISO 639-1. + It defines the language the skin shall be displayed in. + For each language, that a certain skin can display, an appropriate + language file resides in the + lang subdirectory of the + skin directory. It is named by the language code, appended + by .conf, for example + en.conf for English. + If there is no file for your language, + copy en.conf and translate + the texts on the right side of the equal signs to the + language you want to use. It is important that you name + the file according to the list in ISO 639-1. +

+ +

target_unit
+ unit_system

+

+ Which unit system to use with the skin. That can be + US, + METRIC, + METRICWX, or + METRICDE. + If the option is not set, the units set in the + [StdReport][[Defaults]] + section are used. If no defaults are + set, US is the default. + See the section "Changing + the unit system" in the "Customization Guide" + for more details. + The difference between METRICDE + and the other metric unit systems is that it uses + mm for rain and + km/h for wind. + Settings in the section + [[[Units]]][[[[Groups]]]] + overwrite the unit settings resulting from this option + for individual observation types. See "How to + change units" in the "Customization Guide" + for more details. +

+

enable

Set to true to enable the processing of this skin. Set to Date: Fri, 23 Apr 2021 21:35:07 +0200 Subject: [PATCH 13/30] target_unit/unit_system, bugfixes --- bin/weewx/gettext.py | 5 +++- bin/weewx/reportengine.py | 48 ++++++++++++++++++++++++++++++++++++++ skins/Seasons/lang/en.conf | 4 ++-- weewx.conf | 1 + 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 561ac1ff..74f28788 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -137,7 +137,10 @@ class Gettext(SearchList): d={page:d} except (KeyError,IndexError,ValueError,TypeError) as e: # in case of errors get an empty dict - logerr("could not read [[%s]]: %s" % (page,e)) + if self.text_dict: + logerr("could not read section [Texts][[%s]] for report %s: %s" % (page,self.generator.skin_dict.get('REPORT_NAME','unknown'),e)) + else: + logerr("no section [Texts] found for report %s: %s" % (self.generator.skin_dict.get('REPORT_NAME','unknown'),e)) d = {} # if key is not empty, get the value for key diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index f95d4b9a..37e12c61 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -309,6 +309,54 @@ class StdReportEngine(threading.Thread): lang_config_path, report, e) raise + # The key 'target_unit' or 'unit_system' defines the target unit + # system to be used with the report. The value can be 'US', + # 'METRIC', 'METRICWX', or 'METRICDE' + + # Check if a target unit system is defined. + if 'target_unit' in self.config_dict['StdReport'][report]: + # 'target_unit' is set in weewx.conf + target_unit = self.config_dict['StdReport'][report]['target_unit'] + elif 'unit_system' in self.config_dict['StdReport'][report]: + # 'unit_system' is set in weewx.conf + target_unit = self.config_dict['StdReport'][report]['unit_system'] + elif 'target_unit' in skin_dict: + # 'target_unit' is set in skin.conf + target_unit = skin_dict['target_unit'] + elif 'unit_system' in skin_dict: + # 'unit_system' is set in skin.conf + target_unit = skin_dict['unit_system'] + else: + # No unit system defined. Use defaults. + target_unit = None + log.debug("target unit system for report '%s': %s" % (report,target_unit)) + + # If a target unit system is defined get the appropriate dict + # out of units.py. + if target_unit: + + try: + merge_dict = weewx.units.std_groups[weewx.units.unit_constants[target_unit]] + except (KeyError,IndexError): + if target_unit=='METRICDE': + merge_dict = weewx.units.MetricUnits + merge_dict.prepend({ + 'group_rain':'mm', + 'group_rainrate':'mm_per_hour'}) + else: + merge_dict = {} + + merge_dict = {'Units':{'Groups':merge_dict}} + + try: + weeutil.config.merge_config(skin_dict, merge_dict) + if self.first_run: + log.info("Using unit system %s for report '%s'" % + (target_unit, report)) + except (SyntaxError,TypeError,IOError) as e: + log.error("error merging target unit system for report '%s'" % report) + pass + ####################################################################### # Finally, inject any overrides for this specific report. Because this is the last merge, it will have the diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index e22793bb..30a77c86 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -129,7 +129,7 @@ [[statistics]] - "Title" = "Statiscs" + "Title" = "Statistics" [[celestial]] @@ -158,5 +158,5 @@ [[RSS]] "Weather Conditions" = Weather Conditions - "description" = Current conditions, and daily, monthly, and yearly summaries + "description" = "Current conditions, and daily, monthly, and yearly summaries" "from" = from diff --git a/weewx.conf b/weewx.conf index ffadb58b..6aae7952 100644 --- a/weewx.conf +++ b/weewx.conf @@ -159,6 +159,7 @@ version = 4.5.1 # images, templates and plots for the report. skin = Seasons lang = en + target_unit = US enable = true [[SmartphoneReport]] From d069a5be6741f3cfe47d564fbf1536c1bd8daaea Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 24 Apr 2021 09:07:40 +0200 Subject: [PATCH 14/30] updated [Defaults] --> [StdReport][[Defaults]] in user's guide --- docs/usersguide.htm | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/docs/usersguide.htm b/docs/usersguide.htm index e00b5fc4..c85d7725 100644 --- a/docs/usersguide.htm +++ b/docs/usersguide.htm @@ -2263,10 +2263,11 @@ longitude = -77.0366

These are the four reports that actually generate HTML files and plots. They all ship in the standard WeeWX - distribution. They all use US Customary units by default, but this can be changed by editing section [Defaults] - or by the option target_unit/unit_system. + distribution. They all use US Customary units by default, but this can be changed + by setting the option target_unit/unit_system or + by editing section [StdReport][[Defaults]].

They all have the following options in common.

@@ -2465,6 +2466,28 @@ longitude = -77.0366 deleted on the remote server. Valid values are 1 to enable and 0 to disable. Required. Default is 0.

+

[[Defaults]]

+ +

+ This section defines default values for all skins. You can set: +

    +
  • units to be used with observation types
  • +
  • number and time formats
  • +
  • labels
  • +
  • calculation options for some derived values
  • +
+ See Customization Guide + for more details. +

+

+ If the skin you use comes with internationalization + support and you set a language by the + lang option, the settings + resulting from this option overwrite the settings in + the [[Defaults]] section. +

+ +

[StdConvert]

This section is for configuring the StdConvert service. This service acts as a @@ -3124,12 +3147,6 @@ longitude = -77.0366 Default is INNODB.

-

[Defaults]

-

- This section covers a suite of default values, which control things such as which unit system should be - used in reports, what label to be used for an observation type, and how it should be formatted. -

-

[Engine]

From 71bc1b09cd985acbf38f1df22a4966c2c7d2cc50 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 24 Apr 2021 13:21:36 +0200 Subject: [PATCH 15/30] first changes to the customization guide (to be continued) --- docs/customizing.htm | 179 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 4 deletions(-) diff --git a/docs/customizing.htm b/docs/customizing.htm index 8d8d650e..037194bf 100644 --- a/docs/customizing.htm +++ b/docs/customizing.htm @@ -807,6 +807,16 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\

+ + + + + + + @@ -884,6 +894,46 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\ wants to use the string Exterior Temperature, instead of Outside Temperature for the label for outTemp. The file includes no definition for inTemp.

+ +

+ Now suppose the skin author took care of internationalization + and provided language files. In this case s/he would not have + set the label in skin.conf but in + a language file, for English in + lang/en.conf, for german in + lang/de.conf etc. +

+

+ lang/en.conf would contain + what was defined in skin.conf + before: +

+
+...
+[Labels]
+    ...
+    [[Generic]]
+        ...
+        outTemp = Exterior Temperature
+
+

+ lang/de.conf would contain: +

+
+...
+[Labels]
+    ...
+    [[Generic]]
+        ...
+        outTemp = Außentemperatur
+        inTemp = Innentemperatur
+
+

+ The user sets the language by the optional + lang option in + weewx.conf. +

+

Finally, for purposes of illustrating precedence, suppose the [StdReport] section of weewx.conf contains this: @@ -904,6 +954,10 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\ [[[Labels]]] [[[[Generic]]]] outTemp = Barn Temperature + + [[LifeC]] + skin = Life + lang = de

@@ -931,20 +985,31 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\

+ + + + +
Rise$gettext("Rise","celestial") $almanac.sun.rise.format(None_string=$sun_None)  Rise$gettext("Rise","celestial") $almanac.moon.rise
Set$gettext("Set","celestial") $almanac.sun.set.format(None_string=$sun_None)  Set$gettext("Set","celestial") $almanac.moon.set
Daylight$gettext("Daylight",$page) $daylight_str   [[[Labels]]] / [[[[Generic]]]] Highest precedence. Has the final say.
skins/report_name/ lang/language_code.confAffects only the report report_name.[Labels] / [[Generic]]Internationalization support. Preferably + supplied by the skin author.
weewx.conf [StdReport] / [[Defaults]]Inside Temperature Barn Temperature
LifeCInnentemperaturAußentemperatur

- Note how the values specified for inTemp are not overridden anywhere, so the value + Note how the values specified for inTemp + are not overridden anywhere, except + lang/de.conf, so the value specified in weewx/defaults.py, that is, Inside Temperature, is used for all reports.

+ class="code">Inside Temperature, is used for all reports, + except LifeC.

The value for outTemp is not overridden for report SeasonsA, so it uses the label specified in weewx/defaults.py, that is, Outside Temperature. By contrast, for the "Life" reports, a value for outTemp was specified in the skin so, in the absence of any user override, its value, Exterior - Temperature will be used as the new default. Finally, for the report LifeB, + Temperature will be used as the new default. For the report LifeB, the user has specified an override for outTemp, so that value, Barn Temperature, is used. + Finally, for the report LifeC + a language has been set, so the labels are taken from the + specified language file.

@@ -1119,7 +1184,40 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\

To accomplish this, we will generate two reports, one using the defaults, the other using overrides to - change the target unit system and the target directory. The section [StdReport] + change the target unit system and the target directory. +

+

+ If you only want to use one of the predefined unit systems + like US or + METRIC you can simply specify + a unit system in the report configuration like this: +

+
+[StdReport]
+
+    # Where the skins reside, relative to WEEWX_ROOT
+    SKIN_ROOT = skins
+
+    # Where the generated reports should go, relative to WEEWX_ROOT
+    HTML_ROOT = public_html
+
+    # The database binding indicates which data should be used in reports.
+    data_binding = wx_binding
+
+    [[SeasonsUSReport]]
+        skin = Seasons
+        target_unit = US
+        enable = true
+
+    [[SeasonsMetricReport]]
+        skin = Seasons
+        target_unit = METRIC
+        enable = true
+        HTML_ROOT = public_html/metric
+

+ If you need individual settings for a lot of units you + can specify the units directly in the report configuration. + In this case the section [StdReport] will look like this:

@@ -2928,6 +3026,79 @@ $month.outTemp.series(aggregate_type='max', aggregate_interval='day', time_serie
             Tags for series.
         

+

General tags

+ +

+ There are some general tags, that do not reflect observation + data but technical data of processing the template files. + You can especially use them in #if + expressions to control how Cheetah processes the template. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TagDescription
$month_nameName of the month, the file is created for
$year_nameYear, the file is created for
$encodingCharacter encoding, to which the file is converted + after creation. Possible values are + html_entities, + strict_ascii, + normalized_ascii, and + utf-8. +
$pageName of the page that is actually processed. + This is the section name from + skin.conf + where the template is described. You can especially + use it in include files that are included in multiple + templates. So parts of the content defined in the include + file can depend on the template file, for example + header lines. You can also use it together with + $gettext to structure + the language file.
$gettext.langLanguage code set by the + lang option + for the report. You can use this tag in + #if expressions and + to include language codes where the HTML + specification requires them. +
$gettext(page=$page).template + File name of the template actually processed +
+ + +

+ Internationalization support with + $gettext +

+ +

+ +

+

Almanac

From f4f2ecc57e3b8a091b0d4380b59838a68d7ded84 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 24 Apr 2021 14:59:04 +0200 Subject: [PATCH 16/30] further changes to the customization guide (to be continued) --- docs/customizing.htm | 130 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/docs/customizing.htm b/docs/customizing.htm index 037194bf..88ff3593 100644 --- a/docs/customizing.htm +++ b/docs/customizing.htm @@ -3094,10 +3094,138 @@ $month.outTemp.series(aggregate_type='max', aggregate_interval='day', time_serie Internationalization support with $gettext +

+ Web pages and other files to be created do not only contain + observation values and their labels but also static text. + The $gettext tag provides + internationalization support for those static texts. + To support internationalization do not write static + text into to template or include files but use + $gettext there to define it. +

+

+ Suppose you write a skin called + "YourSkin" + and + you want to have a head line in there, that + is "Current Conditions" in English, but "aktuelle Werte" + in german, "Conditions actuelles" in french etc. Then + the template file could contain: +

+
...
+<h1>$gettext("Current Conditions")</h1>
+...
+

+ The section of weewx.conf + configuring your skin could now look like this: +

+
...
+[StdReport]
+    ...
+    [[YourSkinReport]]
+        skin = YourSkin
+        lang = fr
+    ...
+

+ With lang = fr the report + is in french. To get it in English, replace the language + code fr by the code for English + en. And to get it in german + use de. +

+

+ To make that work a language file has to be created for + each language supported. The language files reside in + the lang subdirectory of the + skin directory that is defined by the + skin option. The file name + of the language file is the language code appended + by .conf, for example + en.conf, + de.conf, or + fr.conf. +

+

+ The language file has the same layout as + skin.conf, i.e. + you can put language specific versions of the labels there. + Additionally a section [Texts] + can be defined to hold the static texts used in the skin. + For the example above the language files would contain + the following: +

+

en.conf

+
...
+[Texts]
+    "Current Conditions" = Current Conditions
+    ...
+

de.conf

+
...
+[Texts]
+    "Current Conditions" = Aktuelle Werte
+    ...
+

fr.conf

+
...
+[Texts]
+    "Current Conditions" = Conditions actuelles
+        
+

+ While it is not technically necessary we recommend to use + the whole English text for key. The template is easier to + read then. And it is easier for the person who translates + the texts if the original English version of the text is + found on the left side. But there are cases when that is + not possible, and then you can use any string you find + reasonable enough to describe the entry. +

+

+ See the SKIN_ROOT/Seasons/lang + subdirectory for examples of language files. +

- + If your skin is big and there are lots of texts to define + you can structure the [Texts] + section by subsections. Each template can have its own + subsection. The subsections need to be called identically + to the respective sections in skin.conf. +

+

+ Assuming you have a template section called + [[[index]]] and another + section called [[[othertemplate]]], + then the language files could look like this:

+
...
+[Texts]
+    ...some general texts here...
+    [[index]]
+        ...some texts for template index here, for example
+        Key = Some text
+    [[othertemplate]]
+        ...some texts for template othertemplate here, for example
+        Key = Some other text
+

+ To refer to these template specific texts add + $page as parameter to + $gettext(). For example: +

+
...
+$gettext("Key",$page)
+...
+

+ If template "index" is processed, the entry "Key" in + subsection [[index]] is + used, and the value is "Some text". + If template "othertemplate" is processed, the + entry "Key" in subsection + [[othertemplate]] + is used, and the value is "Some other text". + You can place this tag in an include file + that is called by both "index" and "othertemplate", + and the value is chosen from the appropriate subsection. +

+

Almanac

From 476caf6a6b0b190c8ebc5130667af74ada0c6d43 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 24 Apr 2021 19:17:01 +0200 Subject: [PATCH 17/30] more changes to the customization guide (to be continued) --- docs/customizing.htm | 209 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 179 insertions(+), 30 deletions(-) diff --git a/docs/customizing.htm b/docs/customizing.htm index 88ff3593..2f6e65bc 100644 --- a/docs/customizing.htm +++ b/docs/customizing.htm @@ -44,7 +44,7 @@

-Version: 4.5 +Version: 4.6
WeeWX Customization Guide
@@ -4444,10 +4444,49 @@ class MyStats(SearchList): # 1

Localization

- This section is provides suggestions for localization, including translation to different languages and + This section provides suggestions for localization, + including translation to different languages and display of data in formats specific to a locale.

+ +

If localization is already done

+

+ First look whether the skin already came with a localization + for your language. If there is a + lang subdirectory in the skin + directory, look into it. There you find a file for each + language this skin is already localized to. If your + language is there, all you need to do is to select it + in weewx.conf: +

+
...
+[StdReport]
+    ...
+    [[TheSkin]]
+        skin = skin_directory
+        lang = language_code
+        ...
+

If only your language is missing

+ +

+ If the lang subdirectory + is present in the skin directory the skin is + probably prepared already for localization. + The only thing to do then is translating. + To do so, copy the file + en.conf and name it + according to the language code of your language. + Then translate all the strings on the right + side of the equal signs to your language. + The skin author may be interested in your + language file to ship it together with the + skin for the use of other users. + Last set the language code in + weewx.conf + as described in the previous section. +

+

How to localize a single report

@@ -4456,15 +4495,37 @@ class MyStats(SearchList): # 1 formats and language.

+

Create the language file

+ +

+ Create a subdirectory called lang + in the skin directory. + + Then create a file named by the language code with the + suffix .conf. For example, if + you want to translate to spanish, name the file + es.conf. + The next step is + to make the templates language-aware as described in the + following section. +

+

Translate the templates

- In every HTML template (these typically have a file suffix of .html.tmpl) change - the HTML "lang" attribute to the target language. For example, for Spanish use es: + Open the template file and the language file in different + editor windows. It is much easier if you can change both + files simultaneously. +

+ +

+ In every HTML template (these typically have a file suffix of + .html.tmpl) change + the HTML "lang" attribute to a configurable value.

 <!DOCTYPE html>
-<html lang="es">
+<html lang="$gettext.lang">
   <head>
     <meta charset="UTF-8">
     ...
@@ -4497,12 +4558,26 @@ class MyStats(SearchList):                                                   # 1
         
 <div id='current_widget' class="widget">
   <div class="widget_title">
-    Conditions Actuelle
+    $gettext("Current Conditions")
     <a class="widget_control"
       onclick="toggle_widget('current')">&diams;</a>
   </div>
         
- +

+ In the language file start a + [Texts] section and place the + translation there like: +

+
...
+[Texts]
+    ...
+    "Current Conditions" = Conditions Actuelles
+    ...
+

+ Repeat that for all strings you find. Make sure not + to replace HTML tags and HTML options. +

+

Translate labels and modify local options

@@ -4619,13 +4694,21 @@ class MyStats(SearchList): # 1 locales? This example shows how to translate the Seasons skin for multiple languages.

- Create a directory for each language. Each directory contains template files and a skin configuration file. - Any text in each template file should be in the target language. Ensure that each HTML template file has the - lang set properly. + Create a subdirectory called + lang in the skin directory. + The language files containing the language dependent + information go there. Start creating a language file + for the primary language and save it to the + lang directory. The name + of the file consists of the language code of the + target language and the suffix + .conf. Later on you can + create language files for each language you want + to support based on that file.

- Translate observation names and other labels, and put them into the skin configuration files. There should - be one configuration file for each language. + Translate observation names and other labels, and put them + into the created language file.

Ensure that any locale-specific formatting is specified properly. For example, consider the

- The result will be a directory of templates and configurations, with one directory for each + Static texts are localized using the + $gettext("original text") tag. + Create a section [Texts] + in the language file and place a line +

+
"original text" = translated text
+

+ there in each language file. In the template file you refer + to those texts by +

+
$gettext("original text")
+

+ According to the language setting of the report the tag + stands for the text in the appropriate language. +

+ +

+ The result will be a directory of language files + with one file for each language/localization.

-
-skins/Seasons/
-skins/Seasons/en/skin.conf
-skins/Seasons/en/index.html.tmpl
-skins/Seasons/es/skin.conf
-skins/Seasons/es/index.html.tmpl
-skins/Seasons/de/skin.conf
-skins/Seasons/de/index.html.tmpl
-skins/Seasons/fr/skin.conf
-skins/Seasons/fr/index.html.tmpl

Users will then create each report in the WeeWX configuration file. @@ -4657,16 +4748,20 @@ skins/Seasons/fr/index.html.tmpl

 [StdReport]
     [[Seasons_en]]
-        skin = Seasons/en
+        skin = Seasons
+        lang = en
         HTML_ROOT = public_html/en
     [[Seasons_es]]
-        skin = Seasons/es
+        skin = Seasons
+        lang = es
         HTML_ROOT = public_html/es
     [[Seasons_de]]
-        skin = Seasons/de
+        skin = Seasons
+        lang = de
         HTML_ROOT = public_html/de
     [[Seasons_fr]]
-        skin = Seasons/fr
+        skin = Seasons
+        lang = fr
         HTML_ROOT = public_html/fr

The result is multiple reports, each in a different language and localization, independent of the locale of @@ -5961,7 +6056,23 @@ xstats/bin/user/xstats.py

This section contains the options available in the skin configuration file, skin.conf. + class="code">skin.conf. The same options apply to the + language files found in the subdirectory + lang, like + lang/en.conf for English. +

+

+ We recommend to put +

    +
  • + options that control the behavior of the skin into + skin.conf and +
  • +
  • + language dependent labels and texts into the + language files. +
  • +

@@ -6369,10 +6480,48 @@ growing_base = 50.0, degree_F class="code">time_delta will be accepted. Default is 300 seconds.

- +

[Texts]

+ +

+ This section applies to language files only. +

+

+ The section [Texts] holds + static texts that are used in the templates. + Generally there are multiple language files, each file + for one language and named by the language code + defined in ISO 639-1. + The entries + give the translation of the texts to the target language, like +

+
"English text" = same text in the target language
+

+ or define texts by keys that can be refereced within the template. +

+
"Key" = some text to display
+

+ To use the English text for the key is recommended, because + the template is easier to read then and while translating + you see the original English text on the left side. +

+

+ Note!
+ Strings that include commas must be included in single or + double quotes. +

+

+ There may be subsections, named like the template + subsections in the + [CheetahGenerator] section of + skin.conf. The entries defined + in such subsections apply to the respective template only. +

[CheetahGenerator]

-

This section contains the options for the Cheetah generator.

+

This section contains the options for the Cheetah generator. + It applies to skin.conf only.

search_list

From c12d7b6d1f76f6be0243021ced1376e4cbf3ab76 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 24 Apr 2021 20:07:02 +0200 Subject: [PATCH 18/30] localize Seasons skin RSS; METRICDE removed --- bin/weewx/reportengine.py | 8 +-- skins/Seasons/lang/de.conf | 12 ++++ skins/Seasons/lang/en.conf | 12 ++++ skins/Seasons/rss.xml.tmpl | 144 ++++++++++++++++++------------------- 4 files changed, 97 insertions(+), 79 deletions(-) diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index 37e12c61..f5f5d4ae 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -338,13 +338,7 @@ class StdReportEngine(threading.Thread): try: merge_dict = weewx.units.std_groups[weewx.units.unit_constants[target_unit]] except (KeyError,IndexError): - if target_unit=='METRICDE': - merge_dict = weewx.units.MetricUnits - merge_dict.prepend({ - 'group_rain':'mm', - 'group_rainrate':'mm_per_hour'}) - else: - merge_dict = {} + merge_dict = {} merge_dict = {'Units':{'Groups':merge_dict}} diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf index 640747bc..522ab012 100644 --- a/skins/Seasons/lang/de.conf +++ b/skins/Seasons/lang/de.conf @@ -162,3 +162,15 @@ "Weather Conditions" = Wetterbedingungen "description" = "Aktuelle Werte und Tages-, Monats- und Jahreszusammenfassung" "from" = aus + "Min outside temperature" = Außentemperatur Minimum + "Max outside temperature" = Außentemperatur Maximum + "Min inside temperature" = Innentemperatur Minimum + "Max inside temperature" = Innentemperatur Maximum + "Min barometer" = Luftdruck Minimum + "Max barometer" = Luftdruck Maximum + "Max wind" = Max Wind + "Rain today" = Regen heute + "Weather Conditions at" = Wetter am + "Yearly Weather Summary as of" = Jahreszusammenfassung zum + "Monthly Weather Summary as of" = Monatszusammenfassung zum + "Daily Weather Summary as of" = Tageszusammenfassung für den diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index 30a77c86..2cd6f9e3 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -160,3 +160,15 @@ "Weather Conditions" = Weather Conditions "description" = "Current conditions, and daily, monthly, and yearly summaries" "from" = from + "Min outside temperature" = Min outside temperature + "Max outside temperature" = Max outside temperature + "Min inside temperature" = Min inside temperature + "Max inside temperature" = Max inside temperature + "Min barometer" = Min barometer + "Max barometer" = Max barometer + "Max wind" = Max wind + "Rain today" = Rain today + "Weather Conditions at" = Weather Conditions at + "Yearly Weather Summary as of" = Yearly Weather Summary as of + "Monthly Weather Summary as of" = Monthly Weather Summary as of + "Daily Weather Summary as of" = Daily Weather Summary as of diff --git a/skins/Seasons/rss.xml.tmpl b/skins/Seasons/rss.xml.tmpl index 6f9d38dd..5f933b14 100644 --- a/skins/Seasons/rss.xml.tmpl +++ b/skins/Seasons/rss.xml.tmpl @@ -3,10 +3,10 @@ xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" > - $station.location, Weather Conditions + $station.location, $gettext("Weather Conditions",$page) $station.station_url - Current conditions, and daily, monthly, and yearly summaries - en-us + $gettext("description",$page) + $gettext.lang $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") @@ -18,116 +18,116 @@ Weather Conditions at $current.dateTime $station.station_url - Outside temperature: $current.outTemp; - Barometer: $current.barometer; - Wind: $current.windSpeed from $current.windDir; - Rain rate: $current.rainRate; - Inside temperature: $current.inTemp + $obs.label.outTemp: $current.outTemp; + $obs.label.barometer: $current.barometer; + $obs.label.wind: $current.windSpeed $gettext("from",$page) $current.windDir; + $obs.label.rainRate: $current.rainRate; + $obs.label.inTemp: $current.inTemp $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") $station.latitude_f $station.longitude_f - Time: $current.dateTime
- Outside Temperature: $current.outTemp
- Inside Temperature: $current.inTemp
- Wind Chill: $current.windchill
- Heat Index: $current.heatindex
- Dewpoint: $current.dewpoint
- Humidity: $current.outHumidity
- Barometer: $current.barometer
- Wind: $current.windSpeed from $current.windDir
- Rain Rate: $current.rainRate
+ $obs.label.dateTime: $current.dateTime
+ $obs.label.outTemp: $current.outTemp
+ $obs.label.inTemp: $current.inTemp
+ $obs.label.windchill: $current.windchill
+ $obs.label.heatindex: $current.heatindex
+ $obs.label.dewpoint: $current.dewpoint
+ $obs.label.outHumidity: $current.outHumidity
+ $obs.label.barometer: $current.barometer
+ $obs.label.wind: $current.windSpeed $gettext("from",$page) $current.windDir
+ $obs.label.rainRate: $current.rainRate

]]>
- Daily Weather Summary as of $current.dateTime + $gettext("Daily Weather Summary as of",$page) $current.dateTime $station.station_url - Min outside temperature: $day.outTemp.min at $day.outTemp.mintime; - Max outside temperature: $day.outTemp.max at $day.outTemp.maxtime; - Min inside temperature: $day.inTemp.min at $day.inTemp.mintime; - Max inside temperature: $day.inTemp.max at $day.inTemp.maxtime; - Min barometer: $day.barometer.min at $day.barometer.mintime; - Max barometer: $day.barometer.max at $day.barometer.maxtime; - Max wind : $day.wind.max from $day.wind.gustdir at $day.wind.maxtime; - Rain today: $day.rain.sum + $gettext("Min outside temperature",$page): $day.outTemp.min at $day.outTemp.mintime; + $gettext("Max outside temperature",$page): $day.outTemp.max at $day.outTemp.maxtime; + $gettext("Min inside temperature",$page): $day.inTemp.min at $day.inTemp.mintime; + $gettext("Max inside temperature",$page): $day.inTemp.max at $day.inTemp.maxtime; + $gettext("Min barometer",$page): $day.barometer.min at $day.barometer.mintime; + $gettext("Max barometer",$page): $day.barometer.max at $day.barometer.maxtime; + $gettext("Max wind",$page) : $day.wind.max $gettext("from",$page) $day.wind.gustdir at $day.wind.maxtime; + $gettext("Rain today",$page): $day.rain.sum $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") $station.latitude_f $station.longitude_f - Day: $day.dateTime.format("%d %b %Y")
- Min Outside Temperature: $day.outTemp.min at $day.outTemp.mintime
- Max Outside Temperature: $day.outTemp.max at $day.outTemp.maxtime
- Min Inside Temperature: $day.inTemp.min at $day.inTemp.mintime
- Max Inside Temperature: $day.inTemp.max at $day.inTemp.maxtime
- Min Barometer: $day.barometer.min at $day.barometer.mintime
- Max Barometer: $day.barometer.max at $day.barometer.maxtime
- Max Wind : $day.wind.max from $day.wind.gustdir at $day.wind.maxtime
- Rain today: $day.rain.sum
+ $gettext("Day"): $day.dateTime.format("%d %b %Y")
+ $gettext("Min Outside Temperature",$page): $day.outTemp.min at $day.outTemp.mintime
+ $gettext("Max Outside Temperature",$page): $day.outTemp.max at $day.outTemp.maxtime
+ $gettext("Min Inside Temperature",$page): $day.inTemp.min at $day.inTemp.mintime
+ $gettext("Max Inside Temperature",$page): $day.inTemp.max at $day.inTemp.maxtime
+ $gettext("Min Barometer",$page): $day.barometer.min at $day.barometer.mintime
+ $gettext("Max Barometer",$page): $day.barometer.max at $day.barometer.maxtime
+ $gettext("Max Wind",$page) : $day.wind.max $gettext("from",$page) $day.wind.gustdir at $day.wind.maxtime
+ $gettext("Rain today",$page): $day.rain.sum

]]>
- Monthly Weather Summary as of $current.dateTime + $gettext("Monthly Weather Summary as of",$page) $current.dateTime $station.station_url - Min outside temperature: $month.outTemp.min at $month.outTemp.mintime; - Max outside temperature: $month.outTemp.max at $month.outTemp.maxtime; - Min inside temperature: $month.inTemp.min at $month.inTemp.mintime; - Max inside temperature: $month.inTemp.max at $month.inTemp.maxtime; - Min barometer: $month.barometer.min at $month.barometer.mintime; - Max barometer: $month.barometer.max at $month.barometer.maxtime; - Max wind : $month.wind.max from $month.wind.gustdir at $month.wind.maxtime; - Rain total for month: $month.rain.sum + $gettext("Min outside temperature",$page): $month.outTemp.min at $month.outTemp.mintime; + $gettext("Max outside temperature",$page): $month.outTemp.max at $month.outTemp.maxtime; + $gettext("Min inside temperature",$page): $month.inTemp.min at $month.inTemp.mintime; + $gettext("Max inside temperature",$page): $month.inTemp.max at $month.inTemp.maxtime; + $gettext("Min barometer",$page): $month.barometer.min at $month.barometer.mintime; + $gettext("Max barometer",$page): $month.barometer.max at $month.barometer.maxtime; + $gettext("Max wind",$page) : $month.wind.max $gettext("from",$page) $month.wind.gustdir at $month.wind.maxtime; + $gettext("Rain total for month",$page): $month.rain.sum $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") - Month: $month.dateTime.format("%B %Y")
- Max Outside Temperature: $month.outTemp.max at $month.outTemp.maxtime
- Min Outside Temperature: $month.outTemp.min at $month.outTemp.mintime
- Max Inside Temperature: $month.inTemp.max at $month.inTemp.maxtime
- Min Inside Temperature: $month.inTemp.min at $month.inTemp.mintime
- Min Barometer: $month.barometer.min at $month.barometer.mintime
- Max Barometer: $month.barometer.max at $month.barometer.maxtime
- Max Wind : $month.wind.max from $month.wind.gustdir at $month.wind.maxtime
- Rain total for month: $month.rain.sum
+ $gettext("Month"): $month.dateTime.format("%B %Y")
+ $gettext("Max Outside Temperature",$page): $month.outTemp.max at $month.outTemp.maxtime
+ $gettext("Min Outside Temperature",$page): $month.outTemp.min at $month.outTemp.mintime
+ $gettext("Max Inside Temperature",$page): $month.inTemp.max at $month.inTemp.maxtime
+ $gettext("Min Inside Temperature",$page): $month.inTemp.min at $month.inTemp.mintime
+ $gettext("Min Barometer",$page): $month.barometer.min at $month.barometer.mintime
+ $gettext("Max Barometer",$page): $month.barometer.max at $month.barometer.maxtime
+ $gettext("Max Wind",$page) : $month.wind.max $gettext("from",$page) $month.wind.gustdir at $month.wind.maxtime
+ $gettext("Rain total for month",$page): $month.rain.sum

]]>
- Yearly Weather Summary as of $current.dateTime + $gettext("Yearly Weather Summary as of",$page) $current.dateTime $station.station_url - Min outside temperature: $year.outTemp.min at $year.outTemp.mintime; - Max outside temperature: $year.outTemp.max at $year.outTemp.maxtime; - Min inside temperature: $year.inTemp.min at $year.inTemp.mintime; - Max inside temperature: $year.inTemp.max at $year.inTemp.maxtime; - Min barometer: $year.barometer.min at $year.barometer.mintime; - Max barometer: $year.barometer.max at $year.barometer.maxtime; - Max wind : $year.wind.max from $year.wind.gustdir at $year.wind.maxtime; - Rain total for year: $year.rain.sum + $gettext("Min outside temperature",$page): $year.outTemp.min at $year.outTemp.mintime; + $gettext("Max outside temperature",$page): $year.outTemp.max at $year.outTemp.maxtime; + $gettext("Min inside temperature",$page): $year.inTemp.min at $year.inTemp.mintime; + $gettext("Max inside temperature",$page): $year.inTemp.max at $year.inTemp.maxtime; + $gettext("Min barometer",$page): $year.barometer.min at $year.barometer.mintime; + $gettext("Max barometer",$page): $year.barometer.max at $year.barometer.maxtime; + $gettext("Max wind",$page) : $year.wind.max $gettext("from",$page) $year.wind.gustdir at $year.wind.maxtime; + $gettext("Rain total for year",$page): $year.rain.sum $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") - Year: $year.dateTime.format("%Y")
- Max Outside Temperature: $year.outTemp.max at $year.outTemp.maxtime
- Min Outside Temperature: $year.outTemp.min at $year.outTemp.mintime
- Max Inside Temperature: $year.inTemp.max at $year.inTemp.maxtime
- Min Inside Temperature: $year.inTemp.min at $year.inTemp.mintime
- Min Barometer: $year.barometer.min at $year.barometer.mintime
- Max Barometer: $year.barometer.max at $year.barometer.maxtime
- Max Wind : $year.wind.max from $year.wind.gustdir at $year.wind.maxtime
- Rain total for year: $year.rain.sum
+ $gettext("Year"): $year.dateTime.format("%Y")
+ $gettext("Max Outside Temperature",$page): $year.outTemp.max at $year.outTemp.maxtime
+ $gettext("Min Outside Temperature",$page): $year.outTemp.min at $year.outTemp.mintime
+ $gettext("Max Inside Temperature",$page): $year.inTemp.max at $year.inTemp.maxtime
+ $gettext("Min Inside Temperature",$page): $year.inTemp.min at $year.inTemp.mintime
+ $gettext("Min Barometer",$page): $year.barometer.min at $year.barometer.mintime
+ $gettext("Max Barometer",$page): $year.barometer.max at $year.barometer.maxtime
+ $gettext("Max Wind",$page) : $year.wind.max $gettext("from",$page) $year.wind.gustdir at $year.wind.maxtime
+ $gettext("Rain total for year",$page): $year.rain.sum

]]>
From 5ea72bbf26bf2eec06f64c826fb9be1798d0d2e3 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sat, 24 Apr 2021 20:58:58 +0200 Subject: [PATCH 19/30] minor fixes to the user's guide --- docs/usersguide.htm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/usersguide.htm b/docs/usersguide.htm index c85d7725..410a7101 100644 --- a/docs/usersguide.htm +++ b/docs/usersguide.htm @@ -2277,7 +2277,7 @@ longitude = -77.0366 the directory should be any templates used by the skin and a skin configuration file, skin.conf.

-

lang

+

lang

Which language to display the skin. The value to this option is a two-character language code as defined in

  • labels
  • calculation options for some derived values
  • - See
    Customization Guide + See the Customization Guide for more details.

    From 44e2f14dc5ec5613050ad8176debcf6697ec1bbd Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 25 Apr 2021 15:54:47 +0200 Subject: [PATCH 20/30] target_unit removed; only unit_system remains; reviewed gettext.py (not complete) --- bin/weewx/gettext.py | 62 +++++++++++++++------------------------ bin/weewx/reportengine.py | 26 +++++++--------- docs/customizing.htm | 7 +++-- docs/usersguide.htm | 5 ++-- 4 files changed, 40 insertions(+), 60 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 74f28788..9ad11e99 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -48,44 +48,27 @@ """ from weewx.cheetahgenerator import SearchList -from weewx.units import ValueTuple,ValueHelper -import configobj -import weeutil.weeutil -import weeutil.config -import os -import os.path +#from weewx.units import ValueTuple,ValueHelper +#import configobj +#import weeutil.weeutil +#import weeutil.config +#import os +#import os.path -try: - # Test for new-style weewx v4 logging by trying to import weeutil.logger - import weeutil.logger - import logging +# Test for new-style weewx v4 logging by trying to import weeutil.logger +import weeutil.logger +import logging - log = logging.getLogger(__name__) +log = logging.getLogger(__name__) - def logdbg(msg): - log.debug(msg) +def logdbg(msg): + log.debug(msg) - def loginf(msg): - log.info(msg) +def loginf(msg): + log.info(msg) - def logerr(msg): - log.error(msg) - -except ImportError: - # Old-style weewx logging - import syslog - - def logmsg(level, msg): - syslog.syslog(level, 'gettext: %s' % msg) - - def logdbg(msg): - logmsg(syslog.LOG_DEBUG, msg) - - def loginf(msg): - logmsg(syslog.LOG_INFO, msg) - - def logerr(msg): - logmsg(syslog.LOG_ERR, msg) +def logerr(msg): + log.error(msg) class Gettext(SearchList): @@ -94,6 +77,8 @@ class Gettext(SearchList): """Create an instance of the class""" super(Gettext,self).__init__(generator) + # get the set language code + # (needed for things like self.lang = self.generator.skin_dict.get('lang','undefined') _idx = self.lang.rfind('/') if _idx>=0: @@ -102,16 +87,17 @@ class Gettext(SearchList): if _idx>=0: self.lang = self.lang[:_idx] + # check if skin_dict contains a section [Labels][[Generic]] + # get it, if it is there, otherwise use an empty dict self.labels_dict={} if 'Labels' in self.generator.skin_dict: if 'Generic' in self.generator.skin_dict['Labels']: self.labels_dict = self.generator.skin_dict['Labels']['Generic'] - d=self.generator.skin_dict - if 'Texts' in d: - self.text_dict = d['Texts'] - elif 'Templates' in d: - self.text_dict = d['Templates'] + # check if skin_dict contains a section [Texts] + # get if it is there, otherwise use an empty dict + if 'Texts' in self.generator.skin_dict: + self.text_dict = self.generator.skin_dict['Texts'] else: self.text_dict = {} if not isinstance(self.text_dict,dict): diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index f5f5d4ae..9e6c0a0e 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -309,34 +309,28 @@ class StdReportEngine(threading.Thread): lang_config_path, report, e) raise - # The key 'target_unit' or 'unit_system' defines the target unit + # The key 'unit_system' defines the target unit # system to be used with the report. The value can be 'US', # 'METRIC', 'METRICWX', or 'METRICDE' # Check if a target unit system is defined. - if 'target_unit' in self.config_dict['StdReport'][report]: - # 'target_unit' is set in weewx.conf - target_unit = self.config_dict['StdReport'][report]['target_unit'] - elif 'unit_system' in self.config_dict['StdReport'][report]: + if 'unit_system' in self.config_dict['StdReport'][report]: # 'unit_system' is set in weewx.conf - target_unit = self.config_dict['StdReport'][report]['unit_system'] - elif 'target_unit' in skin_dict: - # 'target_unit' is set in skin.conf - target_unit = skin_dict['target_unit'] + unit_system = self.config_dict['StdReport'][report]['unit_system'] elif 'unit_system' in skin_dict: # 'unit_system' is set in skin.conf - target_unit = skin_dict['unit_system'] + unit_system = skin_dict['unit_system'] else: # No unit system defined. Use defaults. - target_unit = None - log.debug("target unit system for report '%s': %s" % (report,target_unit)) + unit_system = None + log.debug("unit system for report '%s': %s" % (report,unit_system)) - # If a target unit system is defined get the appropriate dict + # If a unit system is defined get the appropriate dict # out of units.py. - if target_unit: + if unit_system: try: - merge_dict = weewx.units.std_groups[weewx.units.unit_constants[target_unit]] + merge_dict = weewx.units.std_groups[weewx.units.unit_constants[unit_system]] except (KeyError,IndexError): merge_dict = {} @@ -346,7 +340,7 @@ class StdReportEngine(threading.Thread): weeutil.config.merge_config(skin_dict, merge_dict) if self.first_run: log.info("Using unit system %s for report '%s'" % - (target_unit, report)) + (unit_system, report)) except (SyntaxError,TypeError,IOError) as e: log.error("error merging target unit system for report '%s'" % report) pass diff --git a/docs/customizing.htm b/docs/customizing.htm index 2f6e65bc..8eef5266 100644 --- a/docs/customizing.htm +++ b/docs/customizing.htm @@ -443,7 +443,8 @@ Version: 4.6

    Each report has a skin associated with it. For most reports, the relationship with the skin is an - obvious one: it contains the templates, any auxiliary files such as background GIFs or CSS style sheets, and + obvious one: it contains the templates, any auxiliary files such as background + GIFs or CSS style sheets, files with localization data, and a skin configuration file, skin.conf. If you will, the skin controls the look and feel of the report. Note that more than one report can use the same skin. For example, you might want to run a report that uses US Customary units, then run another report against the same skin, but @@ -1206,12 +1207,12 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\ [[SeasonsUSReport]] skin = Seasons - target_unit = US + unit_system = US enable = true [[SeasonsMetricReport]] skin = Seasons - target_unit = METRIC + unit_system = METRIC enable = true HTML_ROOT = public_html/metric

    diff --git a/docs/usersguide.htm b/docs/usersguide.htm index 410a7101..b99c512e 100644 --- a/docs/usersguide.htm +++ b/docs/usersguide.htm @@ -2264,7 +2264,7 @@ longitude = -77.0366

    These are the four reports that actually generate HTML files and plots. They all ship in the standard WeeWX distribution. They all use US Customary units by default, but this can be changed - by setting the option target_unit/unit_system or by editing section [StdReport][[Defaults]]. @@ -2297,8 +2297,7 @@ longitude = -77.0366 the file according to the list in ISO 639-1.

    -

    target_unit
    - unit_system

    +

    unit_system

    Which unit system to use with the skin. That can be US, From 02e0b6e5e56bee96c0fd7a084533069e7b01cbda Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 25 Apr 2021 16:43:51 +0200 Subject: [PATCH 21/30] further changes to gettext.py --- bin/weewx/gettext.py | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 9ad11e99..252e248e 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -45,15 +45,12 @@ You can use "speaking" key names. If they contain whitespace they need to be enclosed in quotes in the localization file + If the value contains commas you must enclose it in single or double + quotes. Otherwise an array instead of a string is returned. + """ from weewx.cheetahgenerator import SearchList -#from weewx.units import ValueTuple,ValueHelper -#import configobj -#import weeutil.weeutil -#import weeutil.config -#import os -#import os.path # Test for new-style weewx v4 logging by trying to import weeutil.logger import weeutil.logger @@ -100,6 +97,7 @@ class Gettext(SearchList): self.text_dict = self.generator.skin_dict['Texts'] else: self.text_dict = {} + # if 'Texts' is not a section but an option, use an empty dict if not isinstance(self.text_dict,dict): self.text_dict = {} @@ -112,29 +110,29 @@ class Gettext(SearchList): page: section name """ - d=self.text_dict + _text_dict = self.text_dict # get the appropriate section for page if defined try: if page: # page is specified --> get subsection "page" - d = d[page] - if not isinstance(d,dict): - d={page:d} + _text_dict = _text_dict[page] + if not isinstance(_text_dict,dict): + _text_dict={page:_text_dict} except (KeyError,IndexError,ValueError,TypeError) as e: # in case of errors get an empty dict if self.text_dict: logerr("could not read section [Texts][[%s]] for report %s: %s" % (page,self.generator.skin_dict.get('REPORT_NAME','unknown'),e)) else: logerr("no section [Texts] found for report %s: %s" % (self.generator.skin_dict.get('REPORT_NAME','unknown'),e)) - d = {} + _text_dict = {} # if key is not empty, get the value for key if key: - if key in d: - # key is in dict d --> return value of key - val = d[key] + if key in _text_dict: + # key is in dict _text_dict --> return value of key + val = _text_dict[key] else: # otherwise return key as value val = key @@ -149,10 +147,10 @@ class Gettext(SearchList): cheetah_dict_key = "FileGenerator" if cheetah_dict_key in self.generator.skin_dict: cheetah_dict = Gettext._get_cheetah_dict(self.generator.skin_dict[cheetah_dict_key],page) - return FilesBinder(page,d,self.labels_dict,cheetah_dict) + return FilesBinder(page,_text_dict,self.labels_dict,cheetah_dict) # if key as well as page are empty - return FilesBinder('N/A',d,{},{'lang':self.lang}) + return FilesBinder('N/A',_text_dict,{},{'lang':self.lang}) return [{'gettext':locale_label}] @@ -160,10 +158,10 @@ class Gettext(SearchList): def _get_cheetah_dict(cheetah_dict,page): """ find section page in cheetah_dict recursively """ - for ii in cheetah_dict.sections: - jj = Gettext._get_cheetah_dict(cheetah_dict[ii],page) - if jj is not None: - return jj + for section in cheetah_dict.sections: + subsection = Gettext._get_cheetah_dict(cheetah_dict[section],page) + if subsection is not None: + return subsection if page in cheetah_dict: return cheetah_dict[page] return None From 710dc314811c82f8fc421ec054e54cb70d232661 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 25 Apr 2021 17:22:15 +0200 Subject: [PATCH 22/30] added and corrected comments in reportengine.py --- bin/weewx/reportengine.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index 9e6c0a0e..9d172b87 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -309,16 +309,19 @@ class StdReportEngine(threading.Thread): lang_config_path, report, e) raise - # The key 'unit_system' defines the target unit - # system to be used with the report. The value can be 'US', - # 'METRIC', 'METRICWX', or 'METRICDE' + # The key 'unit_system' defines the unit system to be used with + # the report. The value can be 'US', 'METRIC', or 'METRICWX' # Check if a target unit system is defined. + # As config_dict is not merged into skin_dict so far, we + # need to check both. config_dict (weewx.conf) has the final say, + # so check it first. if 'unit_system' in self.config_dict['StdReport'][report]: # 'unit_system' is set in weewx.conf unit_system = self.config_dict['StdReport'][report]['unit_system'] elif 'unit_system' in skin_dict: - # 'unit_system' is set in skin.conf + # 'unit_system' is set in skin_dict, which is merged from + # serveral sources including skin.conf unit_system = skin_dict['unit_system'] else: # No unit system defined. Use defaults. @@ -326,16 +329,20 @@ class StdReportEngine(threading.Thread): log.debug("unit system for report '%s': %s" % (report,unit_system)) # If a unit system is defined get the appropriate dict - # out of units.py. + # out of units.py. If the user defined addtional units or + # unit groups, they are included here automatically. if unit_system: + # get the chosen unit system out of units.py try: merge_dict = weewx.units.std_groups[weewx.units.unit_constants[unit_system]] except (KeyError,IndexError): merge_dict = {} + # build dict to merge merge_dict = {'Units':{'Groups':merge_dict}} + # merge into skin_dict try: weeutil.config.merge_config(skin_dict, merge_dict) if self.first_run: From 3357034e4d77c8d4dd12c2efcae907edc2356459 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Mon, 26 Apr 2021 11:05:23 +0200 Subject: [PATCH 23/30] code improvements --- bin/weewx/gettext.py | 56 ++++++++++----------------------------- bin/weewx/reportengine.py | 4 +++ 2 files changed, 18 insertions(+), 42 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 252e248e..d6d85996 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -1,5 +1,5 @@ # Simple localization for WeeWX -# Copyright (C) 2021 Johanna Roedenbeck +# Copyright (C) 2021 Johanna Karen Roedenbeck # See the file LICENSE.txt for your full rights. @@ -58,15 +58,6 @@ import logging log = logging.getLogger(__name__) -def logdbg(msg): - log.debug(msg) - -def loginf(msg): - log.info(msg) - -def logerr(msg): - log.error(msg) - class Gettext(SearchList): @@ -84,22 +75,6 @@ class Gettext(SearchList): if _idx>=0: self.lang = self.lang[:_idx] - # check if skin_dict contains a section [Labels][[Generic]] - # get it, if it is there, otherwise use an empty dict - self.labels_dict={} - if 'Labels' in self.generator.skin_dict: - if 'Generic' in self.generator.skin_dict['Labels']: - self.labels_dict = self.generator.skin_dict['Labels']['Generic'] - - # check if skin_dict contains a section [Texts] - # get if it is there, otherwise use an empty dict - if 'Texts' in self.generator.skin_dict: - self.text_dict = self.generator.skin_dict['Texts'] - else: - self.text_dict = {} - # if 'Texts' is not a section but an option, use an empty dict - if not isinstance(self.text_dict,dict): - self.text_dict = {} def get_extension_list(self,timespan,db_lookup): @@ -110,24 +85,21 @@ class Gettext(SearchList): page: section name """ - _text_dict = self.text_dict + _text_dict = self.generator.skin_dict.get('Texts',{}) # get the appropriate section for page if defined - try: - if page: - # page is specified --> get subsection "page" - _text_dict = _text_dict[page] - if not isinstance(_text_dict,dict): - _text_dict={page:_text_dict} - except (KeyError,IndexError,ValueError,TypeError) as e: - # in case of errors get an empty dict - if self.text_dict: - logerr("could not read section [Texts][[%s]] for report %s: %s" % (page,self.generator.skin_dict.get('REPORT_NAME','unknown'),e)) - else: - logerr("no section [Texts] found for report %s: %s" % (self.generator.skin_dict.get('REPORT_NAME','unknown'),e)) - _text_dict = {} + # Note: no hierarchy here + if page: + if not page in _text_dict: + log.error("could not find section [Texts][[%s]] for report %s" % (page,self.generator.skin_dict.get('REPORT_NAME','unknown'))) + # Note: no 'else:' here, because we need the empty dict + # page is specified --> get subsection "page" + _text_dict = _text_dict.get(page,{}) + # if the result is not a dict, make it a dict + if not isinstance(_text_dict,dict): + _text_dict={page:_text_dict} - # if key is not empty, get the value for key + # if key is not empty, get the value for key if key: if key in _text_dict: @@ -147,7 +119,7 @@ class Gettext(SearchList): cheetah_dict_key = "FileGenerator" if cheetah_dict_key in self.generator.skin_dict: cheetah_dict = Gettext._get_cheetah_dict(self.generator.skin_dict[cheetah_dict_key],page) - return FilesBinder(page,_text_dict,self.labels_dict,cheetah_dict) + return FilesBinder(page,_text_dict,self.generator.skin_dict.get('Labels',{}).get('Generic',{}),cheetah_dict) # if key as well as page are empty return FilesBinder('N/A',_text_dict,{},{'lang':self.lang}) diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index 9d172b87..e26a4ccf 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -296,6 +296,10 @@ class StdReportEngine(threading.Thread): try: merge_dict = configobj.ConfigObj(lang_config_path, file_error=True, encoding='utf-8') log.debug("Found localization file %s for report '%s'", lang_config_path, report) + # make sure 'Texts' is a dict (section) + if not isinstance(merge_dict.get('Texts',{}),dict): + log.error("'Texts' is not a section in '%s'" % lang_config_path) + merge_dict['Texts']={} # Merge the skin config file in: weeutil.config.merge_config(skin_dict, merge_dict) if self.first_run: From ff71a145c21580baa926fe26d4d1011de176e873 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Mon, 26 Apr 2021 14:14:39 +0200 Subject: [PATCH 24/30] more code improvements --- bin/weewx/gettext.py | 12 +----------- bin/weewx/reportengine.py | 9 ++++++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index d6d85996..d7c95c83 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -65,16 +65,6 @@ class Gettext(SearchList): """Create an instance of the class""" super(Gettext,self).__init__(generator) - # get the set language code - # (needed for things like - self.lang = self.generator.skin_dict.get('lang','undefined') - _idx = self.lang.rfind('/') - if _idx>=0: - self.lang = self.lang[_idx+1:] - _idx = self.lang.rfind('.conf') - if _idx>=0: - self.lang = self.lang[:_idx] - def get_extension_list(self,timespan,db_lookup): @@ -122,7 +112,7 @@ class Gettext(SearchList): return FilesBinder(page,_text_dict,self.generator.skin_dict.get('Labels',{}).get('Generic',{}),cheetah_dict) # if key as well as page are empty - return FilesBinder('N/A',_text_dict,{},{'lang':self.lang}) + return FilesBinder('N/A',_text_dict,{},{}) return [{'gettext':locale_label}] diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index e26a4ccf..e26b4bb9 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -296,10 +296,13 @@ class StdReportEngine(threading.Thread): try: merge_dict = configobj.ConfigObj(lang_config_path, file_error=True, encoding='utf-8') log.debug("Found localization file %s for report '%s'", lang_config_path, report) - # make sure 'Texts' is a dict (section) - if not isinstance(merge_dict.get('Texts',{}),dict): - log.error("'Texts' is not a section in '%s'" % lang_config_path) + # make sure 'Texts' is present and a dict (section) + if not isinstance(merge_dict.get('Texts',None),dict): + if 'Texts' in merge_dict: + log.error("'Texts' is not a section in '%s'" % lang_config_path) merge_dict['Texts']={} + # set language code for $gettext.lang + merge_dict['Texts']['lang'] = os.path.basename(lang_config_path).split('.')[0] # Merge the skin config file in: weeutil.config.merge_config(skin_dict, merge_dict) if self.first_run: From d8a0d46af578ab93d2ded97a6271c12ec51c9bbd Mon Sep 17 00:00:00 2001 From: roe-dl Date: Mon, 26 Apr 2021 15:21:01 +0200 Subject: [PATCH 25/30] little change --- bin/weewx/gettext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index d7c95c83..4605f2be 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -112,7 +112,7 @@ class Gettext(SearchList): return FilesBinder(page,_text_dict,self.generator.skin_dict.get('Labels',{}).get('Generic',{}),cheetah_dict) # if key as well as page are empty - return FilesBinder('N/A',_text_dict,{},{}) + return _text_dict return [{'gettext':locale_label}] From 041e2528472228f401f073dd3ffb99a090f110da Mon Sep 17 00:00:00 2001 From: roe-dl Date: Tue, 27 Apr 2021 17:38:38 +0200 Subject: [PATCH 26/30] changes according to review --- bin/weewx/gettext.py | 75 ++++++++---------------------------- bin/weewx/reportengine.py | 81 ++++++++++----------------------------- docs/customizing.htm | 4 +- docs/usersguide.htm | 9 ++--- weewx.conf | 2 +- 5 files changed, 43 insertions(+), 128 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 4605f2be..2e1824f0 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -51,6 +51,8 @@ """ from weewx.cheetahgenerator import SearchList +from weeutil.weeutil import KeyDict +import weeutil.config # Test for new-style weewx v4 logging by trying to import weeutil.logger import weeutil.logger @@ -61,11 +63,6 @@ log = logging.getLogger(__name__) class Gettext(SearchList): - def __init__(self,generator): - """Create an instance of the class""" - super(Gettext,self).__init__(generator) - - def get_extension_list(self,timespan,db_lookup): def locale_label(key='',page=''): @@ -80,36 +77,30 @@ class Gettext(SearchList): # get the appropriate section for page if defined # Note: no hierarchy here if page: - if not page in _text_dict: + if page not in _text_dict: log.error("could not find section [Texts][[%s]] for report %s" % (page,self.generator.skin_dict.get('REPORT_NAME','unknown'))) # Note: no 'else:' here, because we need the empty dict # page is specified --> get subsection "page" _text_dict = _text_dict.get(page,{}) - # if the result is not a dict, make it a dict - if not isinstance(_text_dict,dict): - _text_dict={page:_text_dict} # if key is not empty, get the value for key if key: - - if key in _text_dict: - # key is in dict _text_dict --> return value of key - val = _text_dict[key] - else: - # otherwise return key as value - val = key + # return the value for key + # if key not in _text_dict return key instead + return KeyDict(_text_dict)[key] - return val - + # if key is empty but page is not return further class instance if page: - cheetah_dict={} - cheetah_dict_key = 'CheetahGenerator' - if "FileGenerator" in self.generator.skin_dict and 'CheetahGenerator' not in self.generator.skin_dict: - cheetah_dict_key = "FileGenerator" - if cheetah_dict_key in self.generator.skin_dict: - cheetah_dict = Gettext._get_cheetah_dict(self.generator.skin_dict[cheetah_dict_key],page) - return FilesBinder(page,_text_dict,self.generator.skin_dict.get('Labels',{}).get('Generic',{}),cheetah_dict) + _page_dict = weeutil.config.config_from_str('') + merge_dict = self.generator.skin_dict.get('Labels',{}).get('Generic',{}) + if merge_dict: + weeutil.config.merge_config(_page_dict,merge_dict) + merge_dict = Gettext._get_cheetah_dict(self.generator.skin_dict.get('CheetahGenerator',{}),page) + if merge_dict: + weeutil.config.merge_config(_page_dict,merge_dict) + weeutil.config.merge_config(_page_dict,_text_dict) + return _page_dict # if key as well as page are empty return _text_dict @@ -129,38 +120,4 @@ class Gettext(SearchList): return None -class FilesBinder(object): - """ special labels for a specific page to be created by Cheetah """ - - def __init__(self,page,lang_files_dict,skin_labels_dict,cheetah_dict): - self.page=page - self.lang_files_dict=lang_files_dict - self.skin_labels_dict=skin_labels_dict - self.cheetah_dict=cheetah_dict - - def __getattr__(self,attr): - if attr in self.lang_files_dict: - # entry found in localization file - return self.lang_files_dict[attr] - elif attr in self.cheetah_dict: - # entry found [CheetahGenerator] subsection - return self.cheetah_dict[attr] - elif attr=='nav': - # if $gettext(page='xxx').nav not in localization file, try - # nav_xxx in [Labels][[Generic]] section of skin.conf - # helpful for extending Belchertown skin - if 'nav_'+self.page in self.skin_labels_dict: - return self.skin_labels_dict['nav_'+self.page] - elif attr=='page_header': - # if $gettext(page='xxx').page_header not in localization file, - # try xxx_page_header in [Labels][[Generic]] section of skin.conf - # helpful for extending Belchertown skin - x=self.page+'_page_header' - if x in self.skin_labels_dict: - return self.skin_labels_dict[x] - elif attr in self.skin_labels_dict: - # finally look in [Labels][[Generic]] section if skin.conf - return str(self.skin_labels_dict[attr]) - return '$%s.%s' % (self.page,attr) - diff --git a/bin/weewx/reportengine.py b/bin/weewx/reportengine.py index e26b4bb9..a9d761cd 100644 --- a/bin/weewx/reportengine.py +++ b/bin/weewx/reportengine.py @@ -259,28 +259,14 @@ class StdReportEngine(threading.Thread): # The key 'lang' defines a language code like 'en' or 'de'. It is # used as a file name for a language file that is located in the - # 'lang' subdirectory of the skin directory. Like it is with the - # other path settings, a complete path overwrites the skin - # directory setting. + # 'lang' subdirectory of the skin directory. - # If an localization file is defined, determine the path. - # As config_dict is not merged into skin_dict so far, we - # need to check both. config_dict (weewx.conf) has the final say, - # so check it first. - if 'lang' in self.config_dict['StdReport'][report]: - # 'lang' is set in weewx.conf - lang_config = "%s.conf" % self.config_dict['StdReport'][report]['lang'] - log.debug("config_dict lang_config=%s for report %s" % (lang_config,report)) - elif 'lang' in skin_dict: - # 'lang' is set in skin.conf - lang_config = "%s.conf" % skin_dict['lang'] - log.debug("skin_dict lang_config=%s for report" % (lang_config,report)) - else: - # No localization defined. Use defaults. - lang_config = None - log.debug("no language defined for report %s" % report) + # get the language option if defined + # (As config_dict is not merged into skin_dict so far, + # skin_dict['lang'] has not the final value here. We + # have to take config_dict into account, too.) + lang_config = self.config_dict['StdReport'][report].get('lang',skin_dict.get('lang',None)) - # If an localization file name could be determined, read the file. if lang_config: # Now add the options in the report's localization file. Start by figuring where it is located. @@ -289,7 +275,7 @@ class StdReportEngine(threading.Thread): self.config_dict['StdReport']['SKIN_ROOT'], self.config_dict['StdReport'][report].get('skin', ''), 'lang', - lang_config) + lang_config+'.conf') # Now retrieve the language dictionary for the skin. Wrap it in a try block in case we fail. It is ok if # there is no file - everything for a skin might be defined in the weewx configuration. @@ -316,49 +302,22 @@ class StdReportEngine(threading.Thread): lang_config_path, report, e) raise - # The key 'unit_system' defines the unit system to be used with - # the report. The value can be 'US', 'METRIC', or 'METRICWX' - - # Check if a target unit system is defined. - # As config_dict is not merged into skin_dict so far, we - # need to check both. config_dict (weewx.conf) has the final say, - # so check it first. - if 'unit_system' in self.config_dict['StdReport'][report]: - # 'unit_system' is set in weewx.conf - unit_system = self.config_dict['StdReport'][report]['unit_system'] - elif 'unit_system' in skin_dict: - # 'unit_system' is set in skin_dict, which is merged from - # serveral sources including skin.conf - unit_system = skin_dict['unit_system'] - else: - # No unit system defined. Use defaults. - unit_system = None - log.debug("unit system for report '%s': %s" % (report,unit_system)) + # See if the user wants this report based on another unit system than US. + # The value can be US, METRIC, or METRICWX. + # (As config_dict is not merged into skin_dict so far, + # skin_dict['units_base'] has not the final value here. We + # have to take config_dict into account, too.) + report_units_base = self.config_dict['StdReport'][report].get('units_base',skin_dict.get('units_base',None)) - # If a unit system is defined get the appropriate dict - # out of units.py. If the user defined addtional units or - # unit groups, they are included here automatically. - if unit_system: - - # get the chosen unit system out of units.py + if report_units_base: + # Get the chosen unit system out of units.py. Copy it to prevent + # the original from being changed. Merge it into skin_dict. try: - merge_dict = weewx.units.std_groups[weewx.units.unit_constants[unit_system]] - except (KeyError,IndexError): - merge_dict = {} - - # build dict to merge - merge_dict = {'Units':{'Groups':merge_dict}} + merge_dict = weewx.units.std_groups[weewx.units.unit_constants[report_units_base]].copy() + weeutil.config.merge_config(skin_dict, {'Units':{'Groups':merge_dict}}) + except (SyntaxError,TypeError,IndexError,ValueError,IOError) as e: + log.error("error merging unit system '%s' for report '%s'" % (report_units_base,report)) - # merge into skin_dict - try: - weeutil.config.merge_config(skin_dict, merge_dict) - if self.first_run: - log.info("Using unit system %s for report '%s'" % - (unit_system, report)) - except (SyntaxError,TypeError,IOError) as e: - log.error("error merging target unit system for report '%s'" % report) - pass - ####################################################################### # Finally, inject any overrides for this specific report. Because this is the last merge, it will have the diff --git a/docs/customizing.htm b/docs/customizing.htm index 8eef5266..bf3131b6 100644 --- a/docs/customizing.htm +++ b/docs/customizing.htm @@ -1207,12 +1207,12 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\ [[SeasonsUSReport]] skin = Seasons - unit_system = US + units_base = US enable = true [[SeasonsMetricReport]] skin = Seasons - unit_system = METRIC + units_base = METRIC enable = true HTML_ROOT = public_html/metric

    diff --git a/docs/usersguide.htm b/docs/usersguide.htm index b99c512e..98fafac1 100644 --- a/docs/usersguide.htm +++ b/docs/usersguide.htm @@ -2265,7 +2265,7 @@ longitude = -77.0366 These are the four reports that actually generate HTML files and plots. They all ship in the standard WeeWX distribution. They all use US Customary units by default, but this can be changed by setting the option unit_system or + class="code">units_base or by editing section [StdReport][[Defaults]].

    @@ -2297,13 +2297,12 @@ longitude = -77.0366 the file according to the list in ISO 639-1.

    -

    unit_system

    +

    units_base

    Which unit system to use with the skin. That can be US, - METRIC, - METRICWX, or - METRICDE. + METRIC, or + METRICWX. If the option is not set, the units set in the [StdReport][[Defaults]] section are used. If no defaults are diff --git a/weewx.conf b/weewx.conf index 6aae7952..2237a681 100644 --- a/weewx.conf +++ b/weewx.conf @@ -159,7 +159,7 @@ version = 4.5.1 # images, templates and plots for the report. skin = Seasons lang = en - target_unit = US + units_base = US enable = true [[SmartphoneReport]] From 1ce6fe48f701ec8d2a3b46a38adfe371a2c13925 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 2 May 2021 16:41:30 +0200 Subject: [PATCH 27/30] transfer gettext() to dict gettext[] --- bin/weewx/gettext.py | 27 ++++++- skins/Seasons/celestial.html.tmpl | 2 +- skins/Seasons/celestial.inc | 26 +++---- skins/Seasons/current.inc | 2 +- skins/Seasons/hilo.inc | 12 +-- skins/Seasons/identifier.inc | 6 +- skins/Seasons/index.html.tmpl | 14 ++-- skins/Seasons/lang/de.conf | 2 + skins/Seasons/lang/en.conf | 2 + skins/Seasons/rss.xml.tmpl | 116 ++++++++++++++--------------- skins/Seasons/sensors.inc | 2 +- skins/Seasons/statistics.html.tmpl | 2 +- skins/Seasons/statistics.inc | 12 +-- skins/Seasons/sunmoon.inc | 10 +-- skins/Seasons/tabular.html.tmpl | 2 +- skins/Seasons/telemetry.html.tmpl | 10 +-- skins/Seasons/titlebar.inc | 8 +- 17 files changed, 140 insertions(+), 115 deletions(-) diff --git a/bin/weewx/gettext.py b/bin/weewx/gettext.py index 2e1824f0..0d993671 100644 --- a/bin/weewx/gettext.py +++ b/bin/weewx/gettext.py @@ -50,6 +50,7 @@ """ +from six.moves import collections_abc from weewx.cheetahgenerator import SearchList from weeutil.weeutil import KeyDict import weeutil.config @@ -93,9 +94,9 @@ class Gettext(SearchList): # if key is empty but page is not return further class instance if page: _page_dict = weeutil.config.config_from_str('') - merge_dict = self.generator.skin_dict.get('Labels',{}).get('Generic',{}) - if merge_dict: - weeutil.config.merge_config(_page_dict,merge_dict) + #merge_dict = self.generator.skin_dict.get('Labels',{}).get('Generic',{}) + #if merge_dict: + # weeutil.config.merge_config(_page_dict,merge_dict) merge_dict = Gettext._get_cheetah_dict(self.generator.skin_dict.get('CheetahGenerator',{}),page) if merge_dict: weeutil.config.merge_config(_page_dict,merge_dict) @@ -103,7 +104,7 @@ class Gettext(SearchList): return _page_dict # if key as well as page are empty - return _text_dict + return ParallelDict(_text_dict) return [{'gettext':locale_label}] @@ -121,3 +122,21 @@ class Gettext(SearchList): +class ParallelDict(collections_abc.Mapping): + + def __init__(self, source): + self.source = source + + def __getitem__(self, key): + try: + return self.source[key] + except KeyError: + return key + + + def __len__(self): + return self.source.__len__() + + def __iter__(self): + for key in self.source: + yield key diff --git a/skins/Seasons/celestial.html.tmpl b/skins/Seasons/celestial.html.tmpl index d48c5f67..467daea4 100644 --- a/skins/Seasons/celestial.html.tmpl +++ b/skins/Seasons/celestial.html.tmpl @@ -31,7 +31,7 @@ #include "titlebar.inc"

    -

    ❰ $gettext("Current Conditions")

    +

    ❰ $gettext["Current Conditions"]

    #include "celestial.inc" diff --git a/skins/Seasons/celestial.inc b/skins/Seasons/celestial.inc index 9b127228..1a8dc055 100644 --- a/skins/Seasons/celestial.inc +++ b/skins/Seasons/celestial.inc @@ -58,7 +58,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -96,21 +96,21 @@ #if $almanac.next_equinox.raw < $almanac.next_solstice.raw ## The equinox is before the solstice. Display them in order. - + - + #else ## The solstice is before the equinox. Display them in order. - + - + #end if @@ -129,7 +129,7 @@ - + @@ -155,25 +155,25 @@ #if $almanac.next_full_moon.raw < $almanac.next_new_moon.raw - + - + #else - + - + #end if - + diff --git a/skins/Seasons/current.inc b/skins/Seasons/current.inc index 87a5149a..219e35c3 100644 --- a/skins/Seasons/current.inc +++ b/skins/Seasons/current.inc @@ -6,7 +6,7 @@
    - $gettext("Current Conditions") + $gettext["Current Conditions"]
    diff --git a/skins/Seasons/hilo.inc b/skins/Seasons/hilo.inc index 719c3921..f67ce3d8 100644 --- a/skins/Seasons/hilo.inc +++ b/skins/Seasons/hilo.inc @@ -8,7 +8,7 @@
    @@ -18,15 +18,15 @@
    - - - + + + diff --git a/skins/Seasons/identifier.inc b/skins/Seasons/identifier.inc index fe1395e0..49f242ba 100644 --- a/skins/Seasons/identifier.inc +++ b/skins/Seasons/identifier.inc @@ -10,15 +10,15 @@
    ☀ $gettext("Sun",$page)
    Start civil twilight$gettext("Start civil twilight",$page) $almanac(horizon=-6).sun(use_center=1).rise
    $almanac.sun.rise.format(None_string=$sun_None)
    Transit$gettext("Transit",$page) $almanac.sun.transit
    $almanac.sun.set.format(None_string=$sun_None)
    End civil twilight$gettext("End civil twilight",$page) $almanac(horizon=-6).sun(use_center=1).set
    Equinox$gettext("Equinox",$page) $almanac.next_equinox
    Solstice$gettext("Solstice",$page) $almanac.next_solstice
    Solstice$gettext("Solstice",$page) $almanac.next_solstice
    Equinox$gettext("Equinox",$page) $almanac.next_equinox
    $almanac.moon.rise
    Transit$gettext("Transit",$page) $almanac.moon.transit
    Full moon$gettext("Full moon",$page) $almanac.next_full_moon
    New moon$gettext("New moon",$page) $almanac.next_new_moon
    New moon$gettext("New moon",$page) $almanac.next_new_moon
    Full moon$gettext("Full moon",$page) $almanac.next_full_moon
    Phase$gettext("Phase",$page) $almanac.moon_phase
    $almanac.moon_fullness% full
     
    $gettext("Today")
     
    $gettext("Week")
     
    $gettext("Month")
     
    $gettext["Today"]
     
    $gettext["Week"]
     
    $gettext["Month"]
            
    $gettext("Year")
    + onclick="toggle_rainyear()">        
    $gettext["Year"]
    - $gettext("Rainyear1")
    $gettext("Rainyear2")
    + $gettext["Rainyear1"]
    $gettext["Rainyear2"]
    - + - + - + diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index 1707763a..3a7b80a8 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -33,15 +33,15 @@
    -
    $gettext("Plots",$page):   +
    $gettext[$page]["Plots"]:   $gettext("Day") + onclick="choose_history('day')">$gettext["Day"] $gettext("Week") + onclick="choose_history('week')">$gettext["Week"] $gettext("Month") + onclick="choose_history('month')">$gettext["Month"] $gettext("Year") + onclick="choose_history('year')">$gettext["Year"]
    $obs.label.barometer @@ -160,11 +160,13 @@

    - $gettext("footnote1")WeeWX$gettext("footnote2") + $gettext["footnote1"]WeeWX$gettext["footnote2"]

    #include "analytics.inc" +

    $gettext.blabla

    + diff --git a/skins/Seasons/lang/de.conf b/skins/Seasons/lang/de.conf index 522ab012..a3f8213c 100644 --- a/skins/Seasons/lang/de.conf +++ b/skins/Seasons/lang/de.conf @@ -170,6 +170,8 @@ "Max barometer" = Luftdruck Maximum "Max wind" = Max Wind "Rain today" = Regen heute + "Rain total for month" = Regen in diesem Monat + "Rain total for year" = Regen in diesem Jahr "Weather Conditions at" = Wetter am "Yearly Weather Summary as of" = Jahreszusammenfassung zum "Monthly Weather Summary as of" = Monatszusammenfassung zum diff --git a/skins/Seasons/lang/en.conf b/skins/Seasons/lang/en.conf index 2cd6f9e3..74a84301 100644 --- a/skins/Seasons/lang/en.conf +++ b/skins/Seasons/lang/en.conf @@ -168,6 +168,8 @@ "Max barometer" = Max barometer "Max wind" = Max wind "Rain today" = Rain today + "Rain total for month" = Rain total for month + "Rain total for year" = Rain total for year "Weather Conditions at" = Weather Conditions at "Yearly Weather Summary as of" = Yearly Weather Summary as of "Monthly Weather Summary as of" = Monthly Weather Summary as of diff --git a/skins/Seasons/rss.xml.tmpl b/skins/Seasons/rss.xml.tmpl index 5f933b14..093c9cd7 100644 --- a/skins/Seasons/rss.xml.tmpl +++ b/skins/Seasons/rss.xml.tmpl @@ -3,9 +3,9 @@ xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" > - $station.location, $gettext("Weather Conditions",$page) + $station.location, $gettext[$page]["Weather Conditions"] $station.station_url - $gettext("description",$page) + $gettext[$page]["description"] $gettext.lang $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") @@ -20,7 +20,7 @@ $obs.label.outTemp: $current.outTemp; $obs.label.barometer: $current.barometer; - $obs.label.wind: $current.windSpeed $gettext("from",$page) $current.windDir; + $obs.label.wind: $current.windSpeed $gettext[$page]["from"] $current.windDir; $obs.label.rainRate: $current.rainRate; $obs.label.inTemp: $current.inTemp @@ -37,97 +37,97 @@ $obs.label.dewpoint: $current.dewpoint
    $obs.label.outHumidity: $current.outHumidity
    $obs.label.barometer: $current.barometer
    - $obs.label.wind: $current.windSpeed $gettext("from",$page) $current.windDir
    + $obs.label.wind: $current.windSpeed $gettext[$page]["from"] $current.windDir
    $obs.label.rainRate: $current.rainRate

    ]]> - $gettext("Daily Weather Summary as of",$page) $current.dateTime + $gettext[$page]["Daily Weather Summary as of"] $current.dateTime $station.station_url - $gettext("Min outside temperature",$page): $day.outTemp.min at $day.outTemp.mintime; - $gettext("Max outside temperature",$page): $day.outTemp.max at $day.outTemp.maxtime; - $gettext("Min inside temperature",$page): $day.inTemp.min at $day.inTemp.mintime; - $gettext("Max inside temperature",$page): $day.inTemp.max at $day.inTemp.maxtime; - $gettext("Min barometer",$page): $day.barometer.min at $day.barometer.mintime; - $gettext("Max barometer",$page): $day.barometer.max at $day.barometer.maxtime; - $gettext("Max wind",$page) : $day.wind.max $gettext("from",$page) $day.wind.gustdir at $day.wind.maxtime; - $gettext("Rain today",$page): $day.rain.sum + $gettext[$page]["Min outside temperature"]: $day.outTemp.min at $day.outTemp.mintime; + $gettext[$page]["Max outside temperature"]: $day.outTemp.max at $day.outTemp.maxtime; + $gettext[$page]["Min inside temperature"]: $day.inTemp.min at $day.inTemp.mintime; + $gettext[$page]["Max inside temperature"]: $day.inTemp.max at $day.inTemp.maxtime; + $gettext[$page]["Min barometer"]: $day.barometer.min at $day.barometer.mintime; + $gettext[$page]["Max barometer"]: $day.barometer.max at $day.barometer.maxtime; + $gettext[$page]["Max wind"] : $day.wind.max $gettext[$page]["from"] $day.wind.gustdir at $day.wind.maxtime; + $gettext[$page]["Rain today"]: $day.rain.sum $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") $station.latitude_f $station.longitude_f - $gettext("Day"): $day.dateTime.format("%d %b %Y")
    - $gettext("Min Outside Temperature",$page): $day.outTemp.min at $day.outTemp.mintime
    - $gettext("Max Outside Temperature",$page): $day.outTemp.max at $day.outTemp.maxtime
    - $gettext("Min Inside Temperature",$page): $day.inTemp.min at $day.inTemp.mintime
    - $gettext("Max Inside Temperature",$page): $day.inTemp.max at $day.inTemp.maxtime
    - $gettext("Min Barometer",$page): $day.barometer.min at $day.barometer.mintime
    - $gettext("Max Barometer",$page): $day.barometer.max at $day.barometer.maxtime
    - $gettext("Max Wind",$page) : $day.wind.max $gettext("from",$page) $day.wind.gustdir at $day.wind.maxtime
    - $gettext("Rain today",$page): $day.rain.sum
    + $gettext["Day"]: $day.dateTime.format("%d %b %Y")
    + $gettext[$page]["Min outside temperature"]: $day.outTemp.min at $day.outTemp.mintime
    + $gettext[$page]["Max outside temperature"]: $day.outTemp.max at $day.outTemp.maxtime
    + $gettext[$page]["Min inside temperature"]: $day.inTemp.min at $day.inTemp.mintime
    + $gettext[$page]["Max inside temperature"]: $day.inTemp.max at $day.inTemp.maxtime
    + $gettext[$page]["Min barometer"]: $day.barometer.min at $day.barometer.mintime
    + $gettext[$page]["Max barometer"]: $day.barometer.max at $day.barometer.maxtime
    + $gettext[$page]["Max wind"] : $day.wind.max $gettext[$page]["from"] $day.wind.gustdir at $day.wind.maxtime
    + $gettext[$page]["Rain today"]: $day.rain.sum

    ]]>
    - $gettext("Monthly Weather Summary as of",$page) $current.dateTime + $gettext[$page]["Monthly Weather Summary as of"]) $current.dateTime $station.station_url - $gettext("Min outside temperature",$page): $month.outTemp.min at $month.outTemp.mintime; - $gettext("Max outside temperature",$page): $month.outTemp.max at $month.outTemp.maxtime; - $gettext("Min inside temperature",$page): $month.inTemp.min at $month.inTemp.mintime; - $gettext("Max inside temperature",$page): $month.inTemp.max at $month.inTemp.maxtime; - $gettext("Min barometer",$page): $month.barometer.min at $month.barometer.mintime; - $gettext("Max barometer",$page): $month.barometer.max at $month.barometer.maxtime; - $gettext("Max wind",$page) : $month.wind.max $gettext("from",$page) $month.wind.gustdir at $month.wind.maxtime; - $gettext("Rain total for month",$page): $month.rain.sum + $gettext[$page]["Min outside temperature"]: $month.outTemp.min at $month.outTemp.mintime; + $gettext[$page]["Max outside temperature"]: $month.outTemp.max at $month.outTemp.maxtime; + $gettext[$page]["Min inside temperature"]: $month.inTemp.min at $month.inTemp.mintime; + $gettext[$page]["Max inside temperature"]: $month.inTemp.max at $month.inTemp.maxtime; + $gettext[$page]["Min barometer"]: $month.barometer.min at $month.barometer.mintime; + $gettext[$page]["Max barometer"]: $month.barometer.max at $month.barometer.maxtime; + $gettext[$page]["Max wind"] : $month.wind.max $gettext[$page]["from"] $month.wind.gustdir at $month.wind.maxtime; + $gettext[$page]["Rain total for month"]: $month.rain.sum $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") - $gettext("Month"): $month.dateTime.format("%B %Y")
    - $gettext("Max Outside Temperature",$page): $month.outTemp.max at $month.outTemp.maxtime
    - $gettext("Min Outside Temperature",$page): $month.outTemp.min at $month.outTemp.mintime
    - $gettext("Max Inside Temperature",$page): $month.inTemp.max at $month.inTemp.maxtime
    - $gettext("Min Inside Temperature",$page): $month.inTemp.min at $month.inTemp.mintime
    - $gettext("Min Barometer",$page): $month.barometer.min at $month.barometer.mintime
    - $gettext("Max Barometer",$page): $month.barometer.max at $month.barometer.maxtime
    - $gettext("Max Wind",$page) : $month.wind.max $gettext("from",$page) $month.wind.gustdir at $month.wind.maxtime
    - $gettext("Rain total for month",$page): $month.rain.sum
    + $gettext["Month"]: $month.dateTime.format("%B %Y")
    + $gettext[$page]["Max outside temperature"]: $month.outTemp.max at $month.outTemp.maxtime
    + $gettext[$page]["Min outside temperature"]: $month.outTemp.min at $month.outTemp.mintime
    + $gettext[$page]["Max inside temperature"]: $month.inTemp.max at $month.inTemp.maxtime
    + $gettext[$page]["Min inside temperature"]: $month.inTemp.min at $month.inTemp.mintime
    + $gettext[$page]["Min barometer"]: $month.barometer.min at $month.barometer.mintime
    + $gettext[$page]["Max barometer"]: $month.barometer.max at $month.barometer.maxtime
    + $gettext[$page]["Max wind"] : $month.wind.max $gettext[$page]["from"] $month.wind.gustdir at $month.wind.maxtime
    + $gettext[$page]["Rain total for month"]: $month.rain.sum

    ]]>
    - $gettext("Yearly Weather Summary as of",$page) $current.dateTime + $gettext[$page]["Yearly Weather Summary as of"] $current.dateTime $station.station_url - $gettext("Min outside temperature",$page): $year.outTemp.min at $year.outTemp.mintime; - $gettext("Max outside temperature",$page): $year.outTemp.max at $year.outTemp.maxtime; - $gettext("Min inside temperature",$page): $year.inTemp.min at $year.inTemp.mintime; - $gettext("Max inside temperature",$page): $year.inTemp.max at $year.inTemp.maxtime; - $gettext("Min barometer",$page): $year.barometer.min at $year.barometer.mintime; - $gettext("Max barometer",$page): $year.barometer.max at $year.barometer.maxtime; - $gettext("Max wind",$page) : $year.wind.max $gettext("from",$page) $year.wind.gustdir at $year.wind.maxtime; - $gettext("Rain total for year",$page): $year.rain.sum + $gettext[$page]["Min outside temperature"]: $year.outTemp.min at $year.outTemp.mintime; + $gettext[$page]["Max outside temperature"]: $year.outTemp.max at $year.outTemp.maxtime; + $gettext[$page]["Min inside temperature"]: $year.inTemp.min at $year.inTemp.mintime; + $gettext[$page]["Max inside temperature"]: $year.inTemp.max at $year.inTemp.maxtime; + $gettext[$page]["Min barometer"]: $year.barometer.min at $year.barometer.mintime; + $gettext[$page]["Max barometer"]: $year.barometer.max at $year.barometer.maxtime; + $gettext[$page]["Max wind"] : $year.wind.max $gettext[$page]["from"] $year.wind.gustdir at $year.wind.maxtime; + $gettext[$page]["Rain total for year"]: $year.rain.sum $current.dateTime.format("%a, %d %b %Y %H:%M:%S %Z") - $gettext("Year"): $year.dateTime.format("%Y")
    - $gettext("Max Outside Temperature",$page): $year.outTemp.max at $year.outTemp.maxtime
    - $gettext("Min Outside Temperature",$page): $year.outTemp.min at $year.outTemp.mintime
    - $gettext("Max Inside Temperature",$page): $year.inTemp.max at $year.inTemp.maxtime
    - $gettext("Min Inside Temperature",$page): $year.inTemp.min at $year.inTemp.mintime
    - $gettext("Min Barometer",$page): $year.barometer.min at $year.barometer.mintime
    - $gettext("Max Barometer",$page): $year.barometer.max at $year.barometer.maxtime
    - $gettext("Max Wind",$page) : $year.wind.max $gettext("from",$page) $year.wind.gustdir at $year.wind.maxtime
    - $gettext("Rain total for year",$page): $year.rain.sum
    + $gettext["Year"]: $year.dateTime.format("%Y")
    + $gettext[$page]["Max outside temperature"]: $year.outTemp.max at $year.outTemp.maxtime
    + $gettext[$page]["Min outside temperature"]: $year.outTemp.min at $year.outTemp.mintime
    + $gettext[$page]["Max inside temperature"]: $year.inTemp.max at $year.inTemp.maxtime
    + $gettext[$page]["Min inside temperature"]: $year.inTemp.min at $year.inTemp.mintime
    + $gettext[$page]["Min barometer"]: $year.barometer.min at $year.barometer.mintime
    + $gettext[$page]["Max barometer"]: $year.barometer.max at $year.barometer.maxtime
    + $gettext[$page]["Max wind"] : $year.wind.max $gettext[$page]["from"] $year.wind.gustdir at $year.wind.maxtime
    + $gettext[$page]["Rain total for year"]: $year.rain.sum

    ]]>
    diff --git a/skins/Seasons/sensors.inc b/skins/Seasons/sensors.inc index df0fb47d..44c70ec1 100644 --- a/skins/Seasons/sensors.inc +++ b/skins/Seasons/sensors.inc @@ -45,7 +45,7 @@ #if $have_conn or $have_battery_status or $have_voltage
    diff --git a/skins/Seasons/statistics.html.tmpl b/skins/Seasons/statistics.html.tmpl index 6b5bbd90..bb406e78 100644 --- a/skins/Seasons/statistics.html.tmpl +++ b/skins/Seasons/statistics.html.tmpl @@ -39,7 +39,7 @@ #include "titlebar.inc"
    -

    ❰ $gettext("Current Conditions")

    +

    ❰ $gettext["Current Conditions"]

    #include "statistics.inc" diff --git a/skins/Seasons/statistics.inc b/skins/Seasons/statistics.inc index be03bd24..0465a839 100644 --- a/skins/Seasons/statistics.inc +++ b/skins/Seasons/statistics.inc @@ -8,7 +8,7 @@
    - $gettext("Title",$page) + $gettext[$page].Title
    @@ -17,11 +17,11 @@
    - - - - - + + + + + diff --git a/skins/Seasons/sunmoon.inc b/skins/Seasons/sunmoon.inc index 36c51bdc..e4c062a7 100644 --- a/skins/Seasons/sunmoon.inc +++ b/skins/Seasons/sunmoon.inc @@ -27,7 +27,7 @@
    $gettext("Latitude")$gettext["Latitude"] $station.latitude[0]° $station.latitude[1]' $station.latitude[2]
    $gettext("Longitude")$gettext["Longitude"] $station.longitude[0]° $station.longitude[1]' $station.longitude[2]
    $gettext("GeoAltitude")$gettext["GeoAltitude"] $station.altitude
    $gettext("Today")$gettext("Week")$gettext("Month")$gettext("Year")$gettext("Rainyear")$gettext["Today"]$gettext["Week"]$gettext["Month"]$gettext["Year"]$gettext["Rainyear"]
    $obs.label.outTemp
    - + - + - + - + diff --git a/skins/Seasons/tabular.html.tmpl b/skins/Seasons/tabular.html.tmpl index 6898b2af..fb39c7ca 100644 --- a/skins/Seasons/tabular.html.tmpl +++ b/skins/Seasons/tabular.html.tmpl @@ -23,7 +23,7 @@ #include "titlebar.inc" diff --git a/skins/Seasons/telemetry.html.tmpl b/skins/Seasons/telemetry.html.tmpl index ce204897..b76232eb 100644 --- a/skins/Seasons/telemetry.html.tmpl +++ b/skins/Seasons/telemetry.html.tmpl @@ -31,7 +31,7 @@ #include "titlebar.inc"
    -

    ❰ $gettext("Current Conditions")

    +

    ❰ $gettext["Current Conditions"]

    #include "sensors.inc" @@ -41,13 +41,13 @@
    Telemetry:   $gettext("Day") + onclick="choose_history('day')">$gettext["Day"] $gettext("Week") + onclick="choose_history('week')">$gettext["Week"] $gettext("Month") + onclick="choose_history('month')">$gettext["Month"] $gettext("Year") + onclick="choose_history('year')">$gettext["Year"]
    $period_plots($day, 'day') diff --git a/skins/Seasons/titlebar.inc b/skins/Seasons/titlebar.inc index 508c4dbe..49c67b42 100644 --- a/skins/Seasons/titlebar.inc +++ b/skins/Seasons/titlebar.inc @@ -11,20 +11,20 @@
    - $gettext("Monthly Reports"): + $gettext["Monthly Reports"]:
    - $gettext("Yearly Reports"): + $gettext["Yearly Reports"]:
    From 9788ec8fef19f59e73ceed3120c2d307e5b658bf Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 2 May 2021 16:43:26 +0200 Subject: [PATCH 28/30] test text removed --- skins/Seasons/index.html.tmpl | 2 -- 1 file changed, 2 deletions(-) diff --git a/skins/Seasons/index.html.tmpl b/skins/Seasons/index.html.tmpl index 3a7b80a8..7763793c 100644 --- a/skins/Seasons/index.html.tmpl +++ b/skins/Seasons/index.html.tmpl @@ -165,8 +165,6 @@ #include "analytics.inc" -

    $gettext.blabla

    - From a365e39a9c72d93c8bcc3c5337f387ae34871ce7 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 2 May 2021 17:07:21 +0200 Subject: [PATCH 29/30] gettext() to gettext[][] in celestial.inc --- skins/Seasons/celestial.inc | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/skins/Seasons/celestial.inc b/skins/Seasons/celestial.inc index 1a8dc055..72b0252f 100644 --- a/skins/Seasons/celestial.inc +++ b/skins/Seasons/celestial.inc @@ -49,131 +49,131 @@
    - $gettext("Title",$page) + $gettext[$page]["Title"]
    #if $almanac.hasExtras
    $gettext("Rise","celestial")$gettext["celestial"]["Rise"] $almanac.sun.rise.format(None_string=$sun_None)  $gettext("Rise","celestial")$gettext["celestial"]["Rise"] $almanac.moon.rise
    $gettext("Set","celestial")$gettext["celestial"]["Set"] $almanac.sun.set.format(None_string=$sun_None)  $gettext("Set","celestial")$gettext["celestial"]["Set"] $almanac.moon.set
    - + - + - + - + - + - + - + - + - + - + #if $almanac.next_equinox.raw < $almanac.next_solstice.raw ## The equinox is before the solstice. Display them in order. - + - + #else ## The solstice is before the equinox. Display them in order. - + - + #end if - +
    ☀ $gettext("Sun",$page)
    ☀ $gettext[$page]["Sun"]
    $gettext("Start civil twilight",$page)$gettext[$page]["Start civil twilight"] $almanac(horizon=-6).sun(use_center=1).rise
    $gettext("Rise",$page)$gettext[$page]["Rise"] $almanac.sun.rise.format(None_string=$sun_None)
    $gettext("Transit",$page)$gettext[$page]["Transit"] $almanac.sun.transit
    $gettext("Set",$page)$gettext[$page]["Set"] $almanac.sun.set.format(None_string=$sun_None)
    $gettext("End civil twilight",$page)$gettext[$page]["End civil twilight"] $almanac(horizon=-6).sun(use_center=1).set
    $gettext("Azimuth",$page)$gettext[$page]["Azimuth"] $("%.1f°" % $almanac.sun.az)
    $gettext("AstroAltitude",$page)$gettext[$page]["AstroAltitude"] $("%.1f°" % $sun_altitude)
    $gettext("Right ascension",$page)$gettext[$page]["Right ascension"] $("%.1f°" % $almanac.sun.ra)
    $gettext("Declination",$page)$gettext[$page]["Declination"] $("%.1f°" % $almanac.sun.dec)
    $gettext("Equinox",$page)$gettext[$page]["Equinox"] $almanac.next_equinox
    $gettext("Solstice",$page)$gettext[$page]["Solstice"] $almanac.next_solstice
    $gettext("Solstice",$page)$gettext[$page]["Solstice"] $almanac.next_solstice
    $gettext("Equinox",$page)$gettext[$page]["Equinox"] $almanac.next_equinox
    $gettext("Daylight",$page)$gettext[$page]["Daylight"] $daylight_str
    - + - + - + - + - + - + - + - + #if $almanac.next_full_moon.raw < $almanac.next_new_moon.raw - + - + #else - + - + #end if - + From 8ffa9992ecb69c6b74f77844693b64fd50dcde69 Mon Sep 17 00:00:00 2001 From: roe-dl Date: Sun, 2 May 2021 18:54:01 +0200 Subject: [PATCH 30/30] forgotten changes from gettext() to gettext[] --- skins/Seasons/about.inc | 8 ++++---- skins/Seasons/sunmoon.inc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/skins/Seasons/about.inc b/skins/Seasons/about.inc index 55a872d8..85a2d4fd 100644 --- a/skins/Seasons/about.inc +++ b/skins/Seasons/about.inc @@ -6,7 +6,7 @@
    - $gettext("About") + $gettext["About"]
    @@ -17,15 +17,15 @@
    - + - + - + diff --git a/skins/Seasons/sunmoon.inc b/skins/Seasons/sunmoon.inc index e4c062a7..e7786a20 100644 --- a/skins/Seasons/sunmoon.inc +++ b/skins/Seasons/sunmoon.inc @@ -51,7 +51,7 @@ - +
    ☽ $gettext("Moon",$page)
    ☽ $gettext[$page]["Moon"]
      
    $gettext("Rise",$page)$gettext[$page]["Rise"] $almanac.moon.rise
    $gettext("Transit",$page)$gettext[$page]["Transit"] $almanac.moon.transit
    $gettext("Set",$page)$gettext[$page]["Set"] $almanac.moon.set
      
    $gettext("Azimuth",$page)$gettext[$page]["Azimuth"] $("%.1f°" % $almanac.moon.az)
    $gettext("AstroAltitude",$page)$gettext[$page]["AstroAltitude"] $("%.1f°" % $almanac.moon.alt)
    $gettext("Right ascension",$page)$gettext[$page]["Right ascension"] $("%.1f°" % $almanac.moon.ra)
    $gettext("Declination",$page)$gettext[$page]["Declination"] $("%.1f°" % $almanac.moon.dec)
    $gettext("Full moon",$page)$gettext[$page]["Full moon"] $almanac.next_full_moon
    $gettext("New moon",$page)$gettext[$page]["New moon"] $almanac.next_new_moon
    $gettext("New moon",$page)$gettext[$page]["New moon"] $almanac.next_new_moon
    $gettext("Full moon",$page)$gettext[$page]["Full moon"] $almanac.next_full_moon
    $gettext("Phase",$page)$gettext[$page]["Phase"] $almanac.moon_phase
    $almanac.moon_fullness% full
    $station.hardware
    $gettext("Latitude")$gettext["Latitude"] $station.latitude[0]° $station.latitude[1]' $station.latitude[2]
    $gettext("Longitude")$gettext["Longitude"] $station.longitude[0]° $station.longitude[1]' $station.longitude[2]
    $gettext("GeoAltitude")$gettext["GeoAltitude"] $station.altitude
    $almanac.moon.set
    $gettext("Daylight",$page)$gettext[$page]["Daylight"] $daylight_str