diff --git a/merge.conf b/merge.conf deleted file mode 100644 index bdb2efab..00000000 --- a/merge.conf +++ /dev/null @@ -1,274 +0,0 @@ -############################################################################################ -# # -# # -# FTP CONFIGURATION FILE # -# # -# # -############################################################################################ -# # -# Copyright (c) 2010 Tom Keffer # -# # -# See the file LICENSE.txt for your full rights. # -# # -############################################################################################ -# -# $Revision: 164 $ -# $Author: tkeffer $ -# $Date: 2010-03-16 16:16:04 -0700 (Tue, 16 Mar 2010) $ -# -############################################################################################ - -# This isn't really a "report". Instead, we use the report engine to run an FTP service. - -# The list of generators that are part of this report: -generator_list = weewx.reportengine.Ftp, -skin = Ftp -debug = 0 -socket_timeout = 20 -version = 1.6.0 -[Station] - -# -# This section is for information about your station -# - -# Root directory of the weewx file hierarchy for this station: -WEEWX_ROOT = /home/tkeffer/workspace/weewx - -location = "Hood River, Oregon" - -# Latitude, longitude in decimal degrees -latitude = 45.686 -longitude = -121.566 - -# Altitude of the station in the same units as group_altitude (see section 'Units') -altitude = 700 - -rain_year_start = 10 -radar_url = http://radar.weather.gov/ridge/lite/N0R/RTX_loop.gif - -# Base temperature for heating days, in the same units as group_temperature: -heating_base = 65 -# Base temperature for cooling days, in the same units as group_temperature: -cooling_base = 65 - -# Start of week (0=Monday, 6 = Sunday) -week_start = 6 - -# Set to hemisphere abbreviations suitable for your location: -hemispheres = N, S, E, W - -# How often to check the clock on the weather station for drift (in seconds) -clock_check = 14400 - -# Set to 1 (one) to cache LOOP data, otherwise zero. Most people -# will want to set this to one unless you have a specialized application -cache_loop_data = 1 - -# Set to type of station (e.g., 'VantagePro' for a Davis VantagePro or VantagePro2) -# Must match section name below. -station_type = VantagePro -[VantagePro] - -# -# This section is for configuration info for a Davis VantagePro or -# VantagePro2 -# - -# Its port. -# -# Ubuntu and SuSE: -# /dev/ttyUSB0 is a common USB port name -# /dev/ttyS0 a common serial port name -port = /dev/ttyUSB0 -#port = /dev/ttyS0 - -# Its baud rate (usually 19200) -baudrate = 19200 - -# Archive interval in seconds for your station. (Used only when configuring -# the station; otherwise it is downloaded from the station) -archive_interval = 300 - -# The id of your ISS station (usually 1) -iss_id = 1 - -# How long to wait (in seconds) before processing new archive data -archive_delay = 15 - -# How long to wait for a response from the station before giving up (in -# seconds; must be greater than 2) -timeout = 5 - -# How long to wait before trying again (in seconds) -wait_before_retry = 1.2 - -# How many times to try before giving up: -max_retries = 4 - -# How much it can drift before we will correct it (in seconds): -max_drift = 5 - -# What unit system to use on the station. 1=US Customary (the only one the VP -# supports) -unit_system = 1 -[FTP] - -# -# This section is for configuring FTP uploads to a remote web server. -# -# If you wish to do this, make sure the following four lines are uncommented -# and filled out somewhere in this section: -# user = replace with your username -# password = replace with your password -# server = replace with your server name, e.g, www.threefools.org -# path = replace with the destination root directory on your server (e.g., '/weather) - -# Set to 1 to use passive mode, zero for active mode: -passive = 1 - -# How many times to try to transfer a file before giving up: -max_retries = 3 -[Wunderground] -[Archive] - -# -# This section is for configuration info about the sqlite3 archive database -# - -# The path to the database, relative to the WEEWX_ROOT directory -archive_file = archive/weewx.sdb - -# What unit system to use in the database. 1=US Customary (the only -# one supported now) -unit_system = 1 -[Stats] - -# -# This section is for configuration info about the sqlite3 statistical -# database -# - -# Path to the statistics database, relative to the WEEWX_ROOT directory: -stats_file = archive/stats.sdb - -# The types for which Hi/Low statistics will be kept. Types not listed will -# not be available for HTML pages and other stats. Note that while most -# types correspond to their SQL counterpart, 'wind' is a special type that -# replaces windSpeed and windGust. It can answer queries such as dominant -# wind directions, etc. If not given, statistics will be kept for all -# possible types, resulting in a possibly much bigger than necessary stats -# database. - -stats_types = wind, barometer, inTemp, outTemp, inHumidity, outHumidity, rainRate, rain, dewpoint, windchill, heatindex, ET, radiation, UV, extraTemp1, rxCheckPercent -[Units] - -# -# This section is for managing the selection and formatting of units. -# - -[[Groups]] -# -# For each group of measurements, this section sets what units to use for it. -# NB: The unit is always in the singular. I.e., 'mile_per_hour', NOT 'miles_per_hour' -# -group_altitude = foot# Options are 'foot' or 'meter' -group_direction = degree_compass -group_moisture = centibar -group_percent = percent -group_pressure = inHg# Options are 'inHg', 'mbar', or 'hPa' -group_radiation = watt_per_meter_squared -group_rain = inch# Options are 'inch', 'cm', or 'mm' -group_rainrate = inch_per_hour# Options are 'inch_per_hour', 'cm_per_hour', or 'mm_per_hour' -group_speed = mile_per_hour# Options are 'mile_per_hour', 'km_per_hour', 'knot', or 'meter_per_second' -group_speed2 = mile_per_hour2# Options are 'mile_per_hour2', 'km_per_hour2', 'knot2', or 'meter_per_second2' -group_temperature = degree_F# Options are 'degree_F' or 'degree_C' -group_volt = volt - -[[StringFormats]] -# -# This section sets the string formatting for each type of unit. -# -centibar = %.0f -cm = %.2f -cm_per_hour = %.2f -degree_C = %.1f -degree_compass = %.0f -degree_F = %.1f -foot = %.0f -hPa = %.1f -inHg = %.3f -inch = %.2f -inch_per_hour = %.2f -km_per_hour = %.0f -km_per_hour2 = %.1f -knot = %.0f -knot2 = %.1f -mbar = %.1f -meter = %.0f -meter_per_second = %.0f -meter_per_second2 = %.1f -mile_per_hour = %.0f -mile_per_hour2 = %.1f -mm = %.1f -mm_per_hour = %.1f -percent = %.0f -volt = %.1f -watt_per_meter_squared = %.0f - -[[Labels]] -# -# This section sets a label to be used for each type of unit. -# -centibar = cb -cm = cm -cm_per_hour = cm/hr -degree_C = \xb0C -degree_compass = \xb0 -degree_F = \xb0F -foot = feet -hPa = hPa -inHg = inHg -inch = in -inch_per_hour = in/hr -km_per_hour = kph -km_per_hour2 = kph -knot = knots -knot2 = knots -mbar = mbar -meter = meters -meter_per_second = m/s -meter_per_second2 = m/s -mile_per_hour = mph -mile_per_hour2 = mph -mm = mm -mm_per_hour = mm/hr -percent = % -volt = V -watt_per_meter_squared = W/m\xb2 -[Reports] - -# -# 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 - -# Each subsection represents a report you wish to run: -[[Report1]] -skin = Standard - -[[FTP]] -skin = Ftp -[Engines] - -# This section configures the internal weewx engines. It is for advanced customization. - -[[WxEngine]] -# The list of services the main weewx engine should run: -service_list = weewx.wxengine.StdWunderground, weewx.wxengine.StdCatchUp, weewx.wxengine.StdTimeSynch, weewx.wxengine.StdPrint, weewx.wxengine.StdProcess - diff --git a/skins/Ftp/skin.conf b/skins/Ftp/skin.conf index 5798d6ca..3ba74474 100644 --- a/skins/Ftp/skin.conf +++ b/skins/Ftp/skin.conf @@ -12,9 +12,9 @@ # # ############################################################################################ # -# $Revision: 164 $ -# $Author: tkeffer $ -# $Date: 2010-03-16 16:16:04 -0700 (Tue, 16 Mar 2010) $ +# $Revision$ +# $Author$ +# $Date$ # ############################################################################################ diff --git a/skins/Standard/skin.conf b/skins/Standard/skin.conf index 014c846f..bf1d13b6 100644 --- a/skins/Standard/skin.conf +++ b/skins/Standard/skin.conf @@ -73,7 +73,7 @@ generator_list = weewx.reportengine.ByMonth, weewx.reportengine.ByYear, weewx.re # This is things like NOAA summaries by month. # [[NOAA_month]] - template = NOAA/NOAA_month.txt.tmpl + template = NOAA/NOAA-YYYY-MM.txt.tmpl destination_dir = NOAA ############################################################################################ @@ -85,7 +85,7 @@ generator_list = weewx.reportengine.ByMonth, weewx.reportengine.ByYear, weewx.re # This is things like NOAA summaries by year. # [[NOAA_year]] - template = NOAA_year.txt.tmpl + template = NOAA/NOAA-YYYY.txt.tmpl destination_dir = NOAA ############################################################################################ diff --git a/weeutil/weeutil.py b/weeutil/weeutil.py index e401150a..c2a62c75 100644 --- a/weeutil/weeutil.py +++ b/weeutil/weeutil.py @@ -14,7 +14,7 @@ import time import math import ImageFont import configobj - +from htmlentitydefs import codepoint2name def min_no_None(seq): """Searches sequence of tuples, returning tuple where the first member was a minimum. @@ -536,6 +536,21 @@ def latlon_string(ll, hemi): min = frac * 60.0 return ("%d" % (deg,), "%0.2f" % (min,), hemi[0] if ll >= 0 else hemi[1]) +def htmlescape(instring): + """Escape all entities and non-7bit characters.""" + + outlist = [] + for c in instring: + n = ord(c) + if n < 128: + outlist.append(c) + else: + if n in codepoint2name: + outlist.append("&%s;" % codepoint2name[n]) + else: + outlist.append("&#%d;" % n) + return ''.join(outlist) + def _get_object(module_class, *args, **kwargs): """Given a path to a class, instantiates an instance of the class with the given args and returns it.""" diff --git a/weewx.conf b/weewx.conf index 142d8f48..f0f8c744 100644 --- a/weewx.conf +++ b/weewx.conf @@ -40,7 +40,7 @@ version = 1.6.0 # # Root directory of the weewx file hierarchy for this station: - WEEWX_ROOT = /home/tkeffer/workspace/weewx + WEEWX_ROOT = /home/weewx location = "Hood River, Oregon" @@ -301,8 +301,8 @@ version = 1.6.0 [[Report1]] skin = Standard - [[FTP]] - skin = Ftp + #[[FTP]] + # skin = Ftp ############################################################################################ diff --git a/weewx/genfiles.py b/weewx/genfiles.py index de52bd6f..cb220b5c 100644 --- a/weewx/genfiles.py +++ b/weewx/genfiles.py @@ -30,14 +30,10 @@ class GenFiles(object): """Base class for generator classes that generate files""" def __init__(self, report_dict): - self.report_dict = report_dict self.initStation(report_dict) self.initStats(report_dict) self.initUnits(report_dict) - self.moonphases = report_dict['Almanac'].get('moon_phases') -# self.initNoaa(report_dict) -# self.initHtml(report_dict) def initStation(self, report_dict): # station holds info such as 'altitude', 'latitude', etc. It seldom changes @@ -54,192 +50,149 @@ class GenFiles(object): def initUnits(self, report_dict): self.unitTypeDict = weewx.units.getUnitTypeDict(report_dict) + def _prepGen(self, subreport_dict): + + accum_dict = weeutil.weeutil.accumulateLeaves(subreport_dict) + template = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], + self.report_dict['Reports']['SKIN_ROOT'], + accum_dict['skin'], + accum_dict['template']) + destination_dir = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], + self.report_dict['Reports']['HTML_ROOT'], + accum_dict['destination_dir']) + try: + # Create the directory that is to receive the generated files. If + # it already exists an exception will be thrown, so be prepared to + # catch it. + os.makedirs(destination_dir) + except OSError: + pass + + return (template, destination_dir) + class GenByMonth(GenFiles): """Class for generating reports that run 'by month.'""" - - def run(self): + + def generate(self, start_ts, stop_ts): + for subreport in self.report_dict['ByMonth'].sections: print "starting GenByMonth subreport ", subreport - - accum_dict = weeutil.weeutil.accumulateLeaves(self.report_dict['ByMonth'][subreport]) + + (template, destination_dir) = self._prepGen(self.report_dict['ByMonth'][subreport]) - template = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], - self.report_dict['Reports']['SKIN_ROOT'], - accum_dict['skin'], - accum_dict['template']) - destination_dir = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], - self.report_dict['Reports']['HTML_ROOT'], - accum_dict['destination_dir']) - print "Using template ", template - print "Putting results in ", destination_dir - + ngen = 0 + t1 = time.time() + # Loop through all months, looking for reports that need to be + # generated. + for monthSpan in weeutil.weeutil.genMonthSpans(start_ts, stop_ts): + # Calculate the file name for this month + _month_start_tt = time.localtime(monthSpan.start) + _filename = os.path.basename(template).replace('YYYY', "%4d" % _month_start_tt[0]).replace('MM', "%02d" % _month_start_tt[1]).replace('.tmpl','') + _fullpath = os.path.join(destination_dir, _filename) + print "ByMonth output will go to path ", _fullpath + + # If the file doesn't exist, or it is the last month, then + # we must generate it + if not os.path.exists(_fullpath) or monthSpan.includesArchiveTime(stop_ts): + + searchList = self.getSearchList(monthSpan) + # Run everything through the template engine + text = Cheetah.Template.Template(file = template, searchList = searchList) + # Open up the file that is to be created: + file = open(_fullpath, mode='w') + # Write it out + print >> file, text + # Close it + file.close() + ngen += 1 + + t2 = time.time() + elapsed_time = t2 - t1 + syslog.syslog(syslog.LOG_INFO, """genfiles: generated %d "ByMonth" files in %.2f seconds""" % (ngen, elapsed_time)) + + def getSearchList(self, monthSpan): + """Return the searchList for the Cheetah Template engine for month NOAA reports. + + Can easily be overridden to add things to the search list. + """ + month_start_tt = time.localtime(monthSpan.start) + # Form a suitable name for the month: + (_yr, _mo) = month_start_tt[0:2] + monthName = time.strftime("%b", month_start_tt) + + # Get the stats for this month from the database: + monthStats = weewx.stats.TimespanStats(self.statsdb, monthSpan, self.unitTypeDict) + + searchList = [{'station' : self.station, + 'year_name' : _yr, + 'month_name' : monthName, + 'month' : monthStats}] + return searchList class GenByYear(GenFiles): """Class for generating reports that run 'by year.'""" + def generate(self, start_ts, stop_ts): + for subreport in self.report_dict['ByYear'].sections: + print "starting GenByYear subreport ", subreport + + (template, destination_dir) = self._prepGen(self.report_dict['ByYear'][subreport]) + + ngen = 0 + t1 = time.time() + + # Loop through all months, looking for reports that need to be + # generated. + for yearSpan in weeutil.weeutil.genYearSpans(start_ts, stop_ts): + # Calculate the file name for this month + _month_start_tt = time.localtime(yearSpan.start) + _filename = os.path.basename(template).replace('YYYY', "%4d" % _month_start_tt[0]).replace('.tmpl','') + _fullpath = os.path.join(destination_dir, _filename) + print "ByYear output will go to path ", _fullpath + + # If the file doesn't exist, or it is the last month, then + # we must generate it + if not os.path.exists(_fullpath) or yearSpan.includesArchiveTime(stop_ts): + + searchList = self.getSearchList(yearSpan) + # Run everything through the template engine + text = Cheetah.Template.Template(file = template, searchList = searchList) + # Open up the file that is to be created: + file = open(_fullpath, mode='w') + # Write it out + print >> file, text + # Close it + file.close() + ngen += 1 + + t2 = time.time() + elapsed_time = t2 - t1 + syslog.syslog(syslog.LOG_INFO, """genfiles: generated %d "ByYear" files in %.2f seconds""" % (ngen, elapsed_time)) + + def getSearchList(self, yearSpan): + """Return the searchList for the Cheetah Template engine for By Year reports. + + Can easily be overridden to add things to the search list. + """ + + _yr = time.localtime(yearSpan.start)[0] + + yearStats = weewx.stats.TimespanStats(self.statsdb, yearSpan, self.unitTypeDict) + + searchList = [{'station' : self.station, + 'year_name' : _yr, + 'year' : yearStats}] + + return searchList + class GenToDate(GenFiles): """Class for generating "to date" reports, such as daily, weekly, monthly, and yearly summaries.""" - - - def initNoaa(self, report_dict): - # Get the directory holding the NOAA templates - self.noaa_template_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'], - report_dict['NOAA'].get('template_root', 'templates')) - - # Get the directory that will hold the generated NOAA reports: - self.noaa_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'], - report_dict['NOAA'].get('noaa_dir', 'public_html/NOAA')) - - try: - # Create the directory that is to receive the generated files. If - # it already exists an exception will be thrown, so be prepared to - # catch it. - os.makedirs(self.noaa_dir) - except OSError: - pass - - - def initHtml(self, report_dict): - - # Get the directory holding the templates - self.html_template_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'], - report_dict['HTML'].get('template_root', 'templates')) - # Get the directories that will hold the generated HTML files: - self.html_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'], - report_dict['HTML'].get('html_root', 'public_html')) - - # Get an appropriate formatter: - self.formatter = weewx.formatter.Formatter(weewx.units.getStringFormatDict(report_dict), - weewx.units.getHTMLLabelDict(report_dict), - report_dict['HTML']['Time']) - - try: - # Create the directory that is to receive the generated files. If - # it already exists an exception will be thrown, so be prepared to - # catch it. - os.makedirs(self.html_dir) - except OSError: - pass - - self.template_list = ('index', 'week', 'month', 'year') - - def initAlmanac(self, celestial_ts): - """ Initialize an instance of weeutil.Almanac.Almanac for the station's - lat and lon, and for a specific time. - - celestial_ts: The timestamp of the time for which the Almanac is to - be initialized. + def generate(self, currentRec, stop_ts): """ - # almanac holds celestial information (sunrise, phase of moon). Its celestial - # data slowly changes. - self.almanac = weeutil.Almanac.Almanac(celestial_ts, - self.station.latitude_f, - self.station.longitude_f, - self.moonphases) - - def generateNoaa(self, start_ts, stop_ts): - """ Generate NOAA yearly and monthly reports. - - start_ts: The timestamp of the earliest data to be included. - - stop_ts: The report will be current as of this timestamp.""" - - self.generateNoaaYears(start_ts, stop_ts) - self.generateNoaaMonths(start_ts, stop_ts) - - def generateNoaaYears(self, start_ts, stop_ts): - """ Generate NOAA yearly reports. - - start_ts: A timestamp within the year of the first report to be - generated. - - stop_ts: A timestamp within the year of the last report to be - generated.""" - - - ngen = 0 - t1 = time.time() - - # This is the template to be used to generate the yearly reports: - noaa_year_template_file = os.path.join(self.noaa_template_dir, "NOAA_year.tmpl") - - # Loop through all months, looking for reports that need to be - # generated. - for yearSpan in weeutil.weeutil.genYearSpans(start_ts, stop_ts): - - _yr = time.localtime(yearSpan.start)[0] - _filename = "NOAA-%d.txt" % _yr - _fullpath = os.path.join(self.noaa_dir, _filename) - - # If the file doesn't exist, or it is the last year, then - # we must generate it - if not os.path.exists(_fullpath) or yearSpan.includesArchiveTime(stop_ts): - - searchList = self.get_Year_SearchList(yearSpan, stop_ts) - - # Run everything through the template engine - text = Cheetah.Template.Template(file = noaa_year_template_file, searchList = searchList) - # Open up the file that is to be created: - file = open(_fullpath, mode='w') - # Write it out - print >> file, text - # Close it - file.close() - ngen += 1 - - t2 = time.time() - elapsed_time = t2 - t1 - syslog.syslog(syslog.LOG_INFO, "gennoaa: generated %d NOAA year files in %.2f seconds" % (ngen, elapsed_time)) - - def generateNoaaMonths(self, start_ts, stop_ts): - """ Generate NOAA monthly reports. - - start_ts: A timestamp within the month of the first report to be - generated. - - stop_ts: A timestamp within the month of the last report to be - generated.""" - - ngen = 0 - t1 = time.time() - - # This is the template to be used to generate the monthly reports: - noaa_month_template_file = os.path.join(self.noaa_template_dir, "NOAA_month.tmpl") - - # Loop through all months, looking for reports that need to be - # generated. - for monthSpan in weeutil.weeutil.genMonthSpans(start_ts, stop_ts): - # Calculate the file name for this month - _month_start_tt = time.localtime(monthSpan.start) - _filename = "NOAA-%d-%02d.txt" % _month_start_tt[0:2] - _fullpath = os.path.join(self.noaa_dir, _filename) - - # If the file doesn't exist, or it is the last month, then - # we must generate it - if not os.path.exists(_fullpath) or monthSpan.includesArchiveTime(stop_ts): - - searchList = self.get_Month_SearchList(monthSpan, stop_ts) - # Run everything through the template engine - text = Cheetah.Template.Template(file = noaa_month_template_file, searchList = searchList) - # Open up the file that is to be created: - file = open(_fullpath, mode='w') - # Write it out - print >> file, text - # Close it - file.close() - ngen += 1 - - t2 = time.time() - elapsed_time = t2 - t1 - syslog.syslog(syslog.LOG_INFO, "gennoaa: generated %d NOAA monthly files in %.2f seconds" % (ngen, elapsed_time)) - - def generateHtml(self, currentRec, stop_ts): - """Generate HTML pages. - currentRec: A dictionary containing current observation. Key is a type ('outTemp', 'barometer', etc.), value the value of the variable. Usually, this is an archive record. @@ -247,32 +200,57 @@ class GenToDate(GenFiles): stop_ts: A timestamp. The HTML files generated will be current as of this time.""" - self.initAlmanac(stop_ts) - - searchList = self.get_Html_SearchList(currentRec, stop_ts) ngen = 0 t1 = time.time() - # Generate for each HTML template: - for template in self.template_list: - - # Here's the full path to the template file: - template_file = os.path.join(self.html_template_dir, template + ".tmpl") + # Get an appropriate formatter: + self.formatter = weewx.formatter.Formatter(weewx.units.getStringFormatDict(self.report_dict), + weewx.units.getHTMLLabelDict(self.report_dict), + self.report_dict['Labels']['Time']) + self.initAlmanac(stop_ts) + + searchList = self.getSearchList(currentRec, stop_ts) + + for subreport in self.report_dict['ToDate'].sections: + print "starting GenToDate subreport ", subreport + + (template, destination_dir) = self._prepGen(self.report_dict['ToDate'][subreport]) + + print "GenToDate template is ", template, "; destination dir is ", destination_dir + #=================================================================== # Here's where the heavy lifting occurs. Use Cheetah to actually # generate the files. It will use introspection on the searchList to # populate the parameters in the template file. # =================================================================== - html = Cheetah.Template.Template(file = template_file, searchList = searchList) + html = Cheetah.Template.Template(file = template, searchList = searchList) file = open(os.path.join(self.html_dir, template + ".html"), mode='w') print >> file, html ngen += 1 - + elapsed_time = time.time() - t1 - syslog.syslog(syslog.LOG_INFO, "genhtml: generated %d HTML pages in %.2f seconds" % (ngen, elapsed_time)) + syslog.syslog(syslog.LOG_INFO, "genhtml: generated %d 'toDate' pages in %.2f seconds" % (ngen, elapsed_time)) + + def initAlmanac(self, celestial_ts): + """ Initialize an instance of weeutil.Almanac.Almanac for the station's + lat and lon, and for a specific time. + + celestial_ts: The timestamp of the time for which the Almanac is to + be initialized. + """ + self.moonphases = self.report_dict['Almanac'].get('moon_phases') + + # almanac holds celestial information (sunrise, phase of moon). Its celestial + # data slowly changes. + self.almanac = weeutil.Almanac.Almanac(celestial_ts, + self.station.latitude_f, + self.station.longitude_f, + self.moonphases) + + def get_existing_NOAA_reports(self): @@ -295,42 +273,8 @@ class GenToDate(GenFiles): year_list.append(_file[5:9]) return (month_list, year_list) - def get_Year_SearchList(self, yearSpan, stop_ts): - """Return the searchList for the Cheetah Template engine for year NOAA reports. - - Can easily be overridden to add things to the search list. - """ - - _yr = time.localtime(yearSpan.start)[0] - - yearStats = weewx.stats.TimespanStats(self.statsdb, yearSpan, self.unitTypeDict) - - searchList = [{'station' : self.station, - 'year_name' : _yr, - 'year' : yearStats}] - - return searchList - - def get_Month_SearchList(self, monthSpan, stop_ts): - """Return the searchList for the Cheetah Template engine for month NOAA reports. - - Can easily be overridden to add things to the search list. - """ - month_start_tt = time.localtime(monthSpan.start) - # Form a suitable name for the month: - (_yr, _mo) = month_start_tt[0:2] - monthName = time.strftime("%b", month_start_tt) - - # Get the stats for this month from the database: - monthStats = weewx.stats.TimespanStats(self.statsdb, monthSpan, self.unitTypeDict) - - searchList = [{'station' : self.station, - 'year_name' : _yr, - 'month_name' : monthName, - 'month' : monthStats}] - return searchList - def get_Html_SearchList(self, currentRec, stop_ts): + def getSearchList(self, currentRec, stop_ts): """Return the searchList for the Cheetah Template engine for HTML generation. Can easily be overridden to add things to the search list. diff --git a/weewx/reportengine.py b/weewx/reportengine.py index e2ee42b4..f844fa95 100644 --- a/weewx/reportengine.py +++ b/weewx/reportengine.py @@ -86,7 +86,7 @@ class StdReportEngine(threading.Thread): for generator in generator_list: try: # Instantiate an instance of the class - obj = weeutil.weeutil._get_object(generator, report_dict) + obj = weeutil.weeutil._get_object(generator, report_dict, self.gen_ts) # Call its start() method obj.start() @@ -100,8 +100,9 @@ class StdReportEngine(threading.Thread): class ReportGenerator(object): """Base class for all reports.""" - def __init__(self, report_dict): + def __init__(self, report_dict, gen_ts): self.report_dict = report_dict + self.gen_ts = gen_ts def start(self): self.run() @@ -114,15 +115,46 @@ class ByMonth(ReportGenerator): def run(self): print "Running ByMonth reports..." + # Open up the main database archive + archiveFilename = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], + self.report_dict['Archive']['archive_file']) + archive = weewx.archive.Archive(archiveFilename) + + stop_ts = archive.lastGoodStamp() if self.gen_ts is None else self.gen_ts + start_ts = archive.firstGoodStamp() byMonth = weewx.genfiles.GenByMonth(self.report_dict) - byMonth.run() + byMonth.generate(start_ts, stop_ts) class ByYear(ReportGenerator): """Creates yearly reports, such as NOAA reports.""" + def run(self): + print "Running ByYear reports..." + # Open up the main database archive + archiveFilename = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], + self.report_dict['Archive']['archive_file']) + archive = weewx.archive.Archive(archiveFilename) + + stop_ts = archive.lastGoodStamp() if self.gen_ts is None else self.gen_ts + start_ts = archive.firstGoodStamp() + byYear = weewx.genfiles.GenByYear(self.report_dict) + byYear.generate(start_ts, stop_ts) + class ToDate(ReportGenerator): """Creates snapshot statistical reports.""" + def run(self): + print "Running ToDate reports..." + # Open up the main database archive + archiveFilename = os.path.join(self.report_dict['Station']['WEEWX_ROOT'], + self.report_dict['Archive']['archive_file']) + archive = weewx.archive.Archive(archiveFilename) + + stop_ts = archive.lastGoodStamp() if self.gen_ts is None else self.gen_ts + currentRec = archive.getRecord(stop_ts, weewx.units.getUnitTypeDict(self.report_dict)) + toDate = weewx.genfiles.GenToDate(self.report_dict) + toDate.generate(currentRec, stop_ts) + class Images(ReportGenerator): """Creates plots""" diff --git a/weewx/units.py b/weewx/units.py index 8ec61115..5f59af9c 100644 --- a/weewx/units.py +++ b/weewx/units.py @@ -12,6 +12,7 @@ """ import weewx +import weeutil.weeutil # This data structure maps types to a "unit class" unitGroups = {"barometer" : "group_pressure", @@ -180,7 +181,7 @@ def getLabel(config_dict, type): def getHTMLLabel(config_dict, type): """Extract an HTML unit label (e.g., "°F") for a specific type""" - return config_dict['HTML']['UnitLabels'][getUnitType(config_dict, type)] + return weeutil.weeutil.htmlescape(getLabel(config_dict, type)) def getStringFormatDict(config_dict): """Return a dictionary of suitable string formats for all types."""