# Path: api/models.py
# class Station(AbstractTimeTrackable, AbstractLocation):
#     """
#     Model representing sensor station. Can be grouped using Project model.
#     """
# 
#     TYPE_SMOGLY = 'smogly'
#     TYPE_CUSTOM = 'custom'
#     TYPE_AQICN = 'aqicn'
#     TYPE_BASIC_SDS011 = 'basic-sds011'
#     TYPE_CHOICES = (
#         (TYPE_SMOGLY, 'SMOGLY'),
#         (TYPE_CUSTOM, 'CUSTOM'),
#         (TYPE_AQICN, 'AQICN'),
#         (TYPE_BASIC_SDS011, 'BASIC-SDS011'),
#     )
# 
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     name = models.CharField(max_length=255)
#     type = models.CharField(max_length=30, choices=TYPE_CHOICES, default=TYPE_SMOGLY)
#     notes = models.CharField(max_length=255)
#     is_in_test_mode = models.BooleanField(
#         help_text='Whether sensor is in test mode or not (all data).',
#         default=False
#     )
#     token = models.CharField(
#         max_length=255,
#         help_text='Token automatically generated while saving model, needed by Station to POST any data.',
#         default=generate_token,
#         unique=True
#     )
#     altitude = models.FloatField(help_text='Altitude of sensor location.', default=0)
# 
#     # Relationship Fields
#     owner = models.ForeignKey(settings.AUTH_USER_MODEL)
#     project = models.ForeignKey('api.Project')
# 
#     @property
#     def last_metering(self):
#         """
#         Return lastly created, serialized Metering object.
#         We remove cache key while adding metering to given station.
#         """
#         if not cache.get(self.last_metering_cache_key):
#             from api.serializers import MeteringSerializer
#             last_metering = self.metering_set.first()
#             cache.set(self.last_metering_cache_key, MeteringSerializer(last_metering).data)
#         return cache.get(self.last_metering_cache_key)
# 
#     @property
#     def last_metering_cache_key(self):
#         return u'station-{}-last-metering'.format(self.pk)
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def __unicode__(self):
#         return u'%s' % self.id
# 
#     def get_absolute_url(self):
#         return reverse('api_station_detail', args=(self.id,))
# 
#     def get_update_url(self):
#         return reverse('api_station_update', args=(self.id,))
# 
# class Metering(AbstractMetering):
#     """
#     Model representing data submitted by sensor station.
#     """
# 
#     is_test = models.BooleanField(
#         help_text='Whether entry was created using Sensor test mode (Sensor.is_in_test_mode=True).',
#         default=False,
#         db_index=True
#     )
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def get_absolute_url(self):
#         return reverse('api_metering_detail', args=(self.pk,))
# 
# class MeteringHistory(AbstractMetering):
#     """
#     Model representing history entries calculated from Metering entries, resolution 1 hour.
# 
#     Idea:
#     * background job runs once per hour
#     * job calculates avarage of readings from Metering entries older than 2 weeks (avarage
#     should be calulated per hour basis, one MeteringHistory entry per hour)
#     * entries that was used to calculate avarage should be cleaned from Metering database
#     """
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def get_absolute_url(self):
#         return reverse('api_meteringhistory_detail', args=(self.pk,))
# 
# class Project(AbstractTimeTrackable, AbstractLocation):
#     """
#     Model used for grouping sensor stations. Eg. by local anti-smog groups.
#     """
# 
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     name = models.CharField(max_length=255)
#     slug = AutoSlugField(populate_from='name', blank=True, unique=True)
# 
#     website = models.URLField()
#     description = models.TextField()
#     logo = models.ImageField(max_length=100, upload_to='project/', blank=True, null=True, default=None)
# 
#     owner = models.ForeignKey(settings.AUTH_USER_MODEL)
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def __unicode__(self):
#         return u'%s' % self.slug
# 
#     def get_absolute_url(self):
#         return reverse('api_project_detail', args=(self.slug,))
# 
#     def get_update_url(self):
#         return reverse('api_project_update', args=(self.slug,))


import os
import random
import factory
import factory.fuzzy
from django.contrib.auth import get_user_model
from django.contrib.gis.geos import Point
from django.contrib.auth.hashers import make_password
from django.core.files import File
from faker import Faker
from api.models import Station, Metering, MeteringHistory, Project
                    File(
                        open(
                            source_path,
                            # for python 3.x, we need binary mode
                            # https://github.com/python-pillow/Pillow/issues/1605#issuecomment-167402651
                            'rb'
                        )
                    )
                )
                self.save(update_fields=['logo'])

    class Meta:
        model = Project


class StationFactory(AbstractLocationFactory):
    name = factory.Sequence(lambda n: 'Smogly Station %04d' % n)
    type = factory.fuzzy.FuzzyChoice([type_choice[0] for type_choice in Station.TYPE_CHOICES])
    notes = factory.Faker('sentences', nb=3)
    altitude = FuzzyFloatRound(0.0, 300.0, ndigits=2)
    project = factory.SubFactory(ProjectFactory, **{
        'country': factory.SelfAttribute('..country'),
        'state': factory.SelfAttribute('..state'),
        'county': factory.SelfAttribute('..county'),
        'community': factory.SelfAttribute('..community'),
        'district': factory.SelfAttribute('..district')
    })
    owner = factory.SubFactory(UserFactory)

    class Meta:

# Path: api/models.py
# class Station(AbstractTimeTrackable, AbstractLocation):
#     """
#     Model representing sensor station. Can be grouped using Project model.
#     """
# 
#     TYPE_SMOGLY = 'smogly'
#     TYPE_CUSTOM = 'custom'
#     TYPE_AQICN = 'aqicn'
#     TYPE_BASIC_SDS011 = 'basic-sds011'
#     TYPE_CHOICES = (
#         (TYPE_SMOGLY, 'SMOGLY'),
#         (TYPE_CUSTOM, 'CUSTOM'),
#         (TYPE_AQICN, 'AQICN'),
#         (TYPE_BASIC_SDS011, 'BASIC-SDS011'),
#     )
# 
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     name = models.CharField(max_length=255)
#     type = models.CharField(max_length=30, choices=TYPE_CHOICES, default=TYPE_SMOGLY)
#     notes = models.CharField(max_length=255)
#     is_in_test_mode = models.BooleanField(
#         help_text='Whether sensor is in test mode or not (all data).',
#         default=False
#     )
#     token = models.CharField(
#         max_length=255,
#         help_text='Token automatically generated while saving model, needed by Station to POST any data.',
#         default=generate_token,
#         unique=True
#     )
#     altitude = models.FloatField(help_text='Altitude of sensor location.', default=0)
# 
#     # Relationship Fields
#     owner = models.ForeignKey(settings.AUTH_USER_MODEL)
#     project = models.ForeignKey('api.Project')
# 
#     @property
#     def last_metering(self):
#         """
#         Return lastly created, serialized Metering object.
#         We remove cache key while adding metering to given station.
#         """
#         if not cache.get(self.last_metering_cache_key):
#             from api.serializers import MeteringSerializer
#             last_metering = self.metering_set.first()
#             cache.set(self.last_metering_cache_key, MeteringSerializer(last_metering).data)
#         return cache.get(self.last_metering_cache_key)
# 
#     @property
#     def last_metering_cache_key(self):
#         return u'station-{}-last-metering'.format(self.pk)
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def __unicode__(self):
#         return u'%s' % self.id
# 
#     def get_absolute_url(self):
#         return reverse('api_station_detail', args=(self.id,))
# 
#     def get_update_url(self):
#         return reverse('api_station_update', args=(self.id,))
# 
# class Metering(AbstractMetering):
#     """
#     Model representing data submitted by sensor station.
#     """
# 
#     is_test = models.BooleanField(
#         help_text='Whether entry was created using Sensor test mode (Sensor.is_in_test_mode=True).',
#         default=False,
#         db_index=True
#     )
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def get_absolute_url(self):
#         return reverse('api_metering_detail', args=(self.pk,))
# 
# class MeteringHistory(AbstractMetering):
#     """
#     Model representing history entries calculated from Metering entries, resolution 1 hour.
# 
#     Idea:
#     * background job runs once per hour
#     * job calculates avarage of readings from Metering entries older than 2 weeks (avarage
#     should be calulated per hour basis, one MeteringHistory entry per hour)
#     * entries that was used to calculate avarage should be cleaned from Metering database
#     """
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def get_absolute_url(self):
#         return reverse('api_meteringhistory_detail', args=(self.pk,))
# 
# class Project(AbstractTimeTrackable, AbstractLocation):
#     """
#     Model used for grouping sensor stations. Eg. by local anti-smog groups.
#     """
# 
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     name = models.CharField(max_length=255)
#     slug = AutoSlugField(populate_from='name', blank=True, unique=True)
# 
#     website = models.URLField()
#     description = models.TextField()
#     logo = models.ImageField(max_length=100, upload_to='project/', blank=True, null=True, default=None)
# 
#     owner = models.ForeignKey(settings.AUTH_USER_MODEL)
# 
#     class Meta:
#         ordering = ('-created',)
# 
#     def __unicode__(self):
#         return u'%s' % self.slug
# 
#     def get_absolute_url(self):
#         return reverse('api_project_detail', args=(self.slug,))
# 
#     def get_update_url(self):
#         return reverse('api_project_update', args=(self.slug,))


# Path: api/tests/factories.py
import os
import random
import factory
import factory.fuzzy
from django.contrib.auth import get_user_model
from django.contrib.gis.geos import Point
from django.contrib.auth.hashers import make_password
from django.core.files import File
from faker import Faker
from api.models import Station, Metering, MeteringHistory, Project

                    File(
                        open(
                            source_path,
                            # for python 3.x, we need binary mode
                            # https://github.com/python-pillow/Pillow/issues/1605#issuecomment-167402651
                            'rb'
                        )
                    )
                )
                self.save(update_fields=['logo'])

    class Meta:
        model = Project


class StationFactory(AbstractLocationFactory):
    name = factory.Sequence(lambda n: 'Smogly Station %04d' % n)
    type = factory.fuzzy.FuzzyChoice([type_choice[0] for type_choice in Station.TYPE_CHOICES])
    notes = factory.Faker('sentences', nb=3)
    altitude = FuzzyFloatRound(0.0, 300.0, ndigits=2)
    project = factory.SubFactory(ProjectFactory, **{
        'country': factory.SelfAttribute('..country'),
        'state': factory.SelfAttribute('..state'),
        'county': factory.SelfAttribute('..county'),
        'community': factory.SelfAttribute('..community'),
        'district': factory.SelfAttribute('..district')
    })
    owner = factory.SubFactory(UserFactory)

    class Meta:

        model = Station