Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tutorial for street project type #983

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mapswipe_workers/mapswipe_workers/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,14 @@ def tutorial(self):
ClassificationTutorial,
CompletenessTutorial,
FootprintTutorial,
StreetTutorial,
)

project_type_classes = {
1: ClassificationTutorial,
2: FootprintTutorial,
3: ChangeDetectionTutorial,
4: CompletenessTutorial,
7: StreetTutorial,
}
return project_type_classes[self.value]
2 changes: 2 additions & 0 deletions mapswipe_workers/mapswipe_workers/project_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .arbitrary_geometry.footprint.tutorial import FootprintTutorial
from .media_classification.project import MediaClassificationProject
from .street.project import StreetProject
from .street.tutorial import StreetTutorial
from .tile_map_service.change_detection.project import ChangeDetectionProject
from .tile_map_service.change_detection.tutorial import ChangeDetectionTutorial
from .tile_map_service.classification.project import ClassificationProject
Expand All @@ -22,4 +23,5 @@
"FootprintTutorial",
"DigitizationProject",
"StreetProject",
"StreetTutorial",
]
80 changes: 75 additions & 5 deletions mapswipe_workers/mapswipe_workers/project_types/street/tutorial.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,84 @@
from dataclasses import asdict, dataclass

from mapswipe_workers.definitions import logger
from mapswipe_workers.firebase.firebase import Firebase
from mapswipe_workers.project_types.street.project import StreetGroup, StreetTask
from mapswipe_workers.project_types.tutorial import BaseTutorial


@dataclass
class StreetTutorialTask(StreetTask):
projectId: int
taskId: str
groupId: int
referenceAnswer: int
screen: int


class StreetTutorial(BaseTutorial):
"""The subclass for an TMS Grid based Tutorial."""
"""The subclass for an arbitrary geometry based Tutorial."""

def save_tutorial(self):
raise NotImplementedError("Currently Street has no Tutorial")
def __init__(self, tutorial_draft):
# this will create the basis attributes
super().__init__(tutorial_draft)

# self.projectId = tutorial_draft["projectId"]
self.projectType = tutorial_draft["projectType"]
self.tutorial_tasks = tutorial_draft["tasks"]
self.groups = dict()
self.tasks = dict()

def create_tutorial_groups(self):
raise NotImplementedError("Currently Street has no Tutorial")
"""Create group for the tutorial based on provided examples in geojson file."""
# load examples/tasks from file

group = StreetGroup(
groupId=101,
projectId=self.projectId,
numberOfTasks=len(self.tutorial_tasks),
progress=0,
finishedCount=0,
requiredCount=0,
)
self.groups[101] = group

# Add number of tasks for the group here. This needs to be set according to
# the number of features/examples in the geojson file

logger.info(
f"{self.projectId}"
f" - create_tutorial_groups - "
f"created groups dictionary"
)

def create_tutorial_tasks(self):
raise NotImplementedError("Currently Street has no Tutorial")
"""Create the tasks dict based on provided examples in geojson file."""
task_list = []
for i, task in enumerate(self.tutorial_tasks):
task = StreetTutorialTask(
projectId=self.projectId,
groupId=101,
taskId=f"{task['taskImageId']}",
geometry="",
referenceAnswer=task["referenceAnswer"],
screen=i,
)
task_list.append(asdict(task))
if task_list:
self.tasks[101] = task_list
else:
logger.info(f"group in project {self.projectId} is not valid.")

logger.info(
f"{self.projectId}"
f" - create_tutorial_tasks - "
f"created tasks dictionary"
)

def save_tutorial(self):
firebase = Firebase()
firebase.save_tutorial_to_firebase(
self, self.groups, self.tasks, useCompression=True
)
logger.info(self.tutorialDraftId)
firebase.drop_tutorial_draft(self.tutorialDraftId)
1 change: 0 additions & 1 deletion mapswipe_workers/tests/fixtures/projectDrafts/street.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,5 @@
"requestingOrganisation": "test",
"verificationNumber": 3,
"groupSize": 25,
"startTimestamp": "2019-07-01T00:00:00.000Z",
"samplingThreshold": 0.1
}
170 changes: 170 additions & 0 deletions mapswipe_workers/tests/fixtures/tutorialDrafts/street.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{
"createdBy": "LtCUyou6CnSSc1H0Q0nDrN97x892",
"tutorialDraftId": "waste_mapping_dar_es_salaam",
"taskImageIds": [
888464808378923,
1552821322020271,
2969692853315413,
1036040467918366,
837497816845037
],
"answers": [
1,
2,
1,
2,
3
],
"customOptions": [
{
"description": "the shape does outline a building in the image",
"icon": "hand-right-outline",
"iconColor": "#00796B",
"subOptions": [
{
"description": "doppelt",
"value": 2
},
{
"description": "dreifach",
"value": 3
}
],
"title": "Jetzt rede ich",
"value": 1
},
{
"description": "the shape doesn't match a building in the image",
"icon": "close-outline",
"iconColor": "#D32F2F",
"title": "No",
"value": 0
}
],
"informationPages": [
{
"blocks": [
{
"blockNumber": 1,
"blockType": "text",
"textDescription": "asdf"
},
{
"blockNumber": 2,
"blockType": "image",
"image": "https://firebasestorage.googleapis.com/v0/b/dev-mapswipe.appspot.com/o/tutorialImages%2F1705402528654-block-image-2-base-query-form.png?alt=media&token=54325ab8-c5e7-45a3-be41-1926a5984a05"
}
],
"pageNumber": 1,
"title": "asdf"
}
],
"lookFor": "waste",
"name": "Waste Mapping Dar es Salaam",
"projectType": 7,
"screens": [
null,
{
"hint": {
"description": "Swipe to learn some more.",
"icon": "swipe-left",
"title": "We've marked the correct square green."
},
"instructions": {
"description": "Tap once to mark the squares with buildings green.",
"icon": "tap-1",
"title": "There are some buildings in this image"
},
"success": {
"description": "Swipe to the next screen to look for more.",
"icon": "check",
"title": "You found your first areas with buildings!"
}
},
{
"hint": {
"description": "Swipe to learn some more.",
"icon": "swipe-left",
"title": "We've marked the correct square green."
},
"instructions": {
"description": "Tap once to mark the squares with buildings green.",
"icon": "tap-1",
"title": "There are some buildings in this image"
},
"success": {
"description": "Swipe to the next screen to look for more.",
"icon": "check",
"title": "You found your first"
}
},
{
"hint": {
"description": "Swipe to learn some more.",
"icon": "swipe-left",
"title": "We've marked the correct square green."
},
"instructions": {
"description": "Tap once to mark the squares with buildings green.",
"icon": "tap-1",
"title": "There are some buildings in this image"
},
"success": {
"description": "Swipe to the next screen to look for more.",
"icon": "check",
"title": "You found your first areas with buildings!"
}
},
{
"hint": {
"description": "Swipe to learn some more.",
"icon": "swipe-left",
"title": "We've marked the correct square green."
},
"instructions": {
"description": "Tap once to mark the squares with buildings green.",
"icon": "tap-1",
"title": "There are some buildings in this image"
},
"success": {
"description": "Swipe to the next screen to look for more.",
"icon": "check",
"title": "You found your first areas with buildings!"
}
},
{
"hint": {
"description": "Swipe to learn some more.",
"icon": "swipe-left",
"title": "We've marked the correct square green."
},
"instructions": {
"description": "Tap once to mark the squares with buildings green.",
"icon": "tap-1",
"title": "There are some buildings in this image"
},
"success": {
"description": "Swipe to the next screen to look for more.",
"icon": "check",
"title": "You found your first areas with buildings!"
}
},
{
"hint": {
"description": "Swipe to learn some more.",
"icon": "swipe-left",
"title": "We've marked the correct square green."
},
"instructions": {
"description": "Tap once to mark the squares with buildings green.",
"icon": "tap-1",
"title": "There are some buildings in this image"
},
"success": {
"description": "Swipe to the next screen to look for more.",
"icon": "check",
"title": "You found your first areas with buildings!"
}
}
]
}
55 changes: 41 additions & 14 deletions mapswipe_workers/tests/integration/set_up.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,28 @@


def set_firebase_test_data(
project_type: str, data_type: str, fixture_name: str, identifier: str
project_type: str,
data_type: str,
fixture_name: str,
identifier: str,
tutorial_id: str = None,
):
test_dir = os.path.dirname(__file__)
fixture_name = fixture_name + ".json"
file_path = os.path.join(
test_dir, "fixtures", project_type, data_type, fixture_name
)
upload_file_to_firebase(file_path, data_type, identifier)
upload_file_to_firebase(file_path, data_type, identifier, tutorial_id=tutorial_id)


def upload_file_to_firebase(file_path: str, data_type: str, identifier: str):
def upload_file_to_firebase(
file_path: str, data_type: str, identifier: str, tutorial_id: str = None
):
with open(file_path) as test_file:
test_data = json.load(test_file)

if tutorial_id:
test_data["tutorialId"] = tutorial_id
fb_db = auth.firebaseDB()
ref = fb_db.reference(f"/v2/{data_type}/{identifier}")
ref.set(test_data)
Expand Down Expand Up @@ -85,15 +93,20 @@ def create_test_project(
set_postgres_test_data(project_type, "users", "user")
set_firebase_test_data(project_type, "user_groups", "user_group", "")
set_firebase_test_data(project_type, "results", fixture_name, project_id)
set_postgres_test_data(project_type, "mapping_sessions", fixture_name, columns=[
"project_id",
"group_id",
"user_id",
"mapping_session_id",
"start_time",
"end_time",
"items_count",
])
set_postgres_test_data(
project_type,
"mapping_sessions",
fixture_name,
columns=[
"project_id",
"group_id",
"user_id",
"mapping_session_id",
"start_time",
"end_time",
"items_count",
],
)
set_postgres_test_data(project_type, mapping_sessions_results, fixture_name)
if create_user_group_session_data:
set_postgres_test_data(
Expand All @@ -108,7 +121,9 @@ def create_test_project(
"created_at",
],
)
set_postgres_test_data(project_type, "mapping_sessions_user_groups", fixture_name)
set_postgres_test_data(
project_type, "mapping_sessions_user_groups", fixture_name
)

time.sleep(5) # Wait for Firebase Functions to complete
return project_id
Expand All @@ -131,12 +146,24 @@ def create_test_user(project_type: str, user_id: str = None) -> str:


def create_test_project_draft(
project_type: str, fixture_name: str = "user", identifier: str = ""
project_type: str,
fixture_name: str = "user",
identifier: str = "",
tutorial_id: str = None,
) -> str:
"""
Create test project drafts in Firebase and return project ids.
Project drafts in Firebase are created by project manager using the dashboard.
"""
if tutorial_id:
set_firebase_test_data(
project_type,
"projectDrafts",
fixture_name,
identifier,
tutorial_id=tutorial_id,
)
return identifier
if not identifier:
identifier = f"test_{fixture_name}"
set_firebase_test_data(project_type, "projectDrafts", fixture_name, identifier)
Expand Down
Loading