Skip to content

Commit b1db2bb

Browse files
authored
Merge pull request #436 from mapswipe/dev
Dev
2 parents 3a0dfc7 + bc806e6 commit b1db2bb

File tree

22 files changed

+288
-97
lines changed

22 files changed

+288
-97
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ script:
3939
- docker-compose run mapswipe_workers python -m unittest discover --verbose --start-directory tests/integration/
4040

4141
after_success:
42-
# Deploy to development server using Ansible
4342
# SSH setup to deploy to server after build.
4443
- apk add openssh-client
45-
- eval "$(ssh-agent -s)" #start the ssh agent
44+
- eval "$(ssh-agent -s)" # start the ssh agent
4645
- mkdir -p $HOME/.ssh
47-
# - chmod 700 $HOME/.ssh
46+
# Use config to define SSH connection variables (User, IdentityFile)
4847
- cp travis/ssh_config $HOME/.ssh/config
4948
- openssl aes-256-cbc -K $encrypted_c17fa81e6490_key -iv $encrypted_c17fa81e6490_iv -in travis/ssh-private-key.enc -out $HOME/.ssh/private-key -d
5049
- chmod 600 $HOME/.ssh/private-key
5150
- ssh-add $HOME/.ssh/private-key
5251
- chmod +x deploy.sh
5352

5453
deploy:
54+
# Deploy to server using Ansible
5555
provider: script
5656
script: bash deploy.sh
5757
on:

deploy.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
#!/bin/bash
2-
# Deploy to dev server.
2+
# Deploy to server.
33
# This script is called by Travis.
4+
5+
function bell() {
6+
# Print regular to stdout, so that Travis will not abort due to time.
7+
# travis_wait does not work with script deployment.
8+
while true; do
9+
echo -e "\a"
10+
sleep 60
11+
done
12+
}
13+
bell &
14+
415
ansible-playbook -i ansible/inventory.yml ansible/playbook.yml
16+
17+
exit $? # Return exit code of last command

docs/source/contributing.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ From now on `black`, `flake8` and `isort` should run automatically whenever `git
3434

3535
When running those tools manually please make sure the right version is used. The version can be looked up in `.pre-commit-config.yaml`.
3636
To update to newer version please make sure to change version numbers in `.pre-commit-config.yaml`, `.travis.yml` and `requirements.txt`.
37+
38+
39+
### Tips
40+
41+
Ignore a hook: `SKIP=flake8 git commit -m "foo"`
42+
Mark in code that flake8 should ignore the line: `print() # noqa`
43+

docs/source/deployment_overview.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,12 @@ MapSwipe utilizes a bunch of Google Cloud services:
1616
[Configuration](configuration.md) describes all needed configuration and credentials.
1717

1818
[Installation](installation.md) describes step-by-step how to setup the backend for the first time.
19+
20+
21+
## Continuous deployment using Ansible and Travis
22+
23+
Travis is setup to automatically deploy a new version of MapSwipe Back-End to the server once it run successfully.
24+
This is done by using Travis script deployment (https://docs.travis-ci.com/user/deployment/script/). Travis simply calls the `deploy.sh` script found at the root directory of MapSwipe Workers.
25+
To be able to connect to the MapSwipe server the Travis instance uses an encrypted SSH private key (Which can be found in the directory `travis/`).
26+
27+
In the `deploy.sh` script an Ansible Playbook is run (https://docs.ansible.com/ansible/latest/index.html). Ansible is an automation tool which utilizes a SSH connection (`ansible/ansible.cfg`) to run commands defined in the Playbook (`ansible/playbook.yml`) on hosts defined in the Inventory (`ansible/inventory.yml`).

manager_dashboard/manager_dashboard/js/uploadProjects.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function getFormInput() {
4646
break;
4747
case "footprint":
4848
form_data.projectType = 2;
49-
form_data.input_geometries = document.getElementById("inputTaskGeometries").value;
49+
form_data.inputGeometries = document.getElementById("inputTaskGeometries").value;
5050
form_data.tileServer = {
5151
name: document.getElementById("tileServerAName").value,
5252
url: document.getElementById("tileServerAUrl").value,

mapswipe_workers/mapswipe_workers/generate_stats/project_stats.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from psycopg2 import sql
77

88
from mapswipe_workers import auth
9-
from mapswipe_workers.definitions import DATA_PATH, logger, sentry
9+
from mapswipe_workers.definitions import DATA_PATH, ProjectType, logger, sentry
1010
from mapswipe_workers.generate_stats import (
1111
project_stats_by_date,
1212
tasking_manager_geometries,
@@ -141,6 +141,8 @@ def get_groups(filename: str, project_id: str) -> pd.DataFrame:
141141
logger.info(f"file {filename} already exists for {project_id}. skip download.")
142142
pass
143143
else:
144+
# TODO: check how we use number_of_users_required
145+
# it can get you a wrong number, if more users finished than required
144146
sql_query = sql.SQL(
145147
"""
146148
COPY (
@@ -374,7 +376,11 @@ def get_per_project_statistics(project_id: str, project_info: pd.Series) -> dict
374376
)
375377

376378
# generate geometries for HOT Tasking Manager
377-
tasking_manager_geometries.generate_tasking_manager_geometries(project_id)
379+
if project_info.iloc[0]["project_type"] in [ProjectType.FOOTPRINT.value]:
380+
# do not do this for ArbitraryGeometry / BuildingFootprint projects
381+
logger.info(f"do NOT generate tasking manager geometries for {project_id}")
382+
else:
383+
tasking_manager_geometries.generate_tasking_manager_geometries(project_id)
378384

379385
# prepare output of function
380386
project_stats_dict = {

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/group.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ class Group(BaseGroup):
88
def __init__(self, project: object, groupId: int) -> None:
99
super().__init__(project, groupId)
1010

11-
def create_tasks(self, feature_ids: List, feature_geometries: List) -> None:
11+
def create_tasks(
12+
self, feature_ids: List, feature_geometries: List, center_points: List
13+
) -> None:
1214
"""Create tasks for a group
1315
1416
feature_geometries is a list of geometries or feature in geojson format.
@@ -17,6 +19,6 @@ def create_tasks(self, feature_ids: List, feature_geometries: List) -> None:
1719
Every coordinate pair is a vertex.
1820
"""
1921
for i in range(0, len(feature_ids)):
20-
task = Task(self, feature_ids[i], feature_geometries[i])
22+
task = Task(self, feature_ids[i], feature_geometries[i], center_points[i])
2123
self.tasks.append(task)
2224
self.numberOfTasks = len(self.tasks)

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/grouping_functions.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,22 @@ def group_input_geometries(input_geometries_file, group_size):
6262
try:
6363
groups[group_id_string]
6464
except KeyError:
65-
groups[group_id_string] = {"feature_ids": [], "feature_geometries": []}
65+
groups[group_id_string] = {
66+
"feature_ids": [],
67+
"feature_geometries": [],
68+
"center_points": [],
69+
}
6670

6771
groups[group_id_string]["feature_ids"].append(feature.GetFID())
6872
groups[group_id_string]["feature_geometries"].append(
6973
json.loads(feature.GetGeometryRef().ExportToJson())
7074
)
75+
try:
76+
center_x = feature.GetFieldAsDouble("center_x")
77+
center_y = feature.GetFieldAsDouble("center_y")
78+
groups[group_id_string]["center_points"].append([center_x, center_y])
79+
except: # noqa
80+
groups[group_id_string]["center_points"].append([])
7181

7282
return groups
7383

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/project.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from mapswipe_workers.project_types.arbitrary_geometry import grouping_functions as g
88
from mapswipe_workers.project_types.arbitrary_geometry.group import Group
99
from mapswipe_workers.project_types.base.project import BaseProject
10+
from mapswipe_workers.project_types.base.tile_server import BaseTileServer
1011

1112

1213
class Project(BaseProject):
@@ -16,7 +17,7 @@ def __init__(self, project_draft: dict) -> None:
1617
# set group size
1718
self.groupSize = project_draft["groupSize"]
1819
self.inputGeometries = project_draft["inputGeometries"]
19-
self.tileServer = self.get_tile_server(project_draft["tileServer"])
20+
self.tileServer = vars(BaseTileServer(project_draft["tileServer"]))
2021

2122
def validate_geometries(self):
2223
raw_input_file = (
@@ -143,8 +144,13 @@ def create_groups(self):
143144

144145
for group_id, item in raw_groups.items():
145146
group = Group(self, group_id)
146-
group.create_tasks(item["feature_ids"], item["feature_geometries"])
147-
self.groups.append(group)
147+
group.create_tasks(
148+
item["feature_ids"], item["feature_geometries"], item["center_points"]
149+
)
150+
151+
# only append valid groups
152+
if group.is_valid():
153+
self.groups.append(group)
148154

149155
logger.info(
150156
f"{self.projectId} " f"- create_groups - " f"created groups dictionary"

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/task.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
from typing import Dict, List
2+
13
from osgeo import ogr
24

35
from mapswipe_workers.project_types.base.task import BaseTask
46

57

68
class Task(BaseTask):
7-
def __init__(self, group: object, featureId: int, featureGeometry: dict):
9+
def __init__(
10+
self, group: object, featureId: int, featureGeometry: Dict, center: List
11+
):
812
"""
913
Parameters
1014
----------
@@ -17,6 +21,11 @@ def __init__(self, group: object, featureId: int, featureGeometry: dict):
1721
task_id = f"t{featureId}"
1822
super().__init__(group, taskId=task_id)
1923
self.geojson = featureGeometry
24+
self.center = center
25+
26+
# Remove projectId and groupId for tasks of Footprint project type
27+
del self.projectId
28+
del self.groupId
2029

2130
# create wkt geometry from geojson
2231
poly = ogr.CreateGeometryFromJson(str(featureGeometry))

0 commit comments

Comments
 (0)