def test_all_dynamic_translations(self): """Test all the phrases defined in dynamic_translations translate.""" parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join( dir_path, '../safe', 'common', 'dynamic_translations.py') translations_file = file(file_path) failure_list = [] os.environ['LANG'] = 'id' line_count = 0 # exception_words is a list of words that has the same form in both # English and Indonesian. For example hotel, bank exception_words = ['hotel', 'bank', 'Area'] for line in translations_file.readlines(): line_count += 1 if 'tr(' in line: match = re.search(r'\(\'(.*)\'\)', line, re.M | re.I) if match: group = match.group() cleaned_line = group[2:-2] if cleaned_line in exception_words: continue translation = safeTr(cleaned_line) if cleaned_line == translation: failure_list.append(cleaned_line) message = ( 'Translations not found for:\n %s\n%i of %i untranslated\n' % ( str(failure_list).replace(',', '\n'), len(failure_list), line_count)) message += ( 'If you think the Indonesian word for the failed translations is ' 'the same form in English, i.e. "hotel", you can add it in ' 'exception_words in safe_qgis/test_safe_translations.py') self.assertEqual(len(failure_list), 0, message)
def test_dynamic_translation(self): """Test for dynamic translations for a string.""" # English function_title = 'Be affected' expected_title = safeTr('Be affected') message = 'Expected %s but got %s' % (expected_title, function_title) self.assertEqual(function_title, expected_title, message) # Indonesia os.environ['LANG'] = 'id' function_title = 'Be affected' real_title = safeTr(function_title) expected_title = 'Terkena dampak' message = 'expected %s but got %s' % (expected_title, real_title) self.assertEqual(expected_title, real_title, message)
def testAllDynamicTranslatons(self): """Test all the phrases defined in dynamic_translations translate.""" myParentPath = os.path.join(__file__, os.path.pardir, os.path.pardir) myDirPath = os.path.abspath(myParentPath) myFilePath = os.path.join(myDirPath, '../safe', 'common', 'dynamic_translations.py') myFile = file(myFilePath, 'rt') myFailureList = [] os.environ['LANG'] = 'id' myLineCount = 0 # exception_words is a list of words that has the same form in both # English and Indonesian. For example hotel, bank exception_words = ['hotel', 'bank'] for myLine in myFile.readlines(): myLineCount += 1 if 'tr(' in myLine: myMatch = re.search(r'\(\'(.*)\'\)', myLine, re.M | re.I) if myMatch: myGroup = myMatch.group() myCleanedLine = myGroup[2:-2] if myCleanedLine in exception_words: continue myTranslation = safeTr(myCleanedLine) print myTranslation, myCleanedLine if myCleanedLine == myTranslation: myFailureList.append(myCleanedLine) myMessage = ('Translations not found for:\n %s\n%i ' 'of %i untranslated\n' % (str(myFailureList).replace( ',', '\n'), len(myFailureList), myLineCount)) myMessage += ('If you think the Indonesian word for the failed ' 'translations is the same form in English, i.' 'e. "hotel", you can add it in exception_words in ' 'safe_qgis/test_safe_translations.py') assert len(myFailureList) == 0, myMessage
def test_all_dynamic_translations(self): """Test all the phrases defined in dynamic_translations translate.""" parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join(dir_path, '../safe', 'common', 'dynamic_translations.py') translations_file = file(file_path) failure_list = [] os.environ['LANG'] = 'id' line_count = 0 # exception_words is a list of words that has the same form in both # English and Indonesian. For example hotel, bank exception_words = ['hotel', 'bank', 'Area'] for line in translations_file.readlines(): line_count += 1 if 'tr(' in line: match = re.search(r'\(\'(.*)\'\)', line, re.M | re.I) if match: group = match.group() cleaned_line = group[2:-2] if cleaned_line in exception_words: continue translation = safeTr(cleaned_line) print translation, cleaned_line if cleaned_line == translation: failure_list.append(cleaned_line) message = ('Translations not found for:\n %s\n%i ' 'of %i untranslated\n' % (str(failure_list).replace( ',', '\n'), len(failure_list), line_count)) message += ('If you think the Indonesian word for the failed ' 'translations is the same form in English, i.' 'e. "hotel", you can add it in exception_words in ' 'safe_qgis/test_safe_translations.py') assert len(failure_list) == 0, message
def testImpactSummaryWords(self): """Test specific words from impact summary info shown in doc see #348. """ os.environ['LANG'] = 'id' myPhraseList = [] myMessage = 'Specific words checked for translation:\n' for myPhrase in myPhraseList: if myPhrase == safeTr(myPhrase): myMessage += 'FAIL: %s' % myPhrase else: myMessage += 'PASS: %s' % myPhrase self.assertNotIn('FAIL', myMessage, myMessage)
def test_impact_summary_words(self): """Test specific words from impact summary info shown in doc see #348. """ os.environ['LANG'] = 'id' phrase_list = [] message = 'Specific words checked for translation:\n' for phrase in phrase_list: if phrase == safeTr(phrase): message += 'FAIL: %s' % phrase else: message += 'PASS: %s' % phrase self.assertNotIn('FAIL', message, message)
def test_impact_summary_words(self): """Test specific words from impact summary info shown in doc see #348. """ os.environ['LANG'] = 'id' phrase_list = [] message = 'Specific words checked for translation:\n' for myPhrase in phrase_list: if myPhrase == safeTr(myPhrase): message += 'FAIL: %s' % myPhrase else: message += 'PASS: %s' % myPhrase self.assertNotIn('FAIL', message, message)
def test_impact_summary_words(self): """Test specific words from impact summary info shown in doc see #348. """ os.environ["LANG"] = "id" phrase_list = [] message = "Specific words checked for translation:\n" for myPhrase in phrase_list: if myPhrase == safeTr(myPhrase): message += "FAIL: %s" % myPhrase else: message += "PASS: %s" % myPhrase self.assertNotIn("FAIL", message, message)
def Xtest_ImpactFunctionI18n(self): """Library translations are working.""" # Import this late so that i18n setup is already in place # Test indonesian too myCanvas = QgsMapCanvas(PARENT) myIface = QgisInterface(myCanvas) myPlugin = Plugin(myIface) myPlugin.change_i18n('id') # indonesian myExpectedString = 'Letusan gunung berapi' myTranslation = safeTr('A volcano eruption') message = '\nTranslated: %s\nGot: %s\nExpected: %s' % \ ('A volcano eruption', myTranslation, myExpectedString) assert myTranslation == myExpectedString, message
def Xtest_ImpactFunctionI18n(self): """Library translations are working.""" # Import this late so that i18n setup is already in place # Test indonesian too myCanvas = QgsMapCanvas(PARENT) myIface = QgisInterface(myCanvas) myPlugin = Plugin(myIface) myPlugin.setup_i18n('id') # indonesian myExpectedString = 'Letusan gunung berapi' myTranslation = safeTr('A volcano eruption') myMessage = '\nTranslated: %s\nGot: %s\nExpected: %s' % \ ('A volcano eruption', myTranslation, myExpectedString) assert myTranslation == myExpectedString, myMessage
def buildWidget(self, theFormLayout, theName, theValue): """Create a new form element dynamically based from theValue type. The element will be inserted to theFormLayout. :param theFormLayout: Mandatory a layout instance :type theFormLayout: QFormLayout :param theName: Mandatory string referencing the key in the function configurable parameters dictionary. :type theName: str :param theValue: Mandatory representing the value referenced by the key. :type theValue: object :returns: a function that return the value of widget :raises: None """ # create label if isinstance(theName, str): myLabel = QLabel() myLabel.setObjectName(_fromUtf8(theName + "Label")) myLabelText = theName.replace('_', ' ').capitalize() myLabel.setText(safeTr(myLabelText)) myLabel.setToolTip(str(type(theValue))) else: myLabel = theName # create widget based on the type of theValue variable if isinstance(theValue, list): myWidget = QLineEdit() myValue = ', '.join([str(x) for x in theValue]) # NOTE: we assume that all element in list have same type myType = type(theValue[0]) myFunc = lambda x: [myType(y) for y in str(x).split(',')] elif isinstance(theValue, dict): myWidget = QLineEdit() myValue = str(theValue) myFunc = lambda x: ast.literal_eval(str(x)) else: myWidget = QLineEdit() myValue = str(theValue) myFunc = type(theValue) myWidget.setText(myValue) theFormLayout.addRow(myLabel, myWidget) return self.bind(myWidget, 'text', myFunc)
def test_dynamic_translation(self): """Test for dynamic translations for a string """ # English func_title = "Be affected" expected_title = "Be affected" assert func_title == expected_title # Indonesia os.environ["LANG"] = "id" func_title = "Be affected" real_title = safeTr(func_title) expected_title = "Terkena dampak" msg = "expected %s but got %s" % (expected_title, real_title) assert expected_title == real_title, msg
def test_dynamic_translation(self): """Test for dynamic translations for a string """ # English func_title = 'Be affected' expected_title = 'Be affected' assert func_title == expected_title # Indonesia os.environ['LANG'] = 'id' func_title = 'Be affected' real_title = safeTr(func_title) expected_title = 'Terkena dampak' msg = 'expected %s but got %s' % (expected_title, real_title) assert expected_title == real_title, msg
def testDynamicTranslation(self): """Test for dynamic translations for a string """ # English func_title = 'Be affected' expected_title = 'Be affected' assert func_title == expected_title # Indonesia os.environ['LANG'] = 'id' func_title = 'Be affected' real_title = safeTr(func_title) expected_title = 'Terkena dampak' msg = 'expected %s but got %s' % (expected_title, real_title) assert expected_title == real_title, msg
def testAllDynamicTranslatons(self): """Test all the phrases defined in dynamic_translations translate.""" myParentPath = os.path.join(__file__, os.path.pardir, os.path.pardir) myDirPath = os.path.abspath(myParentPath) myFilePath = os.path.join(myDirPath, '../safe', 'common', 'dynamic_translations.py') myFile = file(myFilePath, 'rt') myFailureList = [] os.environ['LANG'] = 'id' myLineCount = 0 # exception_words is a list of words that has the same form in both # English and Indonesian. For example hotel, bank exception_words = ['hotel', 'bank'] for myLine in myFile.readlines(): myLineCount += 1 if 'tr(' in myLine: myMatch = re.search(r'\(\'(.*)\'\)', myLine, re.M | re.I) if myMatch: myGroup = myMatch.group() myCleanedLine = myGroup[2:-2] if myCleanedLine in exception_words: continue myTranslation = safeTr(myCleanedLine) print myTranslation, myCleanedLine if myCleanedLine == myTranslation: myFailureList.append(myCleanedLine) myMessage = ('Translations not found for:\n %s\n%i ' 'of %i untranslated\n' % ( str(myFailureList).replace(',', '\n'), len(myFailureList), myLineCount)) myMessage += ('If you think the Indonesian word for the failed ' 'translations is the same form in English, i.' 'e. "hotel", you can add it in exception_words in ' 'safe_qgis/test_safe_translations.py') assert len(myFailureList) == 0, myMessage
def test_all_dynamic_translations(self): """Test all the phrases defined in dynamic_translations translate.""" parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join(dir_path, "../safe", "common", "dynamic_translations.py") translations_file = file(file_path) failure_list = [] os.environ["LANG"] = "id" line_count = 0 # exception_words is a list of words that has the same form in both # English and Indonesian. For example hotel, bank exception_words = ["hotel", "bank", "Area"] for line in translations_file.readlines(): line_count += 1 if "tr(" in line: match = re.search(r"\(\'(.*)\'\)", line, re.M | re.I) if match: group = match.group() cleaned_line = group[2:-2] if cleaned_line in exception_words: continue translation = safeTr(cleaned_line) print translation, cleaned_line if cleaned_line == translation: failure_list.append(cleaned_line) message = "Translations not found for:\n %s\n%i " "of %i untranslated\n" % ( str(failure_list).replace(",", "\n"), len(failure_list), line_count, ) message += ( "If you think the Indonesian word for the failed " "translations is the same form in English, i." 'e. "hotel", you can add it in exception_words in ' "safe_qgis/test_safe_translations.py" ) assert len(failure_list) == 0, message
def save_scenario(self, scenario_file_path=None): """Save current scenario to a text file. You can use the saved scenario with the batch runner. :param scenario_file_path: A path to the scenario file. :type scenario_file_path: str """ # Validate Input warning_title = self.tr('InaSAFE Save Scenario Warning') is_valid, warning_message = self.validate_input() if not is_valid: # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QtGui.QMessageBox.warning(self, warning_title, warning_message) return # Make extent to look like: # 109.829170982, -8.13333290561, 111.005344795, -7.49226294379 extent = viewport_geo_array(self.iface.mapCanvas()) extent_string = ', '.join(('%f' % x) for x in extent) exposure_path = str(self.exposure_layer.publicSource()) hazard_path = str(self.hazard_layer.publicSource()) title = self.keyword_io.read_keywords(self.hazard_layer, 'title') title = safeTr(title) default_filename = title.replace( ' ', '_').replace('(', '').replace(')', '') # Popup a dialog to request the filename if scenario_file_path = None dialog_title = self.tr('Save Scenario') if scenario_file_path is None: # noinspection PyCallByClass,PyTypeChecker scenario_file_path = str( QFileDialog.getSaveFileName( self, dialog_title, os.path.join( self.output_directory, default_filename + '.txt'), "Text files (*.txt)")) if scenario_file_path is None or scenario_file_path == '': return self.output_directory = os.path.dirname(scenario_file_path) # Get relative path for each layer relative_exposure_path = self.relative_path( scenario_file_path, exposure_path) relative_hazard_path = self.relative_path( scenario_file_path, hazard_path) # Write to file parser = ConfigParser() parser.add_section(title) parser.set(title, 'exposure', relative_exposure_path) parser.set(title, 'hazard', relative_hazard_path) parser.set(title, 'function', self.function_id) parser.set(title, 'extent', extent_string) if self.aggregation_layer is not None: aggregation_path = str(self.aggregation_layer.publicSource()) relative_aggregation_path = self.relative_path( scenario_file_path, aggregation_path) parser.set(title, 'aggregation', relative_aggregation_path) try: parser.write(open(scenario_file_path, 'a')) except IOError: # noinspection PyTypeChecker,PyCallByClass,PyArgumentList QtGui.QMessageBox.warning( self, self.tr('InaSAFE'), self.tr('Failed to save scenario to ' + scenario_file_path)) # Save State self.save_state()
def _generateTables(self): """Parses the postprocessing output as one table per postprocessor. Args: None Returns: str - a string containing the html """ myMessage = m.Message() for proc, resList in self.postProcessingOutput.iteritems(): # resList is for example: # [ # (PyQt4.QtCore.QString(u'Entire area'), OrderedDict([ # (u'Total', {'value': 977536, 'metadata': {}}), # (u'Female population', {'value': 508319, 'metadata': {}}), # (u'Weekly hygiene packs', {'value': 403453, 'metadata': { # 'description': 'Females hygiene packs for weekly use'}}) # ])) #] try: #sorting using the first indicator of a postprocessor sortedResList = sorted( resList, key=self._sortNoData, reverse=True) except KeyError: LOGGER.debug('Skipping sorting as the postprocessor did not ' 'have a "Total" field') #init table hasNoDataValues = False myTable = m.Table( style_class='table table-condensed table-striped') myTable.caption = self.tr('Detailed %1 report').arg(safeTr( get_postprocessor_human_name(proc)).lower()) myHeaderRow = m.Row() myHeaderRow.add(str(self.attributeTitle).capitalize()) for calculationName in sortedResList[0][1]: myHeaderRow.add(self.tr(calculationName)) myTable.add(myHeaderRow) for zoneName, calc in sortedResList: myRow = m.Row(zoneName) for _, calculationData in calc.iteritems(): myValue = calculationData['value'] if myValue == self.aggregator.defaults['NO_DATA']: hasNoDataValues = True myValue += ' *' myRow.add(myValue) myTable.add(myRow) #add table to message myMessage.add(myTable) if hasNoDataValues: myMessage.add(m.EmphasizedText(self.tr( '* "%1" values mean that there where some problems while ' 'calculating them. This did not affect the other ' 'values.').arg(self.aggregator.defaults['NO_DATA']))) try: if (self.keywordIO.read_keywords( self.aggregator.layer, 'HAD_MULTIPART_POLY')): myMessage.add(m.EmphasizedText(self.tr( 'The aggregation layer had multipart polygons, these have ' 'been exploded and are now marked with a #. This has no ' 'influence on the calculation, just keep in mind that the ' 'attributes shown may represent the original multipart ' 'polygon and not the individual exploded polygon parts.'))) except Exception: # pylint: disable=W0703 pass return myMessage
def _generateTables(self): """Parses the postprocessing output as one table per postprocessor. Args: None Returns: str - a string containing the html """ myMessage = m.Message() for proc, resList in self.postProcessingOutput.iteritems(): # resList is for example: # [ # (PyQt4.QtCore.QString(u'Entire area'), OrderedDict([ # (u'Total', {'value': 977536, 'metadata': {}}), # (u'Female population', {'value': 508319, 'metadata': {}}), # (u'Weekly hygiene packs', {'value': 403453, 'metadata': { # 'description': 'Females hygiene packs for weekly use'}}) # ])) #] try: #sorting using the first indicator of a postprocessor sortedResList = sorted(resList, key=self._sortNoData, reverse=True) except KeyError: LOGGER.debug('Skipping sorting as the postprocessor did not ' 'have a "Total" field') #init table hasNoDataValues = False myTable = m.Table( style_class='table table-condensed table-striped') myTable.caption = self.tr('Detailed %1 report').arg( safeTr(get_postprocessor_human_name(proc)).lower()) myHeaderRow = m.Row() myHeaderRow.add(str(self.attributeTitle).capitalize()) for calculationName in sortedResList[0][1]: myHeaderRow.add(self.tr(calculationName)) myTable.add(myHeaderRow) for zoneName, calc in sortedResList: myRow = m.Row(zoneName) for _, calculationData in calc.iteritems(): myValue = calculationData['value'] if myValue == self.aggregator.defaults['NO_DATA']: hasNoDataValues = True myValue += ' *' myRow.add(myValue) myTable.add(myRow) #add table to message myMessage.add(myTable) if hasNoDataValues: myMessage.add( m.EmphasizedText( self. tr('* "%1" values mean that there where some problems while ' 'calculating them. This did not affect the other ' 'values.').arg( self.aggregator.defaults['NO_DATA']))) try: if (self.keywordIO.read_keywords(self.aggregator.layer, 'HAD_MULTIPART_POLY')): myMessage.add( m.EmphasizedText( self. tr('The aggregation layer had multipart polygons, these have ' 'been exploded and are now marked with a #. This has no ' 'influence on the calculation, just keep in mind that the ' 'attributes shown may represent the original multipart ' 'polygon and not the individual exploded polygon parts.' ))) except Exception: # pylint: disable=W0703 pass return myMessage
def impactLayerAttribution(theKeywords, theInaSAFEFlag=False): """Make a little table for attribution of data sources used in impact. Args: * theKeywords: dict{} - a keywords dict for an impact layer. * theInaSAFEFlag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. Returns: str: an html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. Raises: None """ if theKeywords is None: return None myReport = '' myJoinWords = ' - %s ' % tr('sourced from') myHazardDetails = tr('Hazard details') myHazardTitleKeyword = 'hazard_title' myHazardSourceKeyword = 'hazard_source' myExposureDetails = tr('Exposure details') myExposureTitleKeyword = 'exposure_title' myExposureSourceKeyword = 'exposure_source' if myHazardTitleKeyword in theKeywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardTitle = safeTr(theKeywords[myHazardTitleKeyword]) else: myHazardTitle = tr('Hazard layer') if myHazardSourceKeyword in theKeywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardSource = safeTr(theKeywords[myHazardSourceKeyword]) else: myHazardSource = tr('an unknown source') if myExposureTitleKeyword in theKeywords: myExposureTitle = theKeywords[myExposureTitleKeyword] else: myExposureTitle = tr('Exposure layer') if myExposureSourceKeyword in theKeywords: myExposureSource = theKeywords[myExposureSourceKeyword] else: myExposureSource = tr('an unknown source') myReport += ('<table class="table table-striped condensed' ' bordered-table">') myReport += '<tr><th>%s</th></tr>' % myHazardDetails myReport += '<tr><td>%s%s %s.</td></tr>' % ( myHazardTitle, myJoinWords, myHazardSource) myReport += '<tr><th>%s</th></tr>' % myExposureDetails myReport += '<tr><td>%s%s %s.</td></tr>' % ( myExposureTitle, myJoinWords, myExposureSource) if theInaSAFEFlag: myReport += '<tr><th>%s</th></tr>' % tr('Software notes') myInaSAFEPhrase = tr('This report was created using InaSAFE ' 'version %1. Visit http://inasafe.org to get ' 'your free copy of this software!').arg( get_version()) myInaSAFEPhrase += tr('InaSAFE has been jointly developed by' ' BNPB, AusAid & the World Bank') myReport += '<tr><td>%s</td></tr>' % myInaSAFEPhrase myReport += '</table>' return myReport
def impact_attribution(keywords, inasafe_flag=False): """Make a little table for attribution of data sources used in impact. :param keywords: A keywords dict for an impact layer. :type keywords: dict :param inasafe_flag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. :returns: An html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. :rtype: safe.messaging.Message """ if keywords is None: return None join_words = ' - %s ' % tr('sourced from') hazard_details = tr('Hazard details') hazard_title_keywords = 'hazard_title' hazard_source_keywords = 'hazard_source' exposure_details = tr('Exposure details') exposure_title_keywords = 'exposure_title' exposure_source_keyword = 'exposure_source' if hazard_title_keywords in keywords: # We use safe translation infrastructure for this one (rather than Qt) hazard_title = safeTr(keywords[hazard_title_keywords]) else: hazard_title = tr('Hazard layer') if hazard_source_keywords in keywords: # We use safe translation infrastructure for this one (rather than Qt) hazard_source = safeTr(keywords[hazard_source_keywords]) else: hazard_source = tr('an unknown source') if exposure_title_keywords in keywords: exposure_title = keywords[exposure_title_keywords] else: exposure_title = tr('Exposure layer') if exposure_source_keyword in keywords: exposure_source = keywords[exposure_source_keyword] else: exposure_source = tr('an unknown source') report = m.Message() report.add(m.Heading(hazard_details, **INFO_STYLE)) report.add(m.Paragraph( hazard_title, join_words, hazard_source)) report.add(m.Heading(exposure_details, **INFO_STYLE)) report.add(m.Paragraph( exposure_title, join_words, exposure_source)) if inasafe_flag: report.add(m.Heading(tr('Software notes'), **INFO_STYLE)) # noinspection PyUnresolvedReferences inasafe_phrase = tr( 'This report was created using InaSAFE version %s. Visit ' 'http://inasafe.org to get your free copy of this software!' 'InaSAFE has been jointly developed by BNPB, AusAid/AIFDRR & the ' 'World Bank') % (get_version()) report.add(m.Paragraph(m.Text(inasafe_phrase))) return report
def impact_attribution(keywords, inasafe_flag=False): """Make a little table for attribution of data sources used in impact. :param keywords: A keywords dict for an impact layer. :type keywords: dict :param inasafe_flag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. :returns: An html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. :rtype: str """ if keywords is None: return None myJoinWords = ' - %s ' % tr('sourced from') myHazardDetails = tr('Hazard details') myHazardTitleKeyword = 'hazard_title' myHazardSourceKeyword = 'hazard_source' myExposureDetails = tr('Exposure details') myExposureTitleKeyword = 'exposure_title' myExposureSourceKeyword = 'exposure_source' if myHazardTitleKeyword in keywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardTitle = safeTr(keywords[myHazardTitleKeyword]) else: myHazardTitle = tr('Hazard layer') if myHazardSourceKeyword in keywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardSource = safeTr(keywords[myHazardSourceKeyword]) else: myHazardSource = tr('an unknown source') if myExposureTitleKeyword in keywords: myExposureTitle = keywords[myExposureTitleKeyword] else: myExposureTitle = tr('Exposure layer') if myExposureSourceKeyword in keywords: myExposureSource = keywords[myExposureSourceKeyword] else: myExposureSource = tr('an unknown source') myReport = m.Message() myReport.add(m.Heading(myHazardDetails, **INFO_STYLE)) myReport.add(m.Paragraph( myHazardTitle, myJoinWords, myHazardSource)) myReport.add(m.Heading(myExposureDetails, **INFO_STYLE)) myReport.add(m.Paragraph( myExposureTitle, myJoinWords, myExposureSource)) if inasafe_flag: myReport.add(m.Heading(tr('Software notes'), **INFO_STYLE)) myInaSAFEPhrase = tr( 'This report was created using InaSAFE version %1. Visit ' 'http://inasafe.org to get your free copy of this software!' 'InaSAFE has been jointly developed by BNPB, AusAid/AIFDRR & the ' 'World Bank').arg(get_version()) myReport.add(m.Paragraph(m.Text(myInaSAFEPhrase))) return myReport
def _generate_tables(self): """Parses the postprocessing output as one table per postprocessor. TODO: This should rather return json and then have a helper method to make html from the JSON. :returns: The html. :rtype: str """ message = m.Message() for processor, results_list in self.output.iteritems(): self.current_output_postprocessor = processor # results_list is for example: # [ # (PyQt4.QtCore.QString(u'Entire area'), OrderedDict([ # (u'Total', {'value': 977536, 'metadata': {}}), # (u'Female population', {'value': 508319, 'metadata': {}}), # (u'Weekly hygiene packs', {'value': 403453, 'metadata': { # 'description': 'Females hygiene packs for weekly use'}}) # ])) #] #sorting using the first indicator of a postprocessor sorted_results = sorted( results_list, key=self._sort_no_data, reverse=True) #init table has_no_data = False table = m.Table( style_class='table table-condensed table-striped') table.caption = self.tr('Detailed %s report') % (safeTr( get_postprocessor_human_name(processor)).lower()) header = m.Row() header.add(str(self.attribute_title).capitalize()) for calculation_name in sorted_results[0][1]: header.add(self.tr(calculation_name)) table.add(header) # used to calculate the totals row as per issue #690 postprocessor_totals = OrderedDict() for zone_name, calc in sorted_results: row = m.Row(zone_name) for indicator, calculation_data in calc.iteritems(): value = calculation_data['value'] if value == self.aggregator.defaults['NO_DATA']: has_no_data = True value += ' *' try: postprocessor_totals[indicator] += 0 except KeyError: postprocessor_totals[indicator] = 0 else: try: postprocessor_totals[indicator] += int(value) except KeyError: postprocessor_totals[indicator] = int(value) row.add(value) table.add(row) # add the totals row row = m.Row(self.tr('Total in aggregation areas')) for _, total in postprocessor_totals.iteritems(): row.add(str(total)) table.add(row) # add table to message message.add(table) if has_no_data: message.add(m.EmphasizedText(self.tr( '* "%s" values mean that there where some problems while ' 'calculating them. This did not affect the other ' 'values.') % (self.aggregator.defaults['NO_DATA']))) return message
def build_widget(self, form_layout, name, key_value): """Create a new form element dynamically based from theValue type. The element will be inserted to theFormLayout. :param form_layout: Mandatory a layout instance :type form_layout: QFormLayout :param name: Mandatory string referencing the key in the function configurable parameters dictionary. :type name: str :param key_value: Mandatory representing the value referenced by the key. :type key_value: object :returns: a function that return the value of widget :raises: None """ # create label if isinstance(name, str): label = QLabel() label.setObjectName(_fromUtf8(name + "Label")) label_text = name.replace('_', ' ').capitalize() label.setText(safeTr(label_text)) label.setToolTip(str(type(key_value))) else: label = name # create widget based on the type of key_value variable # if widget is a QLineEdit, value needs to be set # if widget is NOT a QLineEdit, property_name needs to be set value = None property_name = None # can be used for widgets that have their own text like QCheckBox hide_label = False if isinstance(key_value, list): widget = QLineEdit() value = ', '.join([str(x) for x in key_value]) # NOTE: we assume that all element in list have same type value_type = type(key_value[0]) function = lambda z: [value_type(y) for y in str(z).split(',')] elif isinstance(key_value, dict): widget = QLineEdit() value = str(key_value) function = lambda z: ast.literal_eval(str(z)) elif isinstance(key_value, bool): widget = QCheckBox() widget.setChecked(key_value) widget.setText(label.text()) property_name = 'checked' function = bool hide_label = True else: widget = QLineEdit() value = str(key_value) function = type(key_value) if hide_label: form_layout.addRow(widget) else: form_layout.addRow(label, widget) if type(widget) is QLineEdit: widget.setText(value) property_name = 'text' return self.bind(widget, property_name, function)
def build_widget(self, form_layout, name, key_value): """Create a new form element dynamically based from theValue type. The element will be inserted to theFormLayout. :param form_layout: Mandatory a layout instance :type form_layout: QFormLayout :param name: Mandatory string referencing the key in the function configurable parameters dictionary. :type name: str :param key_value: Mandatory representing the value referenced by the key. :type key_value: object :returns: a function that return the value of widget :raises: None """ # create label if isinstance(name, str): label = QLabel() label.setObjectName(_fromUtf8(name + "Label")) label_text = name.replace('_', ' ').capitalize() label.setText(safeTr(label_text)) label.setToolTip(str(type(key_value))) else: label = name # create widget based on the type of key_value variable # if widget is a QLineEdit, value needs to be set # if widget is NOT a QLineEdit, property_name needs to be set value = None property_name = None # can be used for widgets that have their own text like QCheckBox hide_label = False if isinstance(key_value, list): widget = QLineEdit() value = ', '.join([str(x) for x in key_value]) # NOTE: we assume that all element in list have same type value_type = type(key_value[0]) function = lambda x: [value_type(y) for y in str(x).split(',')] elif isinstance(key_value, dict): widget = QLineEdit() value = str(key_value) function = lambda x: ast.literal_eval(str(x)) elif isinstance(key_value, bool): widget = QCheckBox() widget.setChecked(key_value) widget.setText(label.text()) property_name = 'checked' function = bool hide_label = True else: widget = QLineEdit() value = str(key_value) function = type(key_value) if hide_label: form_layout.addRow(widget) else: form_layout.addRow(label, widget) # are we dealing with a QLineEdit? if value is not None: widget.setText(value) property_name = 'text' return self.bind(widget, property_name, function)
def impact_attribution(keywords, inasafe_flag=False): """Make a little table for attribution of data sources used in impact. :param keywords: A keywords dict for an impact layer. :type keywords: dict :param inasafe_flag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. :returns: An html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. :rtype: safe.messaging.Message """ if keywords is None: return None join_words = ' - %s ' % tr('sourced from') hazard_details = tr('Hazard details') hazard_title_keywords = 'hazard_title' hazard_source_keywords = 'hazard_source' exposure_details = tr('Exposure details') exposure_title_keywords = 'exposure_title' exposure_source_keyword = 'exposure_source' if hazard_title_keywords in keywords: # We use safe translation infrastructure for this one (rather than Qt) hazard_title = safeTr(keywords[hazard_title_keywords]) else: hazard_title = tr('Hazard layer') if hazard_source_keywords in keywords: # We use safe translation infrastructure for this one (rather than Qt) hazard_source = safeTr(keywords[hazard_source_keywords]) else: hazard_source = tr('an unknown source') if exposure_title_keywords in keywords: exposure_title = keywords[exposure_title_keywords] else: exposure_title = tr('Exposure layer') if exposure_source_keyword in keywords: exposure_source = keywords[exposure_source_keyword] else: exposure_source = tr('an unknown source') report = m.Message() report.add(m.Heading(hazard_details, **INFO_STYLE)) report.add(m.Paragraph(hazard_title, join_words, hazard_source)) report.add(m.Heading(exposure_details, **INFO_STYLE)) report.add(m.Paragraph(exposure_title, join_words, exposure_source)) if inasafe_flag: report.add(m.Heading(tr('Software notes'), **INFO_STYLE)) # noinspection PyUnresolvedReferences inasafe_phrase = tr( 'This report was created using InaSAFE version %s. Visit ' 'http://inasafe.org to get your free copy of this software!' 'InaSAFE has been jointly developed by BNPB, AusAid/AIFDRR & the ' 'World Bank') % (get_version()) report.add(m.Paragraph(m.Text(inasafe_phrase))) return report
def impact_attribution(keywords, inasafe_flag=False): """Make a little table for attribution of data sources used in impact. :param keywords: A keywords dict for an impact layer. :type keywords: dict :param inasafe_flag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. :returns: An html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. :rtype: str """ if keywords is None: return None myJoinWords = ' - %s ' % tr('sourced from') myHazardDetails = tr('Hazard details') myHazardTitleKeyword = 'hazard_title' myHazardSourceKeyword = 'hazard_source' myExposureDetails = tr('Exposure details') myExposureTitleKeyword = 'exposure_title' myExposureSourceKeyword = 'exposure_source' if myHazardTitleKeyword in keywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardTitle = safeTr(keywords[myHazardTitleKeyword]) else: myHazardTitle = tr('Hazard layer') if myHazardSourceKeyword in keywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardSource = safeTr(keywords[myHazardSourceKeyword]) else: myHazardSource = tr('an unknown source') if myExposureTitleKeyword in keywords: myExposureTitle = keywords[myExposureTitleKeyword] else: myExposureTitle = tr('Exposure layer') if myExposureSourceKeyword in keywords: myExposureSource = keywords[myExposureSourceKeyword] else: myExposureSource = tr('an unknown source') myReport = m.Message() myReport.add(m.Heading(myHazardDetails, **INFO_STYLE)) myReport.add(m.Paragraph(myHazardTitle, myJoinWords, myHazardSource)) myReport.add(m.Heading(myExposureDetails, **INFO_STYLE)) myReport.add(m.Paragraph(myExposureTitle, myJoinWords, myExposureSource)) if inasafe_flag: myReport.add(m.Heading(tr('Software notes'), **INFO_STYLE)) myInaSAFEPhrase = tr( 'This report was created using InaSAFE version %1. Visit ' 'http://inasafe.org to get your free copy of this software!' 'InaSAFE has been jointly developed by BNPB, AusAid/AIFDRR & the ' 'World Bank').arg(get_version()) myReport.add(m.Paragraph(m.Text(myInaSAFEPhrase))) return myReport
def save_scenario(self, scenario_file_path=None): """Save current scenario to a text file. You can use the saved scenario with the batch runner. :param scenario_file_path: A path to the scenario file. :type scenario_file_path: str """ # Validate Input warning_title = self.tr('InaSAFE Save Scenario Warning') is_valid, warning_message = self.validate_input() if not is_valid: # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QtGui.QMessageBox.warning(self, warning_title, warning_message) return # Make extent to look like: # 109.829170982, -8.13333290561, 111.005344795, -7.49226294379 # Added in 2.2 to support user defined analysis extents if self.dock.user_extent is not None \ and self.dock.user_extent_crs is not None: extent = extent_to_array(self.dock.user_extent, self.dock.user_extent_crs) else: extent = viewport_geo_array(self.iface.mapCanvas()) extent_string = ', '.join(('%f' % x) for x in extent) exposure_path = str(self.exposure_layer.publicSource()) hazard_path = str(self.hazard_layer.publicSource()) title = self.keyword_io.read_keywords(self.hazard_layer, 'title') title = safeTr(title) default_filename = title.replace(' ', '_').replace('(', '').replace(')', '') # Popup a dialog to request the filename if scenario_file_path = None dialog_title = self.tr('Save Scenario') if scenario_file_path is None: # noinspection PyCallByClass,PyTypeChecker scenario_file_path = str( QFileDialog.getSaveFileName( self, dialog_title, os.path.join(self.output_directory, default_filename + '.txt'), "Text files (*.txt)")) if scenario_file_path is None or scenario_file_path == '': return self.output_directory = os.path.dirname(scenario_file_path) # Get relative path for each layer relative_exposure_path = self.relative_path(scenario_file_path, exposure_path) relative_hazard_path = self.relative_path(scenario_file_path, hazard_path) # Write to file parser = ConfigParser() parser.add_section(title) parser.set(title, 'exposure', relative_exposure_path) parser.set(title, 'hazard', relative_hazard_path) parser.set(title, 'function', self.function_id) parser.set(title, 'extent', extent_string) parser.set(title, 'extent_crs', self.dock.user_extent_crs.authid()) if self.aggregation_layer is not None: aggregation_path = str(self.aggregation_layer.publicSource()) relative_aggregation_path = self.relative_path( scenario_file_path, aggregation_path) parser.set(title, 'aggregation', relative_aggregation_path) try: parser.write(open(scenario_file_path, 'a')) except IOError: # noinspection PyTypeChecker,PyCallByClass,PyArgumentList QtGui.QMessageBox.warning( self, self.tr('InaSAFE'), self.tr('Failed to save scenario to ' + scenario_file_path)) # Save State self.save_state()
def _generateTables(self): """Parses the postprocessing output as one table per postprocessor. Args: None Returns: str - a string containing the html """ myMessage = m.Message() for proc, results_list in self.postProcessingOutput.iteritems(): self._currentOutputPostprocessor = proc # results_list is for example: # [ # (PyQt4.QtCore.QString(u'Entire area'), OrderedDict([ # (u'Total', {'value': 977536, 'metadata': {}}), # (u'Female population', {'value': 508319, 'metadata': {}}), # (u'Weekly hygiene packs', {'value': 403453, 'metadata': { # 'description': 'Females hygiene packs for weekly use'}}) # ])) #] #sorting using the first indicator of a postprocessor sortedResList = sorted( results_list, key=self._sortNoData, reverse=True) #init table hasNoDataValues = False myTable = m.Table( style_class='table table-condensed table-striped') myTable.caption = self.tr('Detailed %s report') % (safeTr( get_postprocessor_human_name(proc)).lower()) myHeaderRow = m.Row() myHeaderRow.add(str(self.attributeTitle).capitalize()) for calculationName in sortedResList[0][1]: myHeaderRow.add(self.tr(calculationName)) myTable.add(myHeaderRow) for zoneName, calc in sortedResList: myRow = m.Row(zoneName) for _, calculationData in calc.iteritems(): myValue = calculationData['value'] if myValue == self.aggregator.defaults['NO_DATA']: hasNoDataValues = True myValue += ' *' myRow.add(myValue) myTable.add(myRow) # add table to message myMessage.add(myTable) if hasNoDataValues: myMessage.add(m.EmphasizedText(self.tr( '* "%s" values mean that there where some problems while ' 'calculating them. This did not affect the other ' 'values.') % (self.aggregator.defaults['NO_DATA']))) return myMessage
def impactLayerAttribution(theKeywords, theInaSAFEFlag=False): """Make a little table for attribution of data sources used in impact. Args: * theKeywords: dict{} - a keywords dict for an impact layer. * theInaSAFEFlag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. Returns: str: an html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. Raises: None """ if theKeywords is None: return None myReport = '' myJoinWords = ' - %s ' % tr('sourced from') myHazardDetails = tr('Hazard details') myHazardTitleKeyword = 'hazard_title' myHazardSourceKeyword = 'hazard_source' myExposureDetails = tr('Exposure details') myExposureTitleKeyword = 'exposure_title' myExposureSourceKeyword = 'exposure_source' if myHazardTitleKeyword in theKeywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardTitle = safeTr(theKeywords[myHazardTitleKeyword]) else: myHazardTitle = tr('Hazard layer') if myHazardSourceKeyword in theKeywords: # We use safe translation infrastructure for this one (rather than Qt) myHazardSource = safeTr(theKeywords[myHazardSourceKeyword]) else: myHazardSource = tr('an unknown source') if myExposureTitleKeyword in theKeywords: myExposureTitle = theKeywords[myExposureTitleKeyword] else: myExposureTitle = tr('Exposure layer') if myExposureSourceKeyword in theKeywords: myExposureSource = theKeywords[myExposureSourceKeyword] else: myExposureSource = tr('an unknown source') myReport += ('<table class="table table-striped condensed' ' bordered-table">') myReport += '<tr><th>%s</th></tr>' % myHazardDetails myReport += '<tr><td>%s%s %s.</td></tr>' % (myHazardTitle, myJoinWords, myHazardSource) myReport += '<tr><th>%s</th></tr>' % myExposureDetails myReport += '<tr><td>%s%s %s.</td></tr>' % (myExposureTitle, myJoinWords, myExposureSource) if theInaSAFEFlag: myReport += '<tr><th>%s</th></tr>' % tr('Software notes') myInaSAFEPhrase = tr('This report was created using InaSAFE ' 'version %1. Visit http://inasafe.org to get ' 'your free copy of this software!').arg( get_version()) myInaSAFEPhrase += tr('InaSAFE has been jointly developed by' ' BNPB, AusAid & the World Bank') myReport += '<tr><td>%s</td></tr>' % myInaSAFEPhrase myReport += '</table>' return myReport