Exemple #1
0
    def save(self, commit=True, *args, **kwargs):

        tseries = super(TimeseriesForm, self).save(commit=False)

        # This may not be a good idea !
        if commit:
            tseries.save()

        # Handle pushing additional data if present back to the db
        if 'data' in self.cleaned_data and self.cleaned_data['data']:
            data = self.cleaned_data['data']
            ts = timeseries.Timeseries(int(self.instance.id))
            data.seek(0)
            ts.read_file(data)
            if self.cleaned_data['data_policy'] == 'A':
                pass
                # ts.append_to_db(db.connection, commit=False)
            else:
                afilename = os.path.join(settings.ENHYDRIS_TS_GRAPH_CACHE_DIR,
                                         '%d.hts' % int(self.instance.id))
                if os.path.exists(afilename):
                    os.remove(afilename)
                ts.write_to_db(db.connection, commit=False)

        return tseries
Exemple #2
0
    def clean_data(self):
        # Check if file contains valid timeseries data.
        if ('data' not in self.cleaned_data) or not self.cleaned_data['data']:
            return None
        self.cleaned_data['data'].seek(0)
        ts = timeseries.Timeseries()
        data = self.cleaned_data['data']

        try:
            ts.read_file(self.cleaned_data['data'])
        except Exception as e:
            raise forms.ValidationError(str(e))

        return self.cleaned_data['data']
Exemple #3
0
    def end_date(self):
        try:
            ts = timeseries.Timeseries(int(self.id))
        except:
            return None
        # This should be removed if ticket #112 gets resolved
        c = db_connection.cursor()
        c.execute("SELECT timeseries_end_date(%s)", (ts.id, ))
        try:
            r = c.fetchone()
        except:
            return None

        c.close()
        return r[0]
Exemple #4
0
    def testTimeseriesData(self):
        """Test that the timeseries data upload/download is correct"""

        from pthelma import timeseries
        # check uploading
        f = open("enhydris/hcore/tests/tsdata.hts", "r")

        file_dict = {'data': SimpleUploadedFile(f.name, f.read())}
        post_dict = {'gentity': self.station.pk, 'variable': self.var.pk,
                     'unit_of_measurement': self.unit.pk,
                     'time_zone': self.tz.pk
                     }
        form = TimeseriesDataForm(post_dict, file_dict, instance=self.ts)

        self.assertEqual(form.is_valid(), True)
        ts = form.save()

        ts.save()
        pts = timeseries.Timeseries(ts.id)
        pts.read_from_db(dj_connection)
        self.assertEqual(len(pts.items()), 12872)

        #check downloading
        url = "/timeseries/d/%d/download/" % self.ts.pk
        response = self.client.get(url)
        if settings.ENHYDRIS_TSDATA_AVAILABLE_FOR_ANONYMOUS_USERS:
            self.assertEqual(response.status_code, 200)
        else:
            self.assertEqual(response.status_code, 302)
            self.assertEquals(self.client.login(username='******',
                                                password='******'), True)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)

        # check fiLe
        lines = response.content.splitlines()
        linecount = len(lines)
        headerlinecount = sum([1 for x in takewhile(lambda x: x != '',
                                                    lines)]) + 1
        datalinecount = linecount - headerlinecount

        self.assertEqual(datalinecount, 12872)

        self.client.logout()
Exemple #5
0
    def clean(self):
        """
        This function checks the timestep and offset values and reports
        inconsistencies.
        """
        time_step = self.cleaned_data.get('time_step', None)
        nominal_offset_minutes = self.cleaned_data.get(
            'nominal_offset_minutes', None)
        nominal_offset_months = self.cleaned_data.get('nominal_offset_months',
                                                      None)
        actual_offset_minutes = self.cleaned_data.get('actual_offset_minutes',
                                                      None)
        actual_offset_months = self.cleaned_data.get('actual_offset_months',
                                                     None)

        if not time_step:
            if nominal_offset_minutes or nominal_offset_months or \
                    actual_offset_minutes or actual_offset_months:
                raise forms.ValidationError(
                    _("Invalid Timestep: If time step is"
                      " null, the offsets must also be null!"))
        else:
            if actual_offset_minutes is None or actual_offset_months is None:
                raise forms.ValidationError(
                    _("Invalid offset: If time step is"
                      " not null, actual offset values must be provided!"))
            if (nominal_offset_minutes is None
                and nominal_offset_months is not None) \
                    or (nominal_offset_minutes is not None
                        and nominal_offset_months is None):
                raise forms.ValidationError(
                    _("Invalid offsets: Nominal"
                      " offsets must be both null or both not null!"))

        #add a validation test for instrument in station:
        instr = self.cleaned_data.get('instrument', None)
        if instr:
            stat = self.cleaned_data.get('gentity', None)
            assert (stat)
            if Instrument.objects.filter(id=instr.id,
                                         station__id=stat.id).count() < 1:
                raise forms.ValidationError(
                    _("Selected instrument "
                      "not in selected station"))

        # XXX: This is not a good idea but it's the only way to handle append
        # errors. We save the data in the clean function instead of the save
        # and if an error occurs we show the error in the form. Another way
        # would be to write a try_append() function in pthelma.timeseries but
        # this is specific to enhydris and should not be part of the pthelma
        # module.

        if 'data' in self.cleaned_data and self.cleaned_data['data']:
            data = self.cleaned_data['data']
            ts = timeseries.Timeseries(int(self.instance.id))
            data.seek(0)
            ts.read_file(data)
            if self.cleaned_data['data_policy'] == 'A':
                try:
                    ts.append_to_db(db.connection, commit=False)
                except Exception, e:
                    raise forms.ValidationError(_(e.message))
Exemple #6
0
    def test_timeseries_data(self):
        # Upload
        with open("enhydris/hcore/tests/tsdata.hts", "r") as f:
            file_dict = {'data': SimpleUploadedFile(f.name, f.read())}
        post_dict = {'gentity': self.station.pk, 'variable': self.var.pk,
                     'unit_of_measurement': self.unit.pk,
                     'time_zone': self.tz.pk
                     }
        form = TimeseriesDataForm(post_dict, file_dict, instance=self.ts)
        self.assertTrue(form.is_valid())
        ts = form.save()
        ts.save()
        pts = timeseries.Timeseries(ts.id)
        pts.read_from_db(dj_connection)
        self.assertEqual(len(pts.items()), 12872)

        # Download

        def nrecords():
            lines = response.content.splitlines()
            linecount = len(lines)
            headerlinecount = sum([1 for x in takewhile(lambda x: x != '',
                                                        lines)]) + 1
            return linecount - headerlinecount

        if not settings.ENHYDRIS_TSDATA_AVAILABLE_FOR_ANONYMOUS_USERS:
            self.client.login(username='******', password='******')

        url = "/timeseries/d/{}/download/".format(self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.splitlines()[0].strip(), 'Version=2')
        self.assertEqual(nrecords(), 12872)

        url = "/timeseries/d/{}/download/?version=3".format(self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        ats = timeseries.Timeseries()
        ats.read_file(StringIO(response.content))
        self.assertAlmostEqual(ats.location['abscissa'], 24.67890, places=6)
        self.assertAlmostEqual(ats.location['ordinate'], 38.12345, places=6)
        self.assertEqual(ats.location['srid'], 4326)
        self.assertAlmostEqual(ats.location['altitude'], 219.22, places=2)
        self.assertTrue(ats.location['asrid'] is None)
        self.assertEqual(nrecords(), 12872)

        url = "/timeseries/d/{}/download/1960-11-04/".format(self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 12870)

        url = "/timeseries/d/{}/download/1960-11-04/1960-11-08T08:00/".format(
            self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 4)

        url = "/timeseries/d/{}/download//1960-11-08T08:00/".format(self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 6)

        url = "/timeseries/d/{}/download//1960-11-08T08:00:00/".format(
            self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 6)

        url = "/timeseries/d/{}/download/1950-02-02/1960-11-08T08:00/".format(
            self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 6)

        url = "/timeseries/d/{}/download/1950-02-02/1960-01-01T08:00/".format(
            self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 0)

        url = "/timeseries/d/{}/download/1998-02-02//".format(
            self.ts.pk)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(nrecords(), 0)

        self.client.logout()