def get_homepage_stats(abbrev=True) -> HomePageStatsDTO: """ Get overall TM stats to give community a feel for progress that's being made """ dto = HomePageStatsDTO() dto.total_projects = Project.query.count() dto.mappers_online = ( Task.query.filter(Task.locked_by is not None) .distinct(Task.locked_by) .count() ) dto.total_mappers = User.query.count() dto.tasks_mapped = Task.query.filter( Task.task_status.in_((TaskStatus.MAPPED.value, TaskStatus.VALIDATED.value)) ).count() if not abbrev: dto.total_validators = ( Task.query.filter(Task.task_status == TaskStatus.VALIDATED.value) .distinct(Task.validated_by) .count() ) dto.tasks_validated = Task.query.filter( Task.task_status == TaskStatus.VALIDATED.value ).count() total_area_sql = """select coalesce(sum(ST_Area(geometry,true)/1000000),0) as sum from public.projects as area""" total_area_result = db.engine.execute(total_area_sql) dto.total_area = total_area_result.fetchone()["sum"] tasks_mapped_sql = """select coalesce(sum(ST_Area(geometry, true)/1000000), 0) as sum from public.tasks where task_status = :task_status""" tasks_mapped_result = db.engine.execute( text(tasks_mapped_sql), task_status=TaskStatus.MAPPED.value ) dto.total_mapped_area = tasks_mapped_result.fetchone()["sum"] tasks_validated_sql = """select coalesce(sum(ST_Area(geometry, true)/1000000), 0) as sum from public.tasks where task_status = :task_status""" tasks_validated_result = db.engine.execute( text(tasks_validated_sql), task_status=TaskStatus.VALIDATED.value ) dto.total_validated_area = tasks_validated_result.fetchone()["sum"] unique_campaigns_sql = "select count(name) as sum from campaigns" unique_campaigns = db.engine.execute(unique_campaigns_sql).fetchone()["sum"] linked_campaigns_sql = "select campaigns.name, count(campaign_projects.campaign_id) from campaigns INNER JOIN campaign_projects\ ON campaigns.id=campaign_projects.campaign_id group by campaigns.id" linked_campaigns_count = db.engine.execute(linked_campaigns_sql).fetchall() no_campaign_count_sql = "select count(*) as project_count from projects where id not in \ (select distinct project_id from campaign_projects order by project_id)" no_campaign_count = db.engine.execute(no_campaign_count_sql).fetchone()[ "project_count" ] for tup in linked_campaigns_count: campaign_stats = CampaignStatsDTO(tup) dto.campaigns.append(campaign_stats) if no_campaign_count: no_campaign_proj = CampaignStatsDTO(("Unassociated", no_campaign_count)) dto.campaigns.append(no_campaign_proj) dto.total_campaigns = unique_campaigns unique_orgs_sql = "select count(name) as sum from organisations" unique_orgs = db.engine.execute(unique_orgs_sql).fetchone()["sum"] linked_orgs_sql = "select organisations.name, count(projects.organisation_id) from projects INNER JOIN organisations\ ON organisations.id=projects.organisation_id group by organisations.id" linked_orgs_count = db.engine.execute(linked_orgs_sql).fetchall() no_org_project_count = 0 no_org_project_count_sql = "select count(*) as project_count from organisations where id not in \ (select distinct organisation_id from projects order by organisation_id)" no_org_project_count = db.engine.execute( no_org_project_count_sql ).fetchone()["project_count"] for tup in linked_orgs_count: org_stats = OrganizationStatsDTO(tup) dto.organizations.append(org_stats) if no_org_project_count: no_org_proj = OrganizationStatsDTO( ("Unassociated", no_org_project_count) ) dto.organisations.append(no_org_proj) dto.total_organisations = unique_orgs else: # Clear null attributes for abbreviated call clear_attrs = [ "total_validators", "tasks_validated", "total_area", "total_mapped_area", "total_validated_area", "campaigns", "total_campaigns", "organisations", "total_organisations", ] for attr in clear_attrs: delattr(dto, attr) return dto
def get_homepage_stats(abbrev=True) -> HomePageStatsDTO: """ Get overall TM stats to give community a feel for progress that's being made """ dto = HomePageStatsDTO() dto.total_projects = Project.query.with_entities( func.count(Project.id) ).scalar() dto.mappers_online = ( Task.query.with_entities(func.count(Task.locked_by.distinct())) .filter(Task.locked_by.isnot(None)) .scalar() ) dto.total_mappers = User.query.with_entities(func.count(User.id)).scalar() dto.tasks_mapped = ( Task.query.with_entities(func.count()) .filter( Task.task_status.in_( (TaskStatus.MAPPED.value, TaskStatus.VALIDATED.value) ) ) .scalar() ) if not abbrev: dto.total_validators = ( Task.query.filter(Task.task_status == TaskStatus.VALIDATED.value) .distinct(Task.validated_by) .count() ) dto.tasks_validated = Task.query.filter( Task.task_status == TaskStatus.VALIDATED.value ).count() dto.total_area = Project.query.with_entities( func.coalesce(func.sum(func.ST_Area(Project.geometry, True) / 1000000)) ).scalar() dto.total_mapped_area = ( Task.query.with_entities( func.coalesce(func.sum(func.ST_Area(Task.geometry, True) / 1000000)) ) .filter(Task.task_status == TaskStatus.MAPPED.value) .scalar() ) dto.total_validated_area = ( Task.query.with_entities( func.coalesce(func.sum(func.ST_Area(Task.geometry, True) / 1000000)) ) .filter(Task.task_status == TaskStatus.VALIDATED.value) .scalar() ) unique_campaigns = Campaign.query.with_entities( func.count(Campaign.id) ).scalar() linked_campaigns_count = ( Campaign.query.join( campaign_projects, Campaign.id == campaign_projects.c.campaign_id ) .with_entities( Campaign.name, func.count(campaign_projects.c.campaign_id) ) .group_by(Campaign.id) .all() ) subquery = ( db.session.query(campaign_projects.c.project_id.distinct()) .order_by(campaign_projects.c.project_id) .subquery() ) no_campaign_count = ( Project.query.with_entities(func.count()) .filter(~Project.id.in_(subquery)) .scalar() ) dto.campaigns = [CampaignStatsDTO(row) for row in linked_campaigns_count] if no_campaign_count: dto.campaigns.append( CampaignStatsDTO(("Unassociated", no_campaign_count)) ) dto.total_campaigns = unique_campaigns unique_orgs = Organisation.query.with_entities( func.count(Organisation.id) ).scalar() linked_orgs_count = ( db.session.query(Organisation.name, func.count(Project.organisation_id)) .join(Project.organisation) .group_by(Organisation.id) .all() ) subquery = ( db.session.query(Project.organisation_id.distinct()) .order_by(Project.organisation_id) .subquery() ) no_org_project_count = ( Organisation.query.with_entities(func.count()) .filter(~Organisation.id.in_(subquery)) .scalar() ) dto.organisations = [OrganizationStatsDTO(row) for row in linked_orgs_count] if no_org_project_count: no_org_proj = OrganizationStatsDTO( ("Unassociated", no_org_project_count) ) dto.organisations.append(no_org_proj) dto.total_organisations = unique_orgs else: # Clear null attributes for abbreviated call clear_attrs = [ "total_validators", "tasks_validated", "total_area", "total_mapped_area", "total_validated_area", "campaigns", "total_campaigns", "organisations", "total_organisations", ] for attr in clear_attrs: delattr(dto, attr) return dto