11import ast
2+ import csv
23import datetime
34import gzip
45import json
@@ -98,6 +99,7 @@ def get_results(
9899 Parse timestamp as datetime object and add attribute "day" for each result.
99100 Return None if there are no results for this project.
100101 Otherwise, return dataframe.
102+ Include the 'ref' JSON field in integer results if it exists.
101103
102104 Parameters
103105 ----------
@@ -108,7 +110,7 @@ def get_results(
108110 if result_table == "mapping_sessions_results_geometry" :
109111 result_sql = "ST_AsGeoJSON(msr.result) as result"
110112 else :
111- result_sql = "msr.result"
113+ result_sql = "msr.result as result "
112114
113115 sql_query = sql .SQL (
114116 f"""
@@ -124,6 +126,7 @@ def get_results(
124126 ms.app_version,
125127 ms.client_type,
126128 { result_sql } ,
129+ refs.ref as ref,
127130 -- the username for users which login to MapSwipe with their
128131 -- OSM account is not defined or ''.
129132 -- We capture this here as it will cause problems
@@ -136,7 +139,10 @@ def get_results(
136139 LEFT JOIN mapping_sessions ms ON
137140 ms.mapping_session_id = msr.mapping_session_id
138141 LEFT JOIN users U USING (user_id)
139- WHERE project_id = { "{}" }
142+ LEFT JOIN mapping_sessions_refs refs
143+ ON msr.mapping_session_id = refs.mapping_session_id
144+ AND msr.task_id = refs.task_id
145+ WHERE ms.project_id = { "{}" }
140146 ) TO STDOUT WITH CSV HEADER
141147 """
142148 ).format (sql .Literal (project_id ))
@@ -427,6 +433,8 @@ def get_agg_results_by_task_id(
427433 :, ~ agg_results_df .columns .str .contains ("Unnamed" )
428434 ]
429435
436+ agg_results_df = add_ref_to_agg_results (results_df , agg_results_df )
437+
430438 return agg_results_df
431439
432440
@@ -504,6 +512,30 @@ def get_statistics_for_geometry_result_project(project_id: str):
504512 return project_stats_dict
505513
506514
515+ def add_ref_to_agg_results (
516+ results_df : pd .DataFrame , agg_results_df : pd .DataFrame
517+ ) -> pd .DataFrame :
518+ """
519+ Adds a 'ref' column to agg_results_df if it exists in results_df.
520+ For each task_id, all unique non-empty refs are collected into a list.
521+ If no refs exist for a task, the corresponding value is empty string.
522+ If results_df has no 'ref' column, agg_results_df is returned unchanged.
523+ """
524+ if "ref" not in results_df .columns :
525+ return agg_results_df
526+
527+ refs_per_task = (
528+ results_df .groupby ("task_id" )["ref" ]
529+ .apply (lambda x : list ({r for r in x if pd .notna (r ) and r not in ({}, "" )}))
530+ .apply (lambda lst : json .dumps ([json .loads (r ) for r in lst ]) if lst else "" )
531+ )
532+
533+ if refs_per_task .apply (lambda x : len (x ) > 0 ).any ():
534+ agg_results_df ["ref" ] = agg_results_df ["task_id" ].map (refs_per_task ).fillna ("" )
535+
536+ return agg_results_df
537+
538+
507539def get_statistics_for_integer_result_project (
508540 project_id : str , project_info : pd .Series , generate_hot_tm_geometries : bool
509541) -> dict :
@@ -550,7 +582,13 @@ def get_statistics_for_integer_result_project(
550582 tasks_df ,
551583 project_info ["custom_options" ],
552584 )
553- agg_results_df .to_csv (agg_results_filename , index_label = "idx" )
585+
586+ agg_results_df .to_csv (
587+ agg_results_filename ,
588+ index_label = "idx" ,
589+ quotechar = '"' ,
590+ quoting = csv .QUOTE_MINIMAL ,
591+ )
554592
555593 geojson_functions .gzipped_csv_to_gzipped_geojson (
556594 filename = agg_results_filename ,
0 commit comments