def _definition_icon_url(definition): svg_image_path = resources_path('img', 'definitions', definition['key'] + '.svg') png_image_path = resources_path('img', 'definitions', definition['key'] + '.png') if exists(svg_image_path): url = resource_url(svg_image_path) elif exists(png_image_path): url = resource_url(png_image_path) else: url = None return url
def _definition_screenshot_url(definition): jpg_image_path = resources_path('img', 'definitions', definition['key'] + '_screenshot.jpg') png_image_path = resources_path('img', 'definitions', definition['key'] + '_screenshot.png') if exists(jpg_image_path): url = resource_url(jpg_image_path) elif exists(png_image_path): url = resource_url(png_image_path) else: url = None return url
def _definition_screenshot_url(definition): jpg_image_path = resources_path( 'img', 'definitions', definition['key'] + '_screenshot.jpg') png_image_path = resources_path( 'img', 'definitions', definition['key'] + '_screenshot.png') if exists(jpg_image_path): url = resource_url(jpg_image_path) elif exists(png_image_path): url = resource_url(png_image_path) else: url = None return url
def _definition_icon_url(definition): if 'key' not in definition: return None svg_image_path = resources_path( 'img', 'definitions', definition['key'] + '.svg') png_image_path = resources_path( 'img', 'definitions', definition['key'] + '.png') if exists(svg_image_path): url = resource_url(svg_image_path) elif exists(png_image_path): url = resource_url(png_image_path) else: url = None return url
def test_resources_url(self): """Test we can get the path as a local url nicely. .. versionadded:: 3.0 """ url = resource_url(resources_path('img', 'logos', 'inasafe-logo.png')) self.assertTrue('file://' in url, url + ' is not valid')
def impact_table_extractor(impact_report, component_metadata): """Extracting impact summary of the impact layer. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ context = {} extra_args = component_metadata.extra_args components_list = resolve_from_dictionary(extra_args, 'components_list') # TODO: Decide either to use it or not if not impact_report.impact_function.debug_mode: # only show experimental MMI Detail when in debug mode components_list.pop('mmi_detail', None) context['brand_logo'] = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) for key, component in list(components_list.items()): context[key] = jinja2_output_as_string(impact_report, component['key']) context['inasafe_resources_base_dir'] = resources_path() return context
def action_checklist_report_extractor(impact_report, component_metadata): """Extracting action checklist of the impact layer to its own report. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.1 """ context = {} extra_args = component_metadata.extra_args components_list = resolve_from_dictionary( extra_args, 'components_list') context['brand_logo'] = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) for key, component in list(components_list.items()): context[key] = jinja2_output_as_string( impact_report, component['key']) context['inasafe_resources_base_dir'] = resources_path() return context
def analysis_provenance_details_report_extractor(impact_report, component_metadata): """Extracting the main provenance details to its own report. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.1 """ context = {} extra_args = component_metadata.extra_args components_list = resolve_from_dictionary(extra_args, 'components_list') context['brand_logo'] = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) for key, component in list(components_list.items()): context[key] = jinja2_output_as_string(impact_report, component['key']) context['inasafe_resources_base_dir'] = resources_path() return context
def to_html(self): """Render as html. """ uri = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) snippet = ('<div class="branding">' '<img src="%s" title="%s" alt="%s" %s/></div>') % ( uri, 'InaSAFE', 'InaSAFE', self.html_attributes()) return snippet
def test_resources_url(self): """Test we can get the path as a local url nicely. .. versionadded:: 3.0 """ url = resource_url( resources_path( 'img', 'logos', 'inasafe-logo.png')) self.assertTrue( 'file://' in url, url + ' is not valid')
def to_html(self): """Render as html. """ uri = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) snippet = ( '<div class="branding">' '<img src="%s" title="%s" alt="%s" %s/></div>') % ( uri, 'InaSAFE', 'InaSAFE', self.html_attributes()) return snippet
def population_chart_legend_extractor(impact_report, component_metadata): """Extracting legend of population chart. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.2 """ context = {} resources_dir = safe_dir(sub_dir='../resources') context['inasafe_resources_base_dir'] = resources_dir """Population Charts""" population_donut_path = impact_report.component_absolute_output_path( 'population-chart-png') css_label_classes = [] try: population_chart_context = impact_report.metadata.component_by_key( 'population-chart').context['context'] """ :type: safe.report.extractors.infographic_elements.svg_charts. DonutChartContext """ for pie_slice in population_chart_context.slices: label = pie_slice['label'] if not label: continue css_class = label.replace(' ', '').lower() css_label_classes.append(css_class) except KeyError: population_chart_context = None context['population_chart'] = { 'img_path': resource_url(population_donut_path), 'context': population_chart_context, 'css_label_classes': css_label_classes } return context
def population_chart_legend_extractor(impact_report, component_metadata): """Extracting legend of population chart. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.2 """ context = {} context['inasafe_resources_base_dir'] = resources_path() """Population Charts""" population_donut_path = impact_report.component_absolute_output_path( 'population-chart-png') css_label_classes = [] try: population_chart_context = impact_report.metadata.component_by_key( 'population-chart').context['context'] """ :type: safe.report.extractors.infographic_elements.svg_charts. DonutChartContext """ for pie_slice in population_chart_context.slices: label = pie_slice['label'] if not label: continue css_class = label.replace(' ', '').lower() css_label_classes.append(css_class) except KeyError: population_chart_context = None context['population_chart'] = { 'img_path': resource_url(population_donut_path), 'context': population_chart_context, 'css_label_classes': css_label_classes } return context
def impact_table_extractor(impact_report, component_metadata): """Extracting impact summary of the impact layer. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ context = {} extra_args = component_metadata.extra_args debug_mode = impact_report.impact_function.debug_mode components_list = resolve_from_dictionary( extra_args, 'components_list') # TODO: Decide either to use it or not if not debug_mode: # only show experimental MMI Detail when in debug mode components_list.pop('mmi_detail', None) context['brand_logo'] = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) for key, component in components_list.iteritems(): context[key] = jinja2_output_as_string( impact_report, component['key']) context['inasafe_resources_base_dir'] = resources_path() return context
def population_infographic_extractor(impact_report, component_metadata): """Extracting aggregate result of demographic. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ context = {} extra_args = component_metadata.extra_args """Initializations""" hazard_layer = impact_report.hazard analysis_layer = impact_report.analysis analysis_layer_fields = analysis_layer.keywords['inasafe_fields'] icons = component_metadata.extra_args.get('icons') # this report sections only applies if it is a population report. population_fields = [ population_count_field['key'], exposure_count_field['key'] % (exposure_population['key'], ), ] + [f['key'] for f in minimum_needs_fields] for item in population_fields: if item in analysis_layer_fields: break else: return context # We try to get total affected field # if it didn't exists, check other fields to show total_affected_fields = [ total_affected_field['key'], # We might want to check other fields, but turn it off until further # discussion population_count_field['key'], exposure_count_field['key'] % (exposure_population['key'], ), ] for item in total_affected_fields: if item in analysis_layer_fields: total_affected = value_from_field_name(analysis_layer_fields[item], analysis_layer) total_affected_field_used = item break else: return context if displaced_field['key'] in analysis_layer_fields: total_displaced = value_from_field_name( analysis_layer_fields[displaced_field['key']], analysis_layer) else: return context sections = OrderedDict() """People Section""" # Take default value from definitions people_header = resolve_from_dictionary(extra_args, ['sections', 'people', 'header']) people_items = resolve_from_dictionary(extra_args, ['sections', 'people', 'items']) # create context for affected infographic sub_header = resolve_from_dictionary(people_items[0], 'sub_header') # retrieve relevant header based on the fields we showed. sub_header = sub_header[total_affected_field_used] affected_infographic = PeopleInfographicElement( header=sub_header, icon=icons.get(total_affected_field['key']), number=total_affected) # create context for displaced infographic sub_header = resolve_from_dictionary(people_items[1], 'sub_header') sub_header_note_format = resolve_from_dictionary(people_items[1], 'sub_header_note_format') rate_description_format = resolve_from_dictionary( people_items[1], 'rate_description_format') rate_description = [] hazard_classification = layer_hazard_classification(hazard_layer) for hazard_class in hazard_classification['classes']: displacement_rate = hazard_class.get('displacement_rate', 0) if displacement_rate: rate_description.append( rate_description_format.format(**hazard_class)) rate_description_string = ', '.join(rate_description) sub_header_note = sub_header_note_format.format( rate_description=rate_description_string) displaced_infographic = PeopleInfographicElement( header=sub_header, header_note=sub_header_note, icon=icons.get(displaced_field['key']), number=total_displaced) sections['people'] = { 'header': people_header, 'items': [affected_infographic, displaced_infographic] } """Vulnerability Section""" # Take default value from definitions vulnerability_items = resolve_from_dictionary( extra_args, ['sections', 'vulnerability', 'items']) vulnerability_section_header = resolve_from_dictionary( extra_args, ['sections', 'vulnerability', 'header']) vulnerability_section_sub_header_format = resolve_from_dictionary( extra_args, ['sections', 'vulnerability', 'sub_header_format']) infographic_elements = [] for group in vulnerability_items: fields = group['fields'] group_header = group['sub_group_header'] bootstrap_column = group['bootstrap_column'] element_column = group['element_column'] headers = group['headers'] elements = [] for field, header in zip(fields, headers): field_key = field['key'] try: field_name = analysis_layer_fields[field_key] value = value_from_field_name(field_name, analysis_layer) except KeyError: # It means the field is not there continue if value: value_percentage = value * 100.0 / total_displaced else: value_percentage = 0 infographic_element = PeopleVulnerabilityInfographicElement( header=header, icon=icons.get(field_key), number=value, percentage=value_percentage) elements.append(infographic_element) if elements: infographic_elements.append({ 'group_header': group_header, 'bootstrap_column': bootstrap_column, 'element_column': element_column, 'items': elements }) total_displaced_rounded = format_number(total_displaced, enable_rounding=True, is_population=True) sections['vulnerability'] = { 'header': vulnerability_section_header, 'small_header': vulnerability_section_sub_header_format.format( number_displaced=total_displaced_rounded), 'items': infographic_elements } """Minimum Needs Section""" minimum_needs_header = resolve_from_dictionary( extra_args, ['sections', 'minimum_needs', 'header']) empty_unit_string = resolve_from_dictionary( extra_args, ['sections', 'minimum_needs', 'empty_unit_string']) items = [] for item in minimum_needs_fields: need = item['need_parameter'] if isinstance(need, ResourceParameter): needs_count = value_from_field_name(item['field_name'], analysis_layer) if need.unit.abbreviation: unit_string = '{unit}/{frequency}'.format( unit=need.unit.abbreviation, frequency=need.frequency) else: unit_string = empty_unit_string item = PeopleMinimumNeedsInfographicElement(header=item['name'], icon=icons.get( item['key']), number=needs_count, unit=unit_string) items.append(item) # TODO: get from impact function provenance later needs_profile = NeedsProfile() sections['minimum_needs'] = { 'header': minimum_needs_header, 'small_header': needs_profile.provenance, 'items': items, } """Population Charts""" population_donut_path = impact_report.component_absolute_output_path( 'population-chart-png') css_label_classes = [] try: population_chart_context = impact_report.metadata.component_by_key( 'population-chart').context['context'] """ :type: safe.report.extractors.infographic_elements.svg_charts. DonutChartContext """ for pie_slice in population_chart_context.slices: label = pie_slice['label'] if not label: continue css_class = label.replace(' ', '').lower() css_label_classes.append(css_class) except KeyError: population_chart_context = None sections['population_chart'] = { 'img_path': resource_url(population_donut_path), 'context': population_chart_context, 'css_label_classes': css_label_classes } context['brand_logo'] = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) context['sections'] = sections context['title'] = analysis_layer.title() or value_from_field_name( analysis_name_field['field_name'], analysis_layer) return context
'headers': [ tr('Youth'), tr('Adult'), tr('Elderly') ] } ] }, 'minimum_needs': { 'header': tr('Minimum needs'), 'empty_unit_string': tr('units') } }, # definitions for icons 'icons': { 'total_affected_field': resource_url(resources_path( 'img/definitions/people.svg')), 'displaced_field': resource_url(resources_path( 'img/definitions/displaced.svg')), 'female_displaced_count_field': resource_url(resources_path( 'img/definitions/female.svg')), 'youth_displaced_count_field': resource_url(resources_path( 'img/definitions/youth.svg')), 'adult_displaced_count_field': resource_url(resources_path( 'img/definitions/adult.svg')), 'elderly_displaced_count_field': resource_url(resources_path( 'img/definitions/elderly.svg')), 'minimum_needs__rice_count_field': resource_url(resources_path( 'img/definitions/rice.svg')), 'minimum_needs__toilets_count_field': resource_url(resources_path( 'img/definitions/toilets.svg')), 'minimum_needs__drinking_water_count_field': resource_url(
], 'headers': [tr('Youth'), tr('Adult'), tr('Elderly')] } ] }, 'minimum_needs': { 'header': tr('Minimum needs'), 'empty_unit_string': tr('units') } }, # definitions for icons 'icons': { 'total_affected_field': resource_url(resources_path('img/definitions/people.svg')), 'displaced_field': resource_url(resources_path('img/definitions/displaced.svg')), 'female_displaced_count_field': resource_url(resources_path('img/definitions/female.svg')), 'youth_displaced_count_field': resource_url(resources_path('img/definitions/youth.svg')), 'adult_displaced_count_field': resource_url(resources_path('img/definitions/adult.svg')), 'elderly_displaced_count_field': resource_url(resources_path('img/definitions/elderly.svg')), 'minimum_needs__rice_count_field': resource_url(resources_path('img/definitions/rice.svg')), 'minimum_needs__toilets_count_field': resource_url(resources_path('img/definitions/toilets.svg')), 'minimum_needs__drinking_water_count_field':
def population_infographic_extractor(impact_report, component_metadata): """Extracting aggregate result of demographic. :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ context = {} extra_args = component_metadata.extra_args """Initializations""" hazard_layer = impact_report.hazard analysis_layer = impact_report.analysis analysis_layer_fields = analysis_layer.keywords['inasafe_fields'] icons = component_metadata.extra_args.get('icons') # this report sections only applies if it is a population report. population_fields = [ population_count_field['key'], exposure_count_field['key'] % (exposure_population['key'], ), ] + [f['key'] for f in minimum_needs_fields] for item in population_fields: if item in analysis_layer_fields: break else: return context # We try to get total affected field # if it didn't exists, check other fields to show total_affected_fields = [ total_affected_field['key'], # We might want to check other fields, but turn it off until further # discussion population_count_field['key'], exposure_count_field['key'] % (exposure_population['key'], ), ] for item in total_affected_fields: if item in analysis_layer_fields: total_affected = value_from_field_name( analysis_layer_fields[item], analysis_layer) total_affected_field_used = item break else: return context if displaced_field['key'] in analysis_layer_fields: total_displaced = value_from_field_name( analysis_layer_fields[displaced_field['key']], analysis_layer) else: return context sections = OrderedDict() """People Section""" # Take default value from definitions people_header = resolve_from_dictionary( extra_args, ['sections', 'people', 'header']) people_items = resolve_from_dictionary( extra_args, ['sections', 'people', 'items']) # create context for affected infographic sub_header = resolve_from_dictionary( people_items[0], 'sub_header') # retrieve relevant header based on the fields we showed. sub_header = sub_header[total_affected_field_used] affected_infographic = PeopleInfographicElement( header=sub_header, icon=icons.get( total_affected_field['key']), number=total_affected) # create context for displaced infographic sub_header = resolve_from_dictionary( people_items[1], 'sub_header') sub_header_note_format = resolve_from_dictionary( people_items[1], 'sub_header_note_format') rate_description_format = resolve_from_dictionary( people_items[1], 'rate_description_format') rate_description = [] hazard_classification = layer_hazard_classification(hazard_layer) for hazard_class in hazard_classification['classes']: displacement_rate = hazard_class.get('displacement_rate', 0) if displacement_rate: rate_description.append( rate_description_format.format(**hazard_class)) rate_description_string = ', '.join(rate_description) sub_header_note = sub_header_note_format.format( rate_description=rate_description_string) displaced_infographic = PeopleInfographicElement( header=sub_header, header_note=sub_header_note, icon=icons.get( displaced_field['key']), number=total_displaced) sections['people'] = { 'header': people_header, 'items': [ affected_infographic, displaced_infographic ] } """Vulnerability Section""" # Take default value from definitions vulnerability_items = resolve_from_dictionary( extra_args, ['sections', 'vulnerability', 'items']) vulnerability_section_header = resolve_from_dictionary( extra_args, ['sections', 'vulnerability', 'header']) vulnerability_section_sub_header_format = resolve_from_dictionary( extra_args, ['sections', 'vulnerability', 'sub_header_format']) infographic_elements = [] for group in vulnerability_items: fields = group['fields'] group_header = group['sub_group_header'] bootstrap_column = group['bootstrap_column'] element_column = group['element_column'] headers = group['headers'] elements = [] for field, header in zip(fields, headers): field_key = field['key'] try: field_name = analysis_layer_fields[field_key] value = value_from_field_name( field_name, analysis_layer) except KeyError: # It means the field is not there continue if value: value_percentage = value * 100.0 / total_displaced else: value_percentage = 0 infographic_element = PeopleVulnerabilityInfographicElement( header=header, icon=icons.get(field_key), number=value, percentage=value_percentage ) elements.append(infographic_element) if elements: infographic_elements.append({ 'group_header': group_header, 'bootstrap_column': bootstrap_column, 'element_column': element_column, 'items': elements }) total_displaced_rounded = format_number( total_displaced, enable_rounding=True, is_population=True) sections['vulnerability'] = { 'header': vulnerability_section_header, 'small_header': vulnerability_section_sub_header_format.format( number_displaced=total_displaced_rounded), 'items': infographic_elements } """Minimum Needs Section""" minimum_needs_header = resolve_from_dictionary( extra_args, ['sections', 'minimum_needs', 'header']) empty_unit_string = resolve_from_dictionary( extra_args, ['sections', 'minimum_needs', 'empty_unit_string']) items = [] for item in minimum_needs_fields: need = item['need_parameter'] if isinstance(need, ResourceParameter): needs_count = value_from_field_name( item['field_name'], analysis_layer) if need.unit.abbreviation: unit_string = '{unit}/{frequency}'.format( unit=need.unit.abbreviation, frequency=need.frequency) else: unit_string = empty_unit_string item = PeopleMinimumNeedsInfographicElement( header=item['name'], icon=icons.get( item['key']), number=needs_count, unit=unit_string) items.append(item) # TODO: get from impact function provenance later needs_profile = NeedsProfile() sections['minimum_needs'] = { 'header': minimum_needs_header, 'small_header': needs_profile.provenance, 'items': items, } """Population Charts""" population_donut_path = impact_report.component_absolute_output_path( 'population-chart-png') css_label_classes = [] try: population_chart_context = impact_report.metadata.component_by_key( 'population-chart').context['context'] """ :type: safe.report.extractors.infographic_elements.svg_charts. DonutChartContext """ for pie_slice in population_chart_context.slices: label = pie_slice['label'] if not label: continue css_class = label.replace(' ', '').lower() css_label_classes.append(css_class) except KeyError: population_chart_context = None sections['population_chart'] = { 'img_path': resource_url(population_donut_path), 'context': population_chart_context, 'css_label_classes': css_label_classes } context['brand_logo'] = resource_url( resources_path('img', 'logos', 'inasafe-logo-white.png')) context['sections'] = sections context['title'] = analysis_layer.title() or value_from_field_name( analysis_name_field['field_name'], analysis_layer) return context
from safe import messaging as m from safe.messaging import styles from safe.common.exceptions import (InsufficientOverlapError, TemplateLoadingError) from safe.report.impact_report import ImpactReport from safe.gui.tools.impact_report_dialog import ImpactReportDialog from safe_extras.pydispatch import dispatcher from safe.utilities.analysis import Analysis from safe.utilities.extent import Extent PROGRESS_UPDATE_STYLE = styles.PROGRESS_UPDATE_STYLE INFO_STYLE = styles.INFO_STYLE WARNING_STYLE = styles.WARNING_STYLE LOGO_ELEMENT = m.Image( resource_url(resources_path('img', 'logos', 'inasafe-logo.png')), 'InaSAFE Logo') LOGGER = logging.getLogger('InaSAFE') class AnalysisHandler(QObject): """Analysis handler for the dock and the wizard.""" analysisDone = pyqtSignal(bool) # noinspection PyUnresolvedReferences def __init__(self, parent): """Constructor for the class. :param parent: Parent widget i.e. the wizard dialog. :type parent: QWidget
from safe.messaging import styles from safe.common.exceptions import ( InsufficientOverlapError, TemplateLoadingError) from safe.report.impact_report import ImpactReport from safe.gui.tools.impact_report_dialog import ImpactReportDialog from safe_extras.pydispatch import dispatcher from safe.utilities.analysis import Analysis from safe.utilities.extent import Extent from safe.impact_functions.impact_function_manager import ImpactFunctionManager PROGRESS_UPDATE_STYLE = styles.PROGRESS_UPDATE_STYLE INFO_STYLE = styles.INFO_STYLE WARNING_STYLE = styles.WARNING_STYLE LOGO_ELEMENT = m.Image( resource_url( resources_path('img', 'logos', 'inasafe-logo.png')), 'InaSAFE Logo') LOGGER = logging.getLogger('InaSAFE') class AnalysisHandler(QObject): """Analysis handler for the dock and the wizard.""" analysisDone = pyqtSignal(bool) # noinspection PyUnresolvedReferences def __init__(self, parent): """Constructor for the class. :param parent: Parent widget i.e. the wizard dialog.
from safe.common.utilities import temp_dir, unique_filename from safe.common.version import get_version from safe.common.exceptions import KeywordNotFoundError, TemplateLoadingError from safe import messaging as m from safe.messaging import styles from safe.utilities.keyword_io import KeywordIO from safe.utilities.resources import resources_path from safe.utilities.gis import qgis_version from safe.utilities.utilities import impact_attribution, html_to_file from safe.utilities.resources import html_footer, html_header, resource_url from safe.utilities.i18n import tr from safe.defaults import default_organisation_logo_path, default_north_arrow_path from safe.report.template_composition import TemplateComposition INFO_STYLE = styles.INFO_STYLE LOGO_ELEMENT = m.Image(resource_url(resources_path("img", "logos", "inasafe-logo.png")), "InaSAFE Logo") LOGGER = logging.getLogger("InaSAFE") class ImpactReport(object): """A class for creating report using QgsComposition.""" def __init__(self, iface, template, layer): """Constructor for the Composition Report class. :param iface: Reference to the QGIS iface object. :type iface: QgsAppInterface :param template: The QGIS template path. :type template: str """