diff --git a/.env.example b/.env.example
index 45f410b..5ae28bc 100644
--- a/.env.example
+++ b/.env.example
@@ -5,6 +5,7 @@ USERNAME=
PASSWORD=
SESSION_COOKIE_NAME=
+MAX_RECORD_DAYS=
# NEW DATABASE URI
-SQLALCHEMY_DATABASE_URI='mysql+mysqlconnector://user:pass@host/database'
\ No newline at end of file
+SQLALCHEMY_DATABASE_URI='mysql+mysqlconnector://user:pass@host/database'
diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
new file mode 100644
index 0000000..48ce960
--- /dev/null
+++ b/.github/workflows/python-app.yml
@@ -0,0 +1,24 @@
+# This workflow will install Python dependencies, run tests and lint with a single version of Python
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Python application
+
+on: [ push, pull_request ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.8
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Run tests
+ run: |
+ python -m unittest discover
diff --git a/README.md b/README.md
index b66c025..8b76563 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,20 @@ Server is based on **Flask** and few extensions:
Database: **MySQL**
+## Executing
+
+First of all, activate virtual environment with:
+
+`source venv/bin/activate`
+
+To start the server run:
+
+`python run.py`
+
+To start tests run:
+
+`python -m unittest tests`
+
## Credits
All credits to @andrew4ever
diff --git a/common/AQICalculator.py b/common/AQICalculator.py
index 7731d47..f23a6cf 100644
--- a/common/AQICalculator.py
+++ b/common/AQICalculator.py
@@ -2,6 +2,9 @@
# In future old backend will be replaced by this new project and aqi calculator will be refactored
import math
+from os import environ
+from datetime import datetime
+
import mysql.connector
@@ -34,13 +37,19 @@ def calculate_aqi(self):
continue
self.cursor.execute(
- "SELECT * FROM `sensor_record` WHERE `sensor_id` = {}".format(
+ "SELECT * FROM `sensor_record` WHERE `sensor_id` = {} ORDER BY `created_at` DESC".format(
sensor[0])
)
record = self.cursor.fetchone()
- if record:
+ if not record:
+ continue
+
+ timedelta = datetime.now() - record[2]
+
+ if timedelta.days < int(environ.get('MAX_RECORD_DAYS')):
records.append(record)
+ print(sensor[0], record)
# arrange records to squares
squares = {}
@@ -52,6 +61,12 @@ def calculate_aqi(self):
squares[square_center].append(record)
+ self.cursor.execute("SELECT * FROM `sensor_value_type`")
+ types = self.cursor.fetchall()
+ used_ids = [value_type[0]
+ for value_type in types if value_type[-2] == 1]
+ types = {value_type[0]: value_type for value_type in types}
+
# get aqi for each square
for center, records in squares.items():
# prepare dataset
@@ -61,12 +76,6 @@ def calculate_aqi(self):
"SELECT * FROM `sensor_value` WHERE `record_id` = {}".format(record[0]))
values = self.cursor.fetchall()
- self.cursor.execute("SELECT * FROM `sensor_value_type`")
- types = self.cursor.fetchall()
- used_ids = [value_type[0]
- for value_type in types if value_type[-2] == 1]
- types = {value_type[0]: value_type for value_type in types}
-
for value in values:
if value[2] not in used_ids:
continue
diff --git a/models/area.py b/models/area.py
index 3abfd6b..1871a65 100644
--- a/models/area.py
+++ b/models/area.py
@@ -36,9 +36,9 @@ class AreaModel(db.Model):
)
def __repr__(self):
- return ''.format(self._string_coords())
+ return ''.format(self.string_coords())
- def _string_coords(self):
+ def string_coords(self):
return str(self.latitude) + '-' + str(self.longitude)
def as_dict(self):
diff --git a/resources/area.py b/resources/area.py
index 727fcb5..3b3a5a1 100644
--- a/resources/area.py
+++ b/resources/area.py
@@ -12,7 +12,7 @@ def get(self):
areas = AreaModel.query \
.filter_by(latitude=latitude) \
.filter_by(longitude=longitude) \
- .limit(10).order_by(desc(AreaModel.created)).all()
+ .order_by(desc(AreaModel.created)).all()
if not areas:
return {'code': 404, 'message': 'Area not found'}, 404
diff --git a/resources/map.py b/resources/map.py
index 8e1206a..7592d99 100644
--- a/resources/map.py
+++ b/resources/map.py
@@ -1,3 +1,6 @@
+from datetime import datetime
+from os import environ
+
from flask_restful import Resource
from sqlalchemy import desc
@@ -17,6 +20,12 @@ def get(self):
if (a['latitude'], a['longitude']) in areas_coords:
continue
+ timedelta = datetime.now() - \
+ datetime.strptime(a['created'], '%Y-%m-%d %H:%M:%S')
+
+ if timedelta.days >= int(environ.get('MAX_RECORD_DAYS')):
+ continue
+
areas_coords.append((a['latitude'], a['longitude']))
areas_list.append(area.as_dict())
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..1b3bd4c
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,3 @@
+from tests.models.area import AreaModelTest
+from tests.resources.area import AreaResourceTest
+from tests.resources.map import MapResourceTest
diff --git a/tests/models/area.py b/tests/models/area.py
new file mode 100644
index 0000000..184c2b3
--- /dev/null
+++ b/tests/models/area.py
@@ -0,0 +1,43 @@
+import unittest
+
+from models import AreaModel
+
+
+class AreaModelTest(unittest.TestCase):
+ def test_as_dict(self):
+ data = {
+ 'aqi': 42,
+ 'latitude': '50.442',
+ 'longitude': '30.91'
+ }
+
+ result = AreaModel(**data).as_dict()
+ del result['created']
+ del result['id']
+
+ self.assertEqual(result, data)
+
+ def test_string_coords(self):
+ data = {
+ 'aqi': 42,
+ 'latitude': '50.442',
+ 'longitude': '30.91'
+ }
+
+ result = AreaModel(**data).string_coords()
+
+ self.assertEqual(result, self.string_coords(data))
+
+ def test_repr(self):
+ data = {
+ 'aqi': 42,
+ 'latitude': '50.442',
+ 'longitude': '30.91'
+ }
+
+ result = str(AreaModel(**data))
+
+ self.assertEqual(result, ''.format(self.string_coords(data)))
+
+ def string_coords(self, data):
+ return data['latitude'] + '-' + data['longitude']
diff --git a/tests/resources/area.py b/tests/resources/area.py
new file mode 100644
index 0000000..5f1ec31
--- /dev/null
+++ b/tests/resources/area.py
@@ -0,0 +1,7 @@
+import unittest
+
+from resources import AreaResource
+
+
+class AreaResourceTest(unittest.TestCase):
+ pass
diff --git a/tests/resources/map.py b/tests/resources/map.py
new file mode 100644
index 0000000..2dd1fb6
--- /dev/null
+++ b/tests/resources/map.py
@@ -0,0 +1,7 @@
+import unittest
+
+from resources import Map
+
+
+class MapResourceTest(unittest.TestCase):
+ pass