Code Monkey home page Code Monkey logo

enhydris-synoptic's Introduction

Enhydris-synoptic - Display current weather conditions

Build button Coverage

Enhydris-synoptic is an app that adds a page to Enhydris that shows current conditions in several stations.

Note that it does not check permissions; any synoptic view created will be public, regardless of whether the timeseries from which it is derived are marked top secret.

Enhydris-synoptic is free software, available under the GNU Affero General Public License.

Installing

  • Install Enhydris 3 or later

  • Make sure enhydris_synoptic is in the PYTHONPATH, or link to it from the top-level directory of Enhydris.

  • In the Enhydris enhydris/settings/local.py file, add enhydris_synoptic to INSTALLED_APPS, and set ENHYDRIS_SYNOPTIC_ROOT and ENHYDRIS_SYNOPTIC_URL.

    Enhydris-synoptic works by creating static files which are then served by the web server. ENHYDRIS_SYNOPTIC_ROOT indicates where these files shall be stored. ENHYDRIS_SYNOPTIC_URL is currently not used anywhere, but it's better to set it anyway; later versions might start to use it without warning.

  • In the Enhydris configuration directory, execute python manage.py migrate.

  • Run celery and celerybeat, and configure celerybeat to execute the enhydris_synoptic.tasks.create_static_files task once in a while.

  • Configure your web server to serve ENHYDRIS_SYNOPTIC_ROOT at ENHYDRIS_SYNOPTIC_URL.

  • Go to the admin and setup a view.

After celery executes, the report will be available at ENHYDRIS_SYNOPTIC_URL + slug + '/', where slug is the URL identifier given to the synoptic view.

Configuration reference

  • ENHYDRIS_SYNOPTIC_ROOT: The filesystem path where the generated files will be stored (see above).
  • ENHYDRIS_SYNOPTIC_URL: The URL where the generated files will be served (see above).
  • ENHYDRIS_SYNOPTIC_STATION_LINK_TARGET: In the rectangles shown on the map, the station name is a link. This is the link target. The default is station/{station.id}/ (the code will use .format() to replace {station.id} with the station id). This default link target leads to a page created by enhydris-synoptic that has a short report about the station, and charts for the last 24 hours. However, in some installations this is undesirable, and it is preferred for the link to lead to the Enhydris station page—in that case, set ENHYDRIS_SYNOPTIC_STATION_LINK_TARGET to /stations/{station.id}/ (if the synoptic domain name is different from the main Enhydris domain name, you need to specify the full URL). (It would be better to use django.urls.reverse() here instead of a hardwired URL, but it isn't easy to find a general enough solution for all that.)

Meta

Copyright (C) 2015-2017 TEI of Epirus
Copyright (C) 2018-2021 National Technical University of Athens
Copyright (C) 2018-2021 Institute of Communication and Computer Systems

Enhydris-synoptic is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License, as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

The software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the licenses for more details.

You should have received a copy of the license along with this program. If not, see http://www.gnu.org/licenses/.

Enhydris was funded by several organizations:

enhydris-synoptic's People

Contributors

aptiko avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

aptiko ad0v0 shrhawk

enhydris-synoptic's Issues

SynopticGroupStation' object is not subscriptable; Cannot cast array from dtype('O') to dtype('float64') according to the rule 'safe'

Task id: 5d478c07-bb21-4244-95ad-36544977ea28

Traceback (most recent call last):
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 829, in _resolve_lookup
    current = current[bit]
TypeError: 'SynopticGroupStation' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "pandas/_libs/parsers.pyx", line 1173, in pandas._libs.parsers.TextReader._convert_tokens
TypeError: Cannot cast array from dtype('O') to dtype('float64') according to the rule 'safe'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/celery/app/trace.py", line 650, in __protected_call__
    return self.run(*args, **kwargs)
  File "/opt/enhydris-openhi/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)
  File "/opt/enhydris-openhi/enhydris_synoptic/views.py", line 91, in render_synoptic_group
    _render_only_group(synoptic_group)
  File "/opt/enhydris-openhi/enhydris_synoptic/views.py", line 97, in _render_only_group
    output = render_to_string("enhydris-synoptic/group.html", context=context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/defaulttags.py", line 209, in render
    nodelist.append(node.render_annotated(context))
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/defaulttags.py", line 161, in render
    values = self.sequence.resolve(context, ignore_failures=True)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 671, in resolve
    obj = self.var.resolve(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 796, in resolve
    value = self._resolve_lookup(context)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/template/base.py", line 837, in _resolve_lookup
    current = getattr(current, bit)
  File "/opt/enhydris-openhi/enhydris_synoptic/models.py", line 104, in synoptic_timeseries_groups
    self._determine_timeseries_groups()
  File "/opt/enhydris-openhi/enhydris_synoptic/models.py", line 116, in _determine_timeseries_groups
    start_date=start_date, end_date=self.last_common_date
  File "/opt/enhydris-openhi/enhydris/models.py", line 573, in get_data
    data = cache.get_or_set(f"timeseries_data_{self.id}", self._get_all_data_as_pd)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/django/core/cache/backends/base.py", line 167, in get_or_set
    default = default()
  File "/opt/enhydris-openhi/enhydris/models.py", line 603, in _get_all_data_as_pd
    return HTimeseries(StringIO(cursor.fetchone()[0])).data
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/htimeseries/htimeseries.py", line 340, in __init__
    self._read_filelike(data, **kwargs)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/htimeseries/htimeseries.py", line 347, in _read_filelike
    self.data = reader.get_data()
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/htimeseries/htimeseries.py", line 381, in get_data
    return TimeseriesRecordsReader(self.f, self.start_date, self.end_date).read()
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/htimeseries/htimeseries.py", line 403, in read
    data = self._read_data_from_stream(f2)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/htimeseries/htimeseries.py", line 432, in _read_data_from_stream
    dtype={"value": np.float64},
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/pandas/io/parsers.py", line 685, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/pandas/io/parsers.py", line 463, in _read
    data = parser.read(nrows)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/pandas/io/parsers.py", line 1154, in read
    ret = self._engine.read(nrows)
  File "/opt/enhydris-openhi/venv/lib/python3.7/site-packages/pandas/io/parsers.py", line 2059, in read
    data = self._reader.read(nrows)
  File "pandas/_libs/parsers.pyx", line 881, in pandas._libs.parsers.TextReader.read
  File "pandas/_libs/parsers.pyx", line 896, in pandas._libs.parsers.TextReader._read_low_memory
  File "pandas/_libs/parsers.pyx", line 973, in pandas._libs.parsers.TextReader._read_rows
  File "pandas/_libs/parsers.pyx", line 1105, in pandas._libs.parsers.TextReader._convert_column_data
  File "pandas/_libs/parsers.pyx", line 1181, in pandas._libs.parsers.TextReader._convert_tokens
ValueError: cannot safely convert passed user dtype of float64 for object dtyped data in column 1

Make cards transparent

The cards on the map with the latest conditions should have opacity 80% and no border. Otherwise when there are many stations the map will be hardly visible.

Rework synoptic front page

Map should occupy the entire screen. The reports underneath should probably go (they're accessible through clicking on the station anyway).

Takes too long on production

Each time task create_static_files runs on production it takes about one and a half hours. It should be finishing in a minute or so. (The result is that the queue grows and grows, since it's set to run every 10 minutes.)

Celery stops with an error

2019-08-29 10:32:00,115: ERROR/ForkPoolWorker-1] Task enhydris_synoptic.tasks.create_static_files[c8176fe2-6be6-4ee3-8cfe-aededcb657f6] raised unexpected: AttributeError("type object 'dummy_request' has no attribute 'GET'",)
Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 648, in __protected_call__
    return self.run(*args, **kwargs)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 91, in render_synoptic_group
    _render_only_group(synoptic_group)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 98, in _render_only_group
    context={"object": synoptic_group, "map_js": _get_map_js(synoptic_group)},
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 107, in _get_map_js
    return enhydris.context_processors.map(dummy_request)["map_js"]
  File "/opt/enhydris-openmeteo/enhydris/context_processors.py", line 33, in map
    json.dumps(request.GET.get("q", ""))
AttributeError: type object 'dummy_request' has no attribute 'GET'

AttributeError: 'Series' object has no attribute 'find'

Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 648, in __protected_call__
    return self.run(*args, **kwargs)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 92, in render_synoptic_group
    _render_group_stations(synoptic_group)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 121, in _render_group_stations
    render_synoptic_station(synstation)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 72, in render_synoptic_station
    _render_station_charts(synstation)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 87, in _render_station_charts
    Chart(t, synstation.synoptic_timeseries).render()
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 133, in render
    self._draw_lines()
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 170, in _draw_lines
    self.xdata, self.ydata, color=self._get_color(i), label=s.get_subtitle()
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/__init__.py", line 1819, in inner
    return func(ax, *args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axes/_axes.py", line 1382, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 381, in _grab_next_args
    for seg in self._plot_args(remaining, kwargs):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 331, in _plot_args
    linestyle, marker, color = _process_plot_format(tup[-1])
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 86, in _process_plot_format
    if fmt.find('--') >= 0:
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/pandas/core/generic.py", line 5067, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'find'

Determine time series automatically

Users who add stations to synoptic have to add the list of time series, and this is tedious work, especially if there are many stations and all have the same variables.

In order for this to work in all cases, maybe the system could just fill in the form, but it would be the user's responsibility to accept it as is or modify it before clicking "save".

Uses system locale

If the locale is set to something else than UTF-8, it attempts to use that one. It should probably ignore it and use UTF-8 when writing files.

TypeError: 'SynopticGroupStation' object is not subscriptable



Task id: e0f1d649-a6d2-4faa-b781-a4968b477105

Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 829, in _resolve_lookup
    current = current[bit]
TypeError: 'SynopticGroupStation' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/celery/app/trace.py", line 650, in __protected_call__
    return self.run(*args, **kwargs)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 91, in render_synoptic_group
    _render_only_group(synoptic_group)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 97, in _render_only_group
    output = render_to_string("enhydris-synoptic/group.html", context=context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/defaulttags.py", line 209, in render
    nodelist.append(node.render_annotated(context))
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 987, in render
    output = self.filter_expression.resolve(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 671, in resolve
    obj = self.var.resolve(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 796, in resolve
    value = self._resolve_lookup(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.7/site-packages/django/template/base.py", line 837, in _resolve_lookup
    current = getattr(current, bit)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/models.py", line 164, in last_common_date_pretty_without_timezone
    return self.last_common_date and self.last_common_date.astimezone(
  File "/opt/enhydris-openmeteo/enhydris_synoptic/models.py", line 142, in last_common_date
    self._determine_last_common_date()
  File "/opt/enhydris-openmeteo/enhydris_synoptic/models.py", line 151, in _determine_last_common_date
    end_date = asyntsg.timeseries_group.default_timeseries.end_date
AttributeError: 'NoneType' object has no attribute 'end_date'

Crash when one of the time series contains a single (null) record in the last 24 hours

Monastiri has been working fine until 2020-02-18 14:00. From that point on until now, there is only one record:

2020-02-19 14:00,,RANGE

Since 14:00 earlier today, each time it runs create_static_files() there's this error:

[2020-02-19 12:08:24,476: ERROR/ForkPoolWorker-1] Signal handler <function email_failed_task at 0x7f0169d0a6a8> raised: OSError(99, 'Cannot assign requested address')
Traceback (most recent call last):                                                                                        
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/celery/app/trace.py", line 385, in trace_task                 
    R = retval = fun(*args, **kwargs)                                                                                        
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/celery/app/trace.py", line 648, in __protected_call__
    return self.run(*args, **kwargs)                                                                                                                                                                                                                         
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)                                                                          
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/views.py", line 92, in render_synoptic_group
    _render_group_stations(synoptic_group)
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/views.py", line 119, in _render_group_stations
    render_synoptic_station(synstation)
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/views.py", line 72, in render_synoptic_station
    _render_station_charts(synstation)
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/views.py", line 87, in _render_station_charts
    Chart(t, synstation.synoptic_timeseries).render()
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/views.py", line 138, in render
    self._create_and_save_plot()
  File "/home/anthony/nosync/development/openmeteo/enhydris/enhydris_synoptic/views.py", line 208, in _create_and_save_plot
    self.fig.savefig(f)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/figure.py", line 2180, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/backend_bases.py", line 2089, in print_figure
    **kwargs)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py", line 527, in print_png
    FigureCanvasAgg.draw(self)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
    self.figure.draw(self.renderer)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/figure.py", line 1709, in draw
    renderer, self, artists, self.suppressComposite)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 2647, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/axis.py", line 1203, in draw
    ticks_to_draw = self._update_ticks()
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/axis.py", line 1079, in _update_ticks
    major_locs = self.get_majorticklocs()
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/axis.py", line 1324, in get_majorticklocs
    return self.major.locator()
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/dates.py", line 1243, in __call__
    return self.tick_values(dmin, dmax)
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/dates.py", line 1265, in tick_values
    return self.raise_if_exceeds(date2num(dates))
  File "/home/anthony/nosync/virtualenvs/enhydris/lib/python3.7/site-packages/matplotlib/ticker.py", line 1523, in raise_if_exceeds
    len(locs), locs[0], locs[-1]))
RuntimeError: Locator attempting to generate 1460 ticks from 736745.0 to 738204.0: exceeds Locator.MAXTICKS

Internal server error when trying to access a synoptic group station in the admin

Traceback:

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in wrapper
  606.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/sites.py" in inner
  223.             return view(request, *args, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in change_view
  1637.         return self.changeform_view(request, object_id, form_url, extra_context)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in changeform_view
  1522.             return self._changeform_view(request, object_id, form_url, extra_context)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in _changeform_view
  1579.                 formsets, inline_instances = self._create_formsets(request, obj, change=True)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in _create_formsets
  1932.         for FormSet, inline in self.get_formsets_with_inlines(*get_formsets_args):

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in get_formsets_with_inlines
  794.             yield inline.get_formset(request, obj), inline

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in get_formset
  2036.             fields = flatten_fieldsets(self.get_fieldsets(request, obj))

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in get_fieldsets
  330.         return [(None, {'fields': self.get_fields(request, obj)})]

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in get_fields
  321.         form = self._get_form_for_get_fields(request, obj)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in _get_form_for_get_fields
  2121.         return self.get_formset(request, obj, fields=None).form

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in get_formset
  2118.         return inlineformset_factory(self.parent_model, self.model, **defaults)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/forms/models.py" in inlineformset_factory
  1077.     FormSet = modelformset_factory(model, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/forms/models.py" in modelformset_factory
  875.                              error_messages=error_messages, field_classes=field_classes)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/forms/models.py" in modelform_factory
  551.     return type(form)(class_name, (form,), form_class_attrs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/forms/models.py" in __new__
  256.                 apply_limit_choices_to=False,

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/forms/models.py" in fields_for_model
  176.             formfield = formfield_callback(f, **kwargs)

File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/contrib/admin/options.py" in formfield_for_dbfield
  156.                 formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)

File "/opt/enhydris-openmeteo/enhydris_synoptic/admin.py" in formfield_for_foreignkey
  24.             synopticgroupstation_id = int(request.resolver_match.args[0])

Exception Type: IndexError at /admin/enhydris_synoptic/synopticgroupstation/8/change/
Exception Value: tuple index out of range

Add meta http-equiv="Content-Type" tag

When serving with the django development server's django.views.static.serve(), we don't get the charset in the "Content-Type" HTTP header and it shows some garbage.

RuntimeError: Locator attempting to generate 1606 ticks from 736591.0 to 738196.0: exceeds Locator.MAXTICKS

Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 648, in __protected_call__
    return self.run(*args, **kwargs)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 92, in render_synoptic_group
    _render_group_stations(synoptic_group)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 119, in _render_group_stations
    render_synoptic_station(synstation)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 72, in render_synoptic_station
    _render_station_charts(synstation)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 87, in _render_station_charts
    Chart(t, synstation.synoptic_timeseries).render()
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 136, in render
    self._create_and_save_plot()
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 205, in _create_and_save_plot
    self.fig.savefig(f)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/figure.py", line 2094, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/backend_bases.py", line 2075, in print_figure
    **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py", line 510, in print_png
    FigureCanvasAgg.draw(self)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py", line 402, in draw
    self.figure.draw(self.renderer)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/figure.py", line 1649, in draw
    renderer, self, artists, self.suppressComposite)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/image.py", line 138, in _draw_list_compositing_images
    a.draw(renderer)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 2628, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/image.py", line 138, in _draw_list_compositing_images
    a.draw(renderer)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axis.py", line 1185, in draw
    ticks_to_draw = self._update_ticks(renderer)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axis.py", line 1023, in _update_ticks
    tick_tups = list(self.iter_ticks())  # iter_ticks calls the locator
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/axis.py", line 967, in iter_ticks
    majorLocs = self.major.locator()
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/dates.py", line 1044, in __call__
    return self.tick_values(dmin, dmax)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/dates.py", line 1066, in tick_values
    return self.raise_if_exceeds(date2num(dates))
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/matplotlib/ticker.py", line 1451, in raise_if_exceeds
    len(locs), locs[0], locs[-1]))
RuntimeError: Locator attempting to generate 1606 ticks from 736591.0 to 738196.0: exceeds Locator.MAXTICKS

Yet another celery crash

Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 829, in _resolve_lookup
    current = current[bit]
TypeError: 'SynopticGroupStation' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/celery/app/trace.py", line 648, in __protected_call__
    return self.run(*args, **kwargs)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/tasks.py", line 11, in create_static_files
    render_synoptic_group(sgroup)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 91, in render_synoptic_group
    _render_only_group(synoptic_group)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/views.py", line 98, in _render_only_group
    context={"object": synoptic_group, "map_js": _get_map_js(synoptic_group)},
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/defaulttags.py", line 209, in render
    nodelist.append(node.render_annotated(context))
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/loader_tags.py", line 188, in render
    return template.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 173, in render
    return self._render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/defaulttags.py", line 309, in render
    return nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/templatetags/tz.py", line 94, in render
    output = self.nodelist.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 937, in render
    bit = node.render_annotated(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 904, in render_annotated
    return self.render(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 987, in render
    output = self.filter_expression.resolve(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 671, in resolve
    obj = self.var.resolve(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 796, in resolve
    value = self._resolve_lookup(context)
  File "/opt/enhydris-openmeteo/venv/lib/python3.5/site-packages/django/template/base.py", line 837, in _resolve_lookup
    current = getattr(current, bit)
  File "/opt/enhydris-openmeteo/enhydris_synoptic/models.py", line 137, in last_common_date_pretty
    return self.last_common_date.strftime("%d %b %Y %H:%M %Z (%z)")
AttributeError: 'NoneType' object has no attribute 'strftime'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.