From 1dfa9b9d884289a8ea34a8cc1ee3fceb69add506 Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Mon, 23 Mar 2015 19:13:25 +0100 Subject: [PATCH 01/22] [#1351] First version of IATI export --- akvo/iati/__init__.py | 0 akvo/iati/elements/__init__.py | 86 + akvo/iati/elements/activity_date.py | 43 + akvo/iati/elements/activity_scope.py | 22 + akvo/iati/elements/activity_status.py | 31 + akvo/iati/elements/background.py | 26 + akvo/iati/elements/budget.py | 50 + akvo/iati/elements/capital_spend.py | 22 + akvo/iati/elements/collaboration_type.py | 22 + akvo/iati/elements/conditions.py | 36 + akvo/iati/elements/contact_info.py | 64 + akvo/iati/elements/country_budget_items.py | 37 + akvo/iati/elements/crs_add.py | 93 + akvo/iati/elements/current_situation.py | 26 + akvo/iati/elements/default_aid_type.py | 22 + akvo/iati/elements/default_finance_type.py | 22 + akvo/iati/elements/default_flow_type.py | 22 + akvo/iati/elements/default_tied_status.py | 22 + akvo/iati/elements/document_link.py | 104 + akvo/iati/elements/fss.py | 51 + akvo/iati/elements/goals_overview.py | 26 + akvo/iati/elements/iati_identifier.py | 22 + akvo/iati/elements/legacy_data.py | 30 + akvo/iati/elements/location.py | 77 + akvo/iati/elements/other_identifier.py | 53 + akvo/iati/elements/participating_org.py | 48 + akvo/iati/elements/planned_disbursement.py | 45 + akvo/iati/elements/policy_marker.py | 34 + akvo/iati/elements/project_plan.py | 26 + akvo/iati/elements/recipient_country.py | 33 + akvo/iati/elements/recipient_region.py | 36 + akvo/iati/elements/related_activity.py | 43 + akvo/iati/elements/reporting_org.py | 39 + akvo/iati/elements/result.py | 102 + akvo/iati/elements/sector.py | 32 + akvo/iati/elements/subtitle.py | 26 + akvo/iati/elements/summary.py | 26 + akvo/iati/elements/sustainability.py | 26 + akvo/iati/elements/target_group.py | 26 + akvo/iati/elements/title.py | 23 + akvo/iati/elements/transaction.py | 132 + akvo/iati/iati_export.py | 96 + akvo/rsr/admin.py | 16 +- akvo/rsr/iati/__init__.py | 1 + akvo/rsr/iati/iati_code_lists.py | 1 - akvo/rsr/iati/iati_file_generator.py | 681 - akvo/rsr/iati/iati_schema.py | 12303 ---------------- ..._add_crsadd__add_crsaddotherflag__del_f.py | 842 ++ akvo/rsr/models/__init__.py | 6 + akvo/rsr/models/budget_item.py | 2 - akvo/rsr/models/crs_add.py | 85 + akvo/rsr/models/fss.py | 49 + akvo/rsr/models/indicator.py | 3 - akvo/rsr/models/project.py | 16 +- akvo/rsr/models/project_condition.py | 1 - akvo/rsr/models/related_project.py | 11 +- akvo/rsr/models/result.py | 3 - akvo/rsr/models/transaction.py | 49 +- 58 files changed, 2841 insertions(+), 13030 deletions(-) create mode 100644 akvo/iati/__init__.py create mode 100644 akvo/iati/elements/__init__.py create mode 100644 akvo/iati/elements/activity_date.py create mode 100644 akvo/iati/elements/activity_scope.py create mode 100644 akvo/iati/elements/activity_status.py create mode 100644 akvo/iati/elements/background.py create mode 100644 akvo/iati/elements/budget.py create mode 100644 akvo/iati/elements/capital_spend.py create mode 100644 akvo/iati/elements/collaboration_type.py create mode 100644 akvo/iati/elements/conditions.py create mode 100644 akvo/iati/elements/contact_info.py create mode 100644 akvo/iati/elements/country_budget_items.py create mode 100644 akvo/iati/elements/crs_add.py create mode 100644 akvo/iati/elements/current_situation.py create mode 100644 akvo/iati/elements/default_aid_type.py create mode 100644 akvo/iati/elements/default_finance_type.py create mode 100644 akvo/iati/elements/default_flow_type.py create mode 100644 akvo/iati/elements/default_tied_status.py create mode 100644 akvo/iati/elements/document_link.py create mode 100644 akvo/iati/elements/fss.py create mode 100644 akvo/iati/elements/goals_overview.py create mode 100644 akvo/iati/elements/iati_identifier.py create mode 100644 akvo/iati/elements/legacy_data.py create mode 100644 akvo/iati/elements/location.py create mode 100644 akvo/iati/elements/other_identifier.py create mode 100644 akvo/iati/elements/participating_org.py create mode 100644 akvo/iati/elements/planned_disbursement.py create mode 100644 akvo/iati/elements/policy_marker.py create mode 100644 akvo/iati/elements/project_plan.py create mode 100644 akvo/iati/elements/recipient_country.py create mode 100644 akvo/iati/elements/recipient_region.py create mode 100644 akvo/iati/elements/related_activity.py create mode 100644 akvo/iati/elements/reporting_org.py create mode 100644 akvo/iati/elements/result.py create mode 100644 akvo/iati/elements/sector.py create mode 100644 akvo/iati/elements/subtitle.py create mode 100644 akvo/iati/elements/summary.py create mode 100644 akvo/iati/elements/sustainability.py create mode 100644 akvo/iati/elements/target_group.py create mode 100644 akvo/iati/elements/title.py create mode 100644 akvo/iati/elements/transaction.py create mode 100644 akvo/iati/iati_export.py delete mode 100644 akvo/rsr/iati/iati_file_generator.py delete mode 100644 akvo/rsr/iati/iati_schema.py create mode 100644 akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py create mode 100644 akvo/rsr/models/crs_add.py create mode 100644 akvo/rsr/models/fss.py diff --git a/akvo/iati/__init__.py b/akvo/iati/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/akvo/iati/elements/__init__.py b/akvo/iati/elements/__init__.py new file mode 100644 index 0000000000..4d808c3366 --- /dev/null +++ b/akvo/iati/elements/__init__.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from .activity_date import activity_date +from .activity_scope import activity_scope +from .activity_status import activity_status +from .background import background +from .budget import budget +from .capital_spend import capital_spend +from .collaboration_type import collaboration_type +from .contact_info import contact_info +from .country_budget_items import country_budget_items +from .conditions import conditions +from .crs_add import crs_add +from .current_situation import current_situation +from .default_aid_type import default_aid_type +from .default_finance_type import default_finance_type +from .default_flow_type import default_flow_type +from .default_tied_status import default_tied_status +from .document_link import document_link +from .fss import fss +from .goals_overview import goals_overview +from .iati_identifier import iati_identifier +from .legacy_data import legacy_data +from .location import location +from .other_identifier import other_identifier +from .participating_org import participating_org +from .planned_disbursement import planned_disbursement +from .policy_marker import policy_marker +from .project_plan import project_plan +from .recipient_country import recipient_country +from .recipient_region import recipient_region +from .related_activity import related_activity +from .reporting_org import reporting_org +from .result import result +from .sector import sector +from .subtitle import subtitle +from .sustainability import sustainability +from .summary import summary +from .target_group import target_group +from .title import title +from .transaction import transaction + +__all__ = [ + 'activity_date', + 'activity_scope', + 'activity_status', + 'background', + 'budget', + 'capital_spend', + 'collaboration_type', + 'conditions', + 'contact_info', + 'country_budget_items', + 'crs_add', + 'current_situation', + 'default_aid_type', + 'default_finance_type', + 'default_flow_type', + 'default_tied_status', + 'document_link', + 'fss', + 'goals_overview', + 'iati_identifier', + 'legacy_data', + 'location', + 'participating_org', + 'planned_disbursement', + 'policy_marker', + 'project_plan', + 'recipient_country', + 'recipient_region', + 'related_activity', + 'reporting_org', + 'result', + 'sector', + 'subtitle', + 'sustainability', + 'summary', + 'target_group', + 'title', + 'transaction', +] diff --git a/akvo/iati/elements/activity_date.py b/akvo/iati/elements/activity_date.py new file mode 100644 index 0000000000..ad3aa082f7 --- /dev/null +++ b/akvo/iati/elements/activity_date.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def activity_date(project): + """ + Generate the activity-date elements. + + :param project: Project object + :return: A list of Etree elements + """ + activity_date_elements = [] + + if project.date_start_planned: + date_start_planned_element = etree.Element("activity-date") + date_start_planned_element.attrib['iso-date'] = str(project.date_start_planned) + date_start_planned_element.attrib['type'] = '1' + activity_date_elements.append(date_start_planned_element) + + if project.date_start_actual: + date_start_actual_element = etree.Element("activity-date") + date_start_actual_element.attrib['iso-date'] = str(project.date_start_actual) + date_start_actual_element.attrib['type'] = '2' + activity_date_elements.append(date_start_actual_element) + + if project.date_end_planned: + date_end_planned_element = etree.Element("activity-date") + date_end_planned_element.attrib['iso-date'] = str(project.date_end_planned) + date_end_planned_element.attrib['type'] = '3' + activity_date_elements.append(date_end_planned_element) + + if project.date_end_actual: + date_end_actual_element = etree.Element("activity-date") + date_end_actual_element.attrib['iso-date'] = str(project.date_end_actual) + date_end_actual_element.attrib['type'] = '4' + activity_date_elements.append(date_end_actual_element) + + return activity_date_elements diff --git a/akvo/iati/elements/activity_scope.py b/akvo/iati/elements/activity_scope.py new file mode 100644 index 0000000000..6f5f7aaab6 --- /dev/null +++ b/akvo/iati/elements/activity_scope.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def activity_scope(project): + """ + Generate the activity-scope element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.project_scope: + element = etree.Element("activity-scope") + element.attrib['code'] = project.project_scope + return [element] + + return [] diff --git a/akvo/iati/elements/activity_status.py b/akvo/iati/elements/activity_status.py new file mode 100644 index 0000000000..f4f51ced84 --- /dev/null +++ b/akvo/iati/elements/activity_status.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + +STATUS_TO_CODE = { + 'N': '6', + 'H': '1', + 'A': '2', + 'C': '3', + 'L': '5', + 'R': '6', +} + + +def activity_status(project): + """ + Generate the activity-status element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.status in STATUS_TO_CODE.keys(): + element = etree.Element("activity-status") + element.attrib['code'] = STATUS_TO_CODE[project.status] + return [element] + + return [] diff --git a/akvo/iati/elements/background.py b/akvo/iati/elements/background.py new file mode 100644 index 0000000000..ff31589402 --- /dev/null +++ b/akvo/iati/elements/background.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def background(project): + """ + Generate the background element, a description element with type "1" and akvo type "6". + + :param project: Project object + :return: A list of Etree elements + """ + if project.background: + element = etree.Element("description") + element.attrib['type'] = '1' + element.attrib['{http://akvo.org/iati-activities}type'] = '6' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.background + return [element] + + return [] diff --git a/akvo/iati/elements/budget.py b/akvo/iati/elements/budget.py new file mode 100644 index 0000000000..3bf9e04d34 --- /dev/null +++ b/akvo/iati/elements/budget.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def budget(project): + """ + Generate the budget elements. + + :param project: Project object + :return: A list of Etree elements + """ + budget_elements = [] + + for budget_item in project.budget_items.all(): + if budget_item.amount: + element = etree.Element("budget") + + if budget_item.type: + element.attrib['type'] = budget_item.type + + if budget_item.period_start: + period_start_element = etree.SubElement(element, "period-start") + period_start_element.attrib['iso-date'] = str(budget_item.period_start) + + if budget_item.period_end: + period_end_element = etree.SubElement(element, "period-end") + period_end_element.attrib['iso-date'] = str(budget_item.period_end) + + value_element = etree.SubElement(element, "value") + value_element.text = str(budget_item.amount) + + if budget_item.value_date: + value_element.attrib['value-date'] = str(budget_item.value_date) + + if budget_item.currency: + value_element.attrib['currency'] = budget_item.currency + + if budget_item.other_extra: + value_element.attrib['{http://akvo.org/iati-activities}label'] = budget_item.other_extra + elif budget_item.label.label: + value_element.attrib['{http://akvo.org/iati-activities}label'] = budget_item.label.label + + budget_elements.append(element) + + return budget_elements diff --git a/akvo/iati/elements/capital_spend.py b/akvo/iati/elements/capital_spend.py new file mode 100644 index 0000000000..53da020f55 --- /dev/null +++ b/akvo/iati/elements/capital_spend.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def capital_spend(project): + """ + Generate the capital-spend element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.capital_spend_percentage: + element = etree.Element("capital-spend") + element.attrib['percentage'] = project.capital_spend_percentage + return [element] + + return [] diff --git a/akvo/iati/elements/collaboration_type.py b/akvo/iati/elements/collaboration_type.py new file mode 100644 index 0000000000..1dd345c947 --- /dev/null +++ b/akvo/iati/elements/collaboration_type.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def collaboration_type(project): + """ + Generate the collaboration-type element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.collaboration_type: + element = etree.Element("collaboration-type") + element.attrib['code'] = project.collaboration_type + return [element] + + return [] diff --git a/akvo/iati/elements/conditions.py b/akvo/iati/elements/conditions.py new file mode 100644 index 0000000000..5d43784b10 --- /dev/null +++ b/akvo/iati/elements/conditions.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def conditions(project): + """ + Generate the conditions element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.conditions.all(): + conditions_element = etree.Element("conditions") + else: + return [] + + if project.conditions_attached is not None: + conditions_element.attrib['attached'] = '1' if project.conditions_attached else '0' + + for condition in project.conditions.all(): + if condition.type: + condition_element = etree.SubElement(conditions_element, "condition") + condition_element.attrib['type'] = condition.type + + if condition.text: + narrative_element = etree.SubElement(condition_element, "narrative") + narrative_element.text = condition.text + + conditions_element.append(condition_element) + + return [conditions_element] diff --git a/akvo/iati/elements/contact_info.py b/akvo/iati/elements/contact_info.py new file mode 100644 index 0000000000..54e900299e --- /dev/null +++ b/akvo/iati/elements/contact_info.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def contact_info(project): + """ + Generate the contact-info elements. + + :param project: Project object + :return: A list of Etree elements + """ + contact_info_elements = [] + + for contact in project.contacts.all(): + element = etree.Element("contact-info") + + if contact.type: + element.attrib['type'] = str(contact.type) + + if contact.organisation: + organisation_element = etree.SubElement(element, "organisation") + narrative_element = etree.SubElement(organisation_element, "narrative") + narrative_element.text = contact.organisation + + if contact.department: + department_element = etree.SubElement(element, "department") + narrative_element = etree.SubElement(department_element, "narrative") + narrative_element.text = contact.department + + if contact.person_name: + person_name_element = etree.SubElement(element, "person-name") + narrative_element = etree.SubElement(person_name_element, "narrative") + narrative_element.text = contact.person_name + + if contact.job_title: + job_title_element = etree.SubElement(element, "job-title") + narrative_element = etree.SubElement(job_title_element, "narrative") + narrative_element.text = contact.job_title + + if contact.telephone: + telephone_element = etree.SubElement(element, "telephone") + telephone_element.text = contact.telephone + + if contact.email: + email_element = etree.SubElement(element, "email") + email_element.text = contact.email + + if contact.website: + website_element = etree.SubElement(element, "website") + website_element.text = contact.website + + if contact.mailing_address: + mailing_address_element = etree.SubElement(element, "mailing-address") + narrative_element = etree.SubElement(mailing_address_element, "narrative") + narrative_element.text = contact.mailing_address + + contact_info_elements.append(element) + + return contact_info_elements diff --git a/akvo/iati/elements/country_budget_items.py b/akvo/iati/elements/country_budget_items.py new file mode 100644 index 0000000000..09145bcb19 --- /dev/null +++ b/akvo/iati/elements/country_budget_items.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def country_budget_items(project): + """ + Generate the country-budget-items element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.country_budget_items.all(): + country_budget_items_element = etree.Element("country-budget-items") + else: + return [] + + if project.country_budget_vocabulary: + country_budget_items_element.attrib['vocabulary'] = project.country_budget_vocabulary + + for budget_item in project.country_budget_items.all(): + if budget_item.code: + element = etree.SubElement(country_budget_items_element, "budget-item") + element.attrib['code'] = budget_item.code + + if budget_item.description: + description_element = etree.SubElement(element, "description") + narrative_element = etree.SubElement(description_element, "narrative") + narrative_element.text = budget_item.description + + country_budget_items_element.append(element) + + return [country_budget_items_element] diff --git a/akvo/iati/elements/crs_add.py b/akvo/iati/elements/crs_add.py new file mode 100644 index 0000000000..16820d2f78 --- /dev/null +++ b/akvo/iati/elements/crs_add.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + +from akvo.rsr.models import CrsAdd + + +def crs_add(project): + """ + Generate the crs-add element. + + :param project: Project object + :return: A list of Etree elements + """ + try: + crs = project.crsadd + except CrsAdd.DoesNotExist: + return [] + + element = etree.Element("crs-add") + + for flag in crs.other_flags.all(): + if flag.code and flag.significance is not None: + other_flag_element = etree.SubElement(element, "other-flags") + other_flag_element.attrib['code'] = flag.code + other_flag_element.attrib['significance'] = '1' if flag.significance else '0' + + element.append(other_flag_element) + + loan_terms_element = etree.SubElement(element, "loan-terms") + + if crs.loan_terms_rate1: + loan_terms_element.attrib['rate-1'] = str(crs.loan_terms_rate1) + + if crs.loan_terms_rate2: + loan_terms_element.attrib['rate-2'] = str(crs.loan_terms_rate2) + + if crs.repayment_type: + repayment_type_element = etree.SubElement(loan_terms_element, "repayment-type") + repayment_type_element.attrib['code'] = crs.repayment_type + + if crs.repayment_plan: + repayment_plan_element = etree.SubElement(loan_terms_element, "repayment-plan") + repayment_plan_element.attrib['code'] = crs.repayment_plan + + if crs.commitment_date: + commitment_date_element = etree.SubElement(loan_terms_element, "commitment-date") + commitment_date_element.attrib['iso-date'] = str(crs.commitment_date) + + if crs.repayment_first_date: + repayment_first_date_element = etree.SubElement(loan_terms_element, "repayment-first-date") + repayment_first_date_element.attrib['iso-date'] = str(crs.repayment_first_date) + + if crs.repayment_final_date: + repayment_final_date_element = etree.SubElement(loan_terms_element, "repayment-final-date") + repayment_final_date_element.attrib['iso-date'] = str(crs.repayment_final_date) + + element.append(loan_terms_element) + + loan_status_element = etree.SubElement(element, "loan-status") + + if crs.loan_status_year: + loan_status_element.attrib['year'] = str(crs.loan_status_year) + + if crs.loan_status_currency: + loan_status_element.attrib['currency'] = crs.loan_status_currency + + if crs.loan_status_value_date: + loan_status_element.attrib['value-date'] = str(crs.loan_status_value_date) + + if crs.interest_received: + interest_received_element = etree.SubElement(loan_status_element, "interest-received") + interest_received_element.text = str(crs.interest_received) + + if crs.principal_outstanding: + principal_outstanding_element = etree.SubElement(loan_status_element, "principal-outstanding") + principal_outstanding_element.text = str(crs.principal_outstanding) + + if crs.principal_arrears: + principal_arrears_element = etree.SubElement(loan_status_element, "principal-arrears") + principal_arrears_element.text = str(crs.principal_arrears) + + if crs.interest_arrears: + interest_arrears_element = etree.SubElement(loan_status_element, "interest-arrears") + interest_arrears_element.text = str(crs.interest_arrears) + + element.append(loan_status_element) + + return [element] diff --git a/akvo/iati/elements/current_situation.py b/akvo/iati/elements/current_situation.py new file mode 100644 index 0000000000..9b4f9e8075 --- /dev/null +++ b/akvo/iati/elements/current_situation.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def current_situation(project): + """ + Generate the current situation element, a description element with type "1" and akvo type "9". + + :param project: Project object + :return: A list of Etree elements + """ + if project.current_status: + element = etree.Element("description") + element.attrib['type'] = '1' + element.attrib['{http://akvo.org/iati-activities}type'] = '9' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.current_status + return [element] + + return [] diff --git a/akvo/iati/elements/default_aid_type.py b/akvo/iati/elements/default_aid_type.py new file mode 100644 index 0000000000..08c1e121b5 --- /dev/null +++ b/akvo/iati/elements/default_aid_type.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def default_aid_type(project): + """ + Generate the default-aid-type element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.default_aid_type: + element = etree.Element("default-aid-type") + element.attrib['code'] = project.default_aid_type + return [element] + + return [] diff --git a/akvo/iati/elements/default_finance_type.py b/akvo/iati/elements/default_finance_type.py new file mode 100644 index 0000000000..28a53bcccb --- /dev/null +++ b/akvo/iati/elements/default_finance_type.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def default_finance_type(project): + """ + Generate the default-finance-type element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.default_finance_type: + element = etree.Element("default-finance-type") + element.attrib['code'] = project.default_finance_type + return [element] + + return [] diff --git a/akvo/iati/elements/default_flow_type.py b/akvo/iati/elements/default_flow_type.py new file mode 100644 index 0000000000..40656f3804 --- /dev/null +++ b/akvo/iati/elements/default_flow_type.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def default_flow_type(project): + """ + Generate the default-flow-type element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.default_flow_type: + element = etree.Element("default-flow-type") + element.attrib['code'] = project.default_flow_type + return [element] + + return [] diff --git a/akvo/iati/elements/default_tied_status.py b/akvo/iati/elements/default_tied_status.py new file mode 100644 index 0000000000..434a911932 --- /dev/null +++ b/akvo/iati/elements/default_tied_status.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def default_tied_status(project): + """ + Generate the default-aid-type element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.default_tied_status: + element = etree.Element("default-tied-status") + element.attrib['code'] = project.default_tied_status + return [element] + + return [] diff --git a/akvo/iati/elements/document_link.py b/akvo/iati/elements/document_link.py new file mode 100644 index 0000000000..a71b0c55ff --- /dev/null +++ b/akvo/iati/elements/document_link.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def document_link(project): + """ + Generate the document-link elements. + + :param project: Project object + :return: A list of Etree elements + """ + document_link_elements = [] + + if project.current_image: + current_image_element = etree.Element("document-link") + current_image_element.attrib['url'] = "http://rsr.akvo.org" + project.current_image.url + current_image_element.attrib['format'] = "image/jpeg" + + if project.current_image_caption or project.current_image_credit: + title_element = etree.SubElement(current_image_element, "title") + narrative_element = etree.SubElement(title_element, "narrative") + if project.current_image_caption and project.current_image_credit: + narrative_element.text = "%s, credit: %s" % ( + project.current_image_caption, + project.current_image_credit + ) + elif project.current_image_caption: + narrative_element.text = project.current_image_caption + elif project.current_image_credit: + narrative_element.text = "Credit: %s" % (project.current_image_credit,) + + category_element = etree.SubElement(current_image_element, "category") + category_element.attrib['code'] = "A12" + + document_link_elements.append(current_image_element) + + for link in project.links.all(): + if link.url: + link_element = etree.Element("document-link") + link_element.attrib['url'] = link.url + link_element.attrib['format'] = "application/http" + + if link.caption: + title_element = etree.SubElement(link_element, "title") + narrative_element = etree.SubElement(title_element, "narrative") + narrative_element.text = link.caption + + category_element = etree.SubElement(link_element, "category") + category_element.attrib['code'] = "A12" + + document_link_elements.append(link_element) + + for document in project.documents.all(): + if document.url or document.document: + document_element = etree.Element("document-link") + + if document.url: + document_element.attrib['url'] = document.url + elif document.document: + document_element.attrib['url'] = "http://rsr.akvo.org" + document.document.url + + if document.format: + document_element.attrib['format'] = document.format + + if document.title: + title_element = etree.SubElement(document_element, "title") + narrative_element = etree.SubElement(title_element, "narrative") + narrative_element.text = document.title + + if document.category: + category_element = etree.SubElement(document_element, "category") + category_element.attrib['code'] = document.category + + if document.language: + language_element = etree.SubElement(document_element, "language") + language_element.attrib['code'] = document.language + + document_link_elements.append(document_element) + + for update in project.project_updates.all(): + update_element = etree.Element("document-link") + update_element.attrib['url'] = "http://rsr.akvo.org/project/%s/update/%s/" % (str(project.pk), str(update.pk)) + update_element.attrib['format'] = "application/http" + + if update.title: + title_element = etree.SubElement(update_element, "title") + narrative_element = etree.SubElement(title_element, "narrative") + narrative_element.text = update.title + + category_element = etree.SubElement(update_element, "category") + category_element.attrib['code'] = "A12" + + if update.language: + language_element = etree.SubElement(update_element, "language") + language_element.attrib['code'] = update.language + + document_link_elements.append(update_element) + + return document_link_elements diff --git a/akvo/iati/elements/fss.py b/akvo/iati/elements/fss.py new file mode 100644 index 0000000000..1a86b4719c --- /dev/null +++ b/akvo/iati/elements/fss.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + +from akvo.rsr.models import Fss + + +def fss(project): + """ + Generate the fss element. + + :param project: Project object + :return: A list of Etree elements + """ + try: + fss_object = project.fss + except Fss.DoesNotExist: + return [] + + element = etree.Element("fss") + + if fss_object.extraction_date: + element.attrib['extraction-date'] = str(fss_object.extraction_date) + + if fss_object.priority is not None: + element.attrib['priority'] = '1' if fss_object.priority else '0' + + if fss_object.phaseout_year: + element.attrib['phaseout-year'] = str(fss_object.phaseout_year) + + for forecast in fss_object.forecasts.all(): + if forecast.value: + forecast_element = etree.SubElement(element, "forecast") + forecast_element.text = str(forecast.value) + + if forecast.year: + forecast_element.attrib['year'] = str(forecast.year) + + if forecast.value_date: + forecast_element.attrib['value-date'] = str(forecast.value_date) + + if forecast.currency: + forecast_element.attrib['currency'] = str(forecast.currency) + + element.append(forecast_element) + + return [element] diff --git a/akvo/iati/elements/goals_overview.py b/akvo/iati/elements/goals_overview.py new file mode 100644 index 0000000000..af53ddeb55 --- /dev/null +++ b/akvo/iati/elements/goals_overview.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def goals_overview(project): + """ + Generate the goals overview element, a description element with type "2" and akvo type "8". + + :param project: Project object + :return: A list of Etree elements + """ + if project.goals_overview: + element = etree.Element("description") + element.attrib['type'] = '2' + element.attrib['{http://akvo.org/iati-activities}type'] = '8' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.goals_overview + return [element] + + return [] diff --git a/akvo/iati/elements/iati_identifier.py b/akvo/iati/elements/iati_identifier.py new file mode 100644 index 0000000000..9666620b89 --- /dev/null +++ b/akvo/iati/elements/iati_identifier.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def iati_identifier(project): + """ + Generate the iati-identifier element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.iati_activity_id: + element = etree.Element("iati-identifier") + element.text = project.iati_activity_id + return [element] + + return [] diff --git a/akvo/iati/elements/legacy_data.py b/akvo/iati/elements/legacy_data.py new file mode 100644 index 0000000000..0e69acc6e6 --- /dev/null +++ b/akvo/iati/elements/legacy_data.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def legacy_data(project): + """ + Generate the legacy-data element. + + :param project: Project object + :return: A list of Etree elements + """ + legacy_data_elements = [] + + for legacy in project.legacy_data.all(): + if legacy.name and legacy.value: + element = etree.Element("legacy-data") + element.attrib['name'] = legacy.name + element.attrib['value'] = legacy.value + + if legacy.iati_equivalent: + element.attrib['iati-equivalent'] = legacy.iati_equivalent + + legacy_data_elements.append(element) + + return legacy_data_elements diff --git a/akvo/iati/elements/location.py b/akvo/iati/elements/location.py new file mode 100644 index 0000000000..8b3c4208ae --- /dev/null +++ b/akvo/iati/elements/location.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def location(project): + """ + Generate the location elements. + + :param project: Project object + :return: A list of Etree elements + """ + location_elements = [] + + for loc in project.locations.all(): + element = etree.Element("location") + + if loc.reference: + element.attrib['ref'] = loc.reference + + if loc.location_reach: + reach_element = etree.SubElement(element, "location-reach") + reach_element.attrib['code'] = loc.location_reach + + if loc.location_code and loc.vocabulary: + id_element = etree.SubElement(element, "location-id") + id_element.attrib['vocabulary'] = loc.vocabulary + id_element.attrib['code'] = loc.location_code + + if loc.name: + name_element = etree.SubElement(element, "name") + narrative_element = etree.SubElement(name_element, "narrative") + narrative_element.text = loc.name + + if loc.description: + description_element = etree.SubElement(element, "description") + narrative_element = etree.SubElement(description_element, "narrative") + narrative_element.text = loc.description + + if loc.activity_description: + activity_description_element = etree.SubElement(element, "activity-description") + narrative_element = etree.SubElement(activity_description_element, "narrative") + narrative_element.text = loc.activity_description + + if loc.administrative_code and loc.administrative_vocabulary: + administrative_element = etree.SubElement(element, "administrative") + administrative_element.attrib['vocabulary'] = loc.administrative_vocabulary + administrative_element.attrib['code'] = loc.administrative_code + + if loc.administrative_level: + administrative_element.attrib['level'] = str(loc.administrative_code) + + if loc.latitude and loc.longitude: + point_element = etree.SubElement(element, "point") + point_element.attrib['srsName'] = 'http://www.opengis.net/def/crs/EPSG/0/4326' + pos_element = etree.SubElement(point_element, "pos") + pos_element.text = "%s %s" % (str(loc.latitude), str(loc.longitude)) + + if loc.exactness: + exactness_element = etree.SubElement(element, "exactness") + exactness_element.attrib['code'] = str(loc.exactness) + + if loc.location_class: + class_element = etree.SubElement(element, "location-class") + class_element.attrib['code'] = str(loc.location_class) + + if loc.feature_designation: + feature_element = etree.SubElement(element, "feature-designation") + feature_element.attrib['code'] = str(loc.feature_designation) + + location_elements.append(element) + + return location_elements diff --git a/akvo/iati/elements/other_identifier.py b/akvo/iati/elements/other_identifier.py new file mode 100644 index 0000000000..bbad59c9a1 --- /dev/null +++ b/akvo/iati/elements/other_identifier.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def other_identifier(project): + """ + Generate the other-identifier elements. + + :param project: Project object + :return: A list of Etree elements + """ + other_identifier_elements = [] + + element = etree.Element("other-identifier") + element.attrib['ref'] = str(project.pk) + element.attrib['type'] = 'B9' + + owner_org_element = etree.SubElement(element, "owner-org") + owner_org_element.attrib['ref'] = 'NL-KVK-27327087' + + narrative_element = etree.SubElement(owner_org_element, "narrative") + narrative_element.text = 'Akvo Foundation' + + other_identifier_elements.append(element) + + for partnership in project.partnerships.all(): + org = partnership.organisation + + if partnership.internal_id: + element = etree.Element("other-identifier") + element.attrib['ref'] = str(partnership.internal_id) + element.attrib['type'] = 'A1' if org == project.sync_owner else 'B9' + + owner_org_element = etree.SubElement(element, "owner-org") + + if org.iati_org_id: + owner_org_element.attrib['ref'] = org.iati_org_id + + narrative_element = etree.SubElement(owner_org_element, "narrative") + + if org.long_name: + narrative_element.text = org.long_name + elif org.name: + narrative_element.text = org.name + + other_identifier_elements.append(element) + + return other_identifier_elements diff --git a/akvo/iati/elements/participating_org.py b/akvo/iati/elements/participating_org.py new file mode 100644 index 0000000000..925320726f --- /dev/null +++ b/akvo/iati/elements/participating_org.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + +TYPE_TO_CODE = { + 'funding': '1', + 'support': '2', + 'sponsor': '3', + 'field': '4', +} + + +def participating_org(project): + """ + Generate the participating-org element. + + :param project: Project object + :return: A list of Etree elements + """ + partnership_elements = [] + + for partnership in project.partnerships.all(): + org = partnership.organisation + element = etree.Element("participating-org") + + if org.iati_org_id: + element.attrib['ref'] = org.iati_org_id + + if org.new_organisation_type: + element.attrib['type'] = str(org.new_organisation_type) + + if partnership.partner_type in TYPE_TO_CODE.keys(): + element.attrib['role'] = TYPE_TO_CODE[partnership.partner_type] + + narrative_element = etree.SubElement(element, "narrative") + + if org.long_name: + narrative_element.text = org.long_name + elif org.name: + narrative_element.text = org.name + + partnership_elements.append(element) + + return partnership_elements diff --git a/akvo/iati/elements/planned_disbursement.py b/akvo/iati/elements/planned_disbursement.py new file mode 100644 index 0000000000..5955556eb5 --- /dev/null +++ b/akvo/iati/elements/planned_disbursement.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def planned_disbursement(project): + """ + Generate the planned-disbursement elements. + + :param project: Project object + :return: A list of Etree elements + """ + planned_disbursement_elements = [] + + for planned_disbursement in project.planned_disbursements.all(): + if planned_disbursement.value: + element = etree.Element("planned-disbursement") + + if planned_disbursement.type: + element.attrib['type'] = planned_disbursement.type + + if planned_disbursement.period_start: + period_start_element = etree.SubElement(element, "period-start") + period_start_element.attrib['iso-date'] = str(planned_disbursement.period_start) + + if planned_disbursement.period_end: + period_end_element = etree.SubElement(element, "period-end") + period_end_element.attrib['iso-date'] = str(planned_disbursement.period_end) + + value_element = etree.SubElement(element, "value") + value_element.text = str(planned_disbursement.value) + + if planned_disbursement.value_date: + value_element.attrib['value-date'] = str(planned_disbursement.value_date) + + if planned_disbursement.currency: + value_element.attrib['currency'] = planned_disbursement.currency + + planned_disbursement_elements.append(element) + + return planned_disbursement_elements diff --git a/akvo/iati/elements/policy_marker.py b/akvo/iati/elements/policy_marker.py new file mode 100644 index 0000000000..faf553cc80 --- /dev/null +++ b/akvo/iati/elements/policy_marker.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def policy_marker(project): + """ + Generate the policy-marker element. + + :param project: Project object + :return: A list of Etree elements + """ + policy_marker_elements = [] + + for policy in project.policy_markers.all(): + if policy.policy_marker and policy.significance: + element = etree.Element("policy-marker") + element.attrib['code'] = policy.policy_marker + element.attrib['significance'] = policy.significance + + if policy.vocabulary: + element.attrib['vocabulary'] = policy.vocabulary + + if policy.description: + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = policy.description + + policy_marker_elements.append(element) + + return policy_marker_elements diff --git a/akvo/iati/elements/project_plan.py b/akvo/iati/elements/project_plan.py new file mode 100644 index 0000000000..afce1a0aba --- /dev/null +++ b/akvo/iati/elements/project_plan.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def project_plan(project): + """ + Generate the project plan element, a description element with type "1" and akvo type "7". + + :param project: Project object + :return: A list of Etree elements + """ + if project.project_plan: + element = etree.Element("description") + element.attrib['type'] = '1' + element.attrib['{http://akvo.org/iati-activities}type'] = '7' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.project_plan + return [element] + + return [] diff --git a/akvo/iati/elements/recipient_country.py b/akvo/iati/elements/recipient_country.py new file mode 100644 index 0000000000..b9baa9671a --- /dev/null +++ b/akvo/iati/elements/recipient_country.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def recipient_country(project): + """ + Generate the recipient-country element. + + :param project: Project object + :return: A list of Etree elements + """ + recipient_country_elements = [] + + for country in project.recipient_countries.all(): + if country.country: + element = etree.Element("recipient-country") + element.attrib['code'] = country.country + + if country.percentage: + element.attrib['percentage'] = str(country.percentage) + + if country.text: + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = country.text + + recipient_country_elements.append(element) + + return recipient_country_elements diff --git a/akvo/iati/elements/recipient_region.py b/akvo/iati/elements/recipient_region.py new file mode 100644 index 0000000000..bda1134d13 --- /dev/null +++ b/akvo/iati/elements/recipient_region.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def recipient_region(project): + """ + Generate the recipient-region element. + + :param project: Project object + :return: A list of Etree elements + """ + recipient_region_elements = [] + + for region in project.recipient_regions.all(): + if region.region: + element = etree.Element("recipient-region") + element.attrib['code'] = region.region + + if region.percentage: + element.attrib['percentage'] = str(region.percentage) + + if region.region_vocabulary: + element.attrib['vocabulary'] = str(region.region_vocabulary) + + if region.text: + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = region.text + + recipient_region_elements.append(element) + + return recipient_region_elements diff --git a/akvo/iati/elements/related_activity.py b/akvo/iati/elements/related_activity.py new file mode 100644 index 0000000000..bea90a3e68 --- /dev/null +++ b/akvo/iati/elements/related_activity.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def related_activity(project): + """ + Generate the related-activity elements. + + :param project: Project object + :return: A list of Etree elements + """ + related_activity_elements = [] + + for related_project in project.related_projects.all(): + if related_project.related_project and related_project.relation: + if related_project.related_project.iati_activity_id: + element = etree.Element("related-activity") + element.attrib['ref'] = related_project.related_project.iati_activity_id + element.attrib['type'] = related_project.relation + + related_activity_elements.append(element) + + elif related_project.related_iati_id and related_project.relation: + element = etree.Element("related-activity") + element.attrib['ref'] = related_project.related_iati_id + element.attrib['type'] = related_project.relation + + related_activity_elements.append(element) + + for related_to_project in project.related_to_projects.all(): + if related_to_project.project.iati_activity_id and related_to_project.relation: + element = etree.Element("related-activity") + element.attrib['ref'] = related_to_project.project.iati_activity_id + element.attrib['type'] = related_to_project.relation + + related_activity_elements.append(element) + + return related_activity_elements diff --git a/akvo/iati/elements/reporting_org.py b/akvo/iati/elements/reporting_org.py new file mode 100644 index 0000000000..cf148b57cc --- /dev/null +++ b/akvo/iati/elements/reporting_org.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def reporting_org(project): + """ + Generate the reporting-org element. + + :param project: Project object + :return: A list of Etree elements + """ + org = project.sync_owner + if org: + element = etree.Element("reporting-org") + + if org.iati_org_id: + element.attrib['ref'] = org.iati_org_id + + if project.sync_owner_secondary_reporter is not None: + element.attrib['secondary_reporter'] = '1' if project.sync_owner_secondary_reporter else '0' + + if org.new_organisation_type: + element.attrib['type'] = str(org.new_organisation_type) + + narrative_element = etree.SubElement(element, "narrative") + + if org.long_name: + narrative_element.text = org.long_name + elif org.name: + narrative_element.text = org.name + + return [element] + + return [] diff --git a/akvo/iati/elements/result.py b/akvo/iati/elements/result.py new file mode 100644 index 0000000000..7e3031de76 --- /dev/null +++ b/akvo/iati/elements/result.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def result(project): + """ + Generate the result elements. + + :param project: Project object + :return: A list of Etree elements + """ + result_elements = [] + + for res in project.results.all(): + element = etree.Element("result") + + if res.type: + element.attrib['type'] = res.type + + if res.aggregation_status is not None: + element.attrib['aggregation-status'] = '1' if res.aggregation_status else '0' + + if res.title: + title_element = etree.SubElement(element, "title") + narrative_element = etree.SubElement(title_element, "narrative") + narrative_element.text = res.title + + if res.description: + description_element = etree.SubElement(element, "description") + narrative_element = etree.SubElement(description_element, "narrative") + narrative_element.text = res.description + + for indicator in res.indicators.all(): + indicator_element = etree.SubElement(element, "indicator") + + if indicator.measure: + indicator_element.attrib['measure'] = indicator.measure + + if indicator.ascending is not None: + indicator_element.attrib['ascending'] = '1' if indicator.ascending else '0' + + if indicator.title: + title_element = etree.SubElement(indicator_element, "title") + narrative_element = etree.SubElement(title_element, "narrative") + narrative_element.text = indicator.title + + if indicator.description: + description_element = etree.SubElement(indicator_element, "description") + narrative_element = etree.SubElement(description_element, "narrative") + narrative_element.text = res.description + + if indicator.baseline_year and indicator.baseline_value: + baseline_element = etree.SubElement(indicator_element, "baseline") + baseline_element.attrib['year'] = str(indicator.baseline_year) + baseline_element.attrib['value'] = indicator.baseline_value + + if indicator.baseline_comment: + comment_element = etree.SubElement(indicator_element, "comment") + narrative_element = etree.SubElement(comment_element, "narrative") + narrative_element.text = indicator.baseline_comment + + for period in indicator.periods.all(): + period_element = etree.SubElement(indicator_element, "period") + + if period.period_start: + period_start_element = etree.SubElement(period_element, "period-start") + period_start_element.attrib['iso-date'] = str(period.period_start) + + if period.period_end: + period_end_element = etree.SubElement(period_element, "period-end") + period_end_element.attrib['iso-date'] = str(period.period_end) + + if period.target_value: + target_element = etree.SubElement(period_element, "target") + target_element.attrib['value'] = period.target_value + + if period.target_comment: + comment_element = etree.SubElement(target_element, "comment") + narrative_element = etree.SubElement(comment_element, "narrative") + narrative_element.text = period.target_comment + + if period.actual_value: + actual_element = etree.SubElement(period_element, "actual") + actual_element.attrib['value'] = period.actual_value + + if period.actual_comment: + comment_element = etree.SubElement(actual_element, "comment") + narrative_element = etree.SubElement(comment_element, "narrative") + narrative_element.text = period.actual_comment + + indicator_element.append(period_element) + + element.append(indicator_element) + + result_elements.append(element) + + return result_elements diff --git a/akvo/iati/elements/sector.py b/akvo/iati/elements/sector.py new file mode 100644 index 0000000000..1d22e11da2 --- /dev/null +++ b/akvo/iati/elements/sector.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def sector(project): + """ + Generate the sector elements. + + :param project: Project object + :return: A list of Etree elements + """ + sector_elements = [] + + for sec in project.sectors.all(): + if sec.sector_code: + element = etree.Element("sector") + element.attrib['code'] = sec.sector_code + + if sec.vocabulary: + element.attrib['vocabulary'] = sec.vocabulary + + if sec.percentage: + element.attrib['percentage'] = str(sec.percentage) + + sector_elements.append(element) + + return sector_elements diff --git a/akvo/iati/elements/subtitle.py b/akvo/iati/elements/subtitle.py new file mode 100644 index 0000000000..de05017c90 --- /dev/null +++ b/akvo/iati/elements/subtitle.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def subtitle(project): + """ + Generate the subtitle element, a description element with type "1" and akvo type "4". + + :param project: Project object + :return: A list of Etree elements + """ + if project.subtitle: + element = etree.Element("description") + element.attrib['type'] = '1' + element.attrib['{http://akvo.org/iati-activities}type'] = '4' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.subtitle + return [element] + + return [] diff --git a/akvo/iati/elements/summary.py b/akvo/iati/elements/summary.py new file mode 100644 index 0000000000..bd894d8c6f --- /dev/null +++ b/akvo/iati/elements/summary.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def summary(project): + """ + Generate the summary element, a description element with type "1" and akvo type "5". + + :param project: Project object + :return: A list of Etree elements + """ + if project.project_plan_summary: + element = etree.Element("description") + element.attrib['type'] = '1' + element.attrib['{http://akvo.org/iati-activities}type'] = '5' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.project_plan_summary + return [element] + + return [] diff --git a/akvo/iati/elements/sustainability.py b/akvo/iati/elements/sustainability.py new file mode 100644 index 0000000000..c19caaa3c9 --- /dev/null +++ b/akvo/iati/elements/sustainability.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def sustainability(project): + """ + Generate the sustainability element, a description element with type "1" and akvo type "10". + + :param project: Project object + :return: A list of Etree elements + """ + if project.sustainability: + element = etree.Element("description") + element.attrib['type'] = '1' + element.attrib['{http://akvo.org/iati-activities}type'] = '10' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.sustainability + return [element] + + return [] diff --git a/akvo/iati/elements/target_group.py b/akvo/iati/elements/target_group.py new file mode 100644 index 0000000000..9f7438a90a --- /dev/null +++ b/akvo/iati/elements/target_group.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def target_group(project): + """ + Generate the target group element, a description element with type "3" and akvo type "3". + + :param project: Project object + :return: A list of Etree elements + """ + if project.target_group: + element = etree.Element("description") + element.attrib['type'] = '3' + element.attrib['{http://akvo.org/iati-activities}type'] = '3' + + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.target_group + return [element] + + return [] diff --git a/akvo/iati/elements/title.py b/akvo/iati/elements/title.py new file mode 100644 index 0000000000..18b90ed5e0 --- /dev/null +++ b/akvo/iati/elements/title.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def title(project): + """ + Generate the title element. + + :param project: Project object + :return: A list of Etree elements + """ + if project.title: + element = etree.Element("title") + narrative_element = etree.SubElement(element, "narrative") + narrative_element.text = project.title + return [element] + + return [] diff --git a/akvo/iati/elements/transaction.py b/akvo/iati/elements/transaction.py new file mode 100644 index 0000000000..f56bcf44c8 --- /dev/null +++ b/akvo/iati/elements/transaction.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from lxml import etree + + +def transaction(project): + """ + Generate the transaction elements. + + :param project: Project object + :return: A list of Etree elements + """ + + transaction_elements = [] + + for trans in project.transactions.all(): + element = etree.Element("transaction") + + if trans.reference: + element.attrib['ref'] = trans.reference + + if trans.transaction_type: + type_element = etree.SubElement(element, "transaction-type") + type_element.attrib['code'] = trans.transaction_type + + if trans.transaction_date: + date_element = etree.SubElement(element, "transaction-date") + date_element.attrib['iso-date'] = str(trans.transaction_date) + + if trans.value: + value_element = etree.SubElement(element, "value") + value_element.text = str(trans.value) + + if trans.currency: + value_element.attrib['currency'] = trans.currency + + if trans.value_date: + value_element.attrib['value-date'] = str(trans.value_date) + + if trans.description: + description_element = etree.SubElement(element, "description") + narrative_element = etree.SubElement(description_element, "narrative") + narrative_element.text = trans.description + + if trans.provider_organisation: + org = trans.provider_organisation + provider_org_element = etree.SubElement(element, "provider-org") + + if trans.provider_organisation_activity: + provider_org_element.attrib['provider-activity-id'] = trans.provider_organisation_activity + + if org.iati_org_id: + provider_org_element.attrib['ref'] = org.iati_org_id + + if org.long_name: + narrative_element = etree.SubElement(provider_org_element, "narrative") + narrative_element.text = org.long_name + elif org.name: + narrative_element = etree.SubElement(provider_org_element, "narrative") + narrative_element.text = org.name + + if trans.receiver_organisation: + org = trans.receiver_organisation + receiver_org_element = etree.SubElement(element, "receiver-org") + + if trans.receiver_organisation_activity: + receiver_org_element.attrib['receiver-activity-id'] = trans.receiver_organisation_activity + + if org.iati_org_id: + receiver_org_element.attrib['ref'] = org.iati_org_id + + if org.long_name: + narrative_element = etree.SubElement(receiver_org_element, "narrative") + narrative_element.text = org.long_name + elif org.name: + narrative_element = etree.SubElement(receiver_org_element, "narrative") + narrative_element.text = org.name + + if trans.disbursement_channel: + disbursement_channel_element = etree.SubElement(element, "disbursement-channel") + disbursement_channel_element.attrib['code'] = trans.disbursement_channel + + if trans.sector: + sector_element = etree.SubElement(element, "sector") + sector_element.attrib['code'] = trans.sector + sector_element.attrib['vocabulary'] = '1' + + if trans.sector_category: + sector_category_element = etree.SubElement(element, "sector") + sector_category_element.attrib['code'] = trans.sector_category + sector_category_element.attrib['vocabulary'] = '2' + + if trans.sector_other: + sector_other_element = etree.SubElement(element, "sector") + sector_other_element.attrib['vocabulary'] = '99' + narrative_element = etree.SubElement(sector_other_element, "narrative") + narrative_element.text = trans.sector_other + + if trans.recipient_country: + recipient_country_element = etree.SubElement(element, "recipient-country") + recipient_country_element.attrib['code'] = trans.recipient_country + + if trans.recipient_region: + recipient_region_element = etree.SubElement(element, "recipient-region") + recipient_region_element.attrib['code'] = trans.recipient_region + + if trans.recipient_region_vocabulary: + recipient_region_element.attrib['vocabulary'] = trans.recipient_region_vocabulary + + if trans.flow_type: + flow_type_element = etree.SubElement(element, "flow-type") + flow_type_element.attrib['code'] = trans.flow_type + + if trans.finance_type: + finance_type_element = etree.SubElement(element, "finance-type") + finance_type_element.attrib['code'] = trans.finance_type + + if trans.aid_type: + aid_type_element = etree.SubElement(element, "aid-type") + aid_type_element.attrib['code'] = trans.aid_type + + if trans.tied_status: + tied_status_element = etree.SubElement(element, "tied-status") + tied_status_element.attrib['code'] = trans.tied_status + + transaction_elements.append(element) + + return transaction_elements diff --git a/akvo/iati/iati_export.py b/akvo/iati/iati_export.py new file mode 100644 index 0000000000..9c282f962a --- /dev/null +++ b/akvo/iati/iati_export.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +import elements + +from datetime import datetime +from lxml import etree + +ELEMENTS = [ + 'iati_identifier', + 'reporting_org', + 'title', + 'subtitle', + 'summary', + 'background', + 'project_plan', + 'current_situation', + 'sustainability', + 'goals_overview', + 'target_group', + 'participating_org', + 'other_identifier', + 'activity_status', + 'activity_date', + 'contact_info', + 'activity_scope', + 'recipient_country', + 'recipient_region', + 'location', + 'sector', + 'country_budget_items', + 'policy_marker', + 'collaboration_type', + 'default_flow_type', + 'default_finance_type', + 'default_aid_type', + 'default_tied_status', + 'budget', + 'planned_disbursement', + 'capital_spend', + 'transaction', + 'document_link', + 'related_activity', + 'legacy_data', + 'conditions', + 'result', + 'crs_add', + 'fss', +] + + +class IatiXML(object): + def print_file(self, file_path): + """ + Export the etree to a file. + + :param file_path: String of the file location + :return: File object + """ + f = open(file_path, 'w') + f.write(etree.tostring(self.iati_activities, pretty_print=True)) + f.close() + print "Done." + return f + + def add_project(self, project): + """ + Adds a project to the IATI XML. + + :param project: Project object + """ + project_element = etree.SubElement(self.iati_activities, "iati-activity") + for element in ELEMENTS: + tree_elements = getattr(elements, element)(project) + for tree_element in tree_elements: + project_element.append(tree_element) + + def __init__(self, projects, version='2.01', excluded_elements=None): + """ + Initialise the IATI XML object, creating a 'iati-activities' etree Element as root. + + :param projects: QuerySet of Projects + :param version: String of IATI version + :param excluded_elements: List of fieldnames that should be ignored when exporting + """ + self.projects, self.version, self.excluded_elements = projects, version, excluded_elements + + self.iati_activities = etree.Element("iati-activities", nsmap={'akvo': 'http://akvo.org/iati-activities'}) + self.iati_activities.attrib['version'] = self.version + self.iati_activities.attrib['generated-datetime'] = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") + + for project in projects: + self.add_project(project) diff --git a/akvo/rsr/admin.py b/akvo/rsr/admin.py index ff85c480e5..e9a9e24deb 100644 --- a/akvo/rsr/admin.py +++ b/akvo/rsr/admin.py @@ -361,7 +361,7 @@ class CountryBudgetInline(NestedTabularInline): fieldsets = ( ('Country Budget Item', { 'classes': ('collapse',), - 'fields': ('code', 'description', 'vocabulary', 'percentage') + 'fields': ('code', 'description', 'percentage') }), ) @@ -430,7 +430,7 @@ class ProjectConditionInline(NestedTabularInline): fieldsets = ( ('Project Condition', { 'classes': ('collapse',), - 'fields': ('type', 'text', 'attached') + 'fields': ('type', 'text') }), ) @@ -496,10 +496,10 @@ class TransactionInline(NestedStackedInline): }), ('IATI fields (advanced)', { 'classes': ('collapse',), - 'fields': ('currency', 'value_date', 'transaction_type_text', 'provider_organisation', - 'provider_organisation_activity', 'receiver_organisation', 'receiver_organisation_activity', - 'aid_type', 'aid_type_text', 'disbursement_channel', 'disbursement_channel_text', 'finance_type', - 'finance_type_text', 'flow_type', 'flow_type_text', 'tied_status', 'tied_status_text', ) + 'fields': ('currency', 'value_date', 'provider_organisation', 'provider_organisation_activity', + 'receiver_organisation', 'receiver_organisation_activity', 'aid_type', 'disbursement_channel', + 'finance_type', 'flow_type', 'tied_status', 'recipient_country', 'recipient_region', + 'recipient_region_vocabulary', 'sector', 'sector_category', 'sector_other') }), ) @@ -556,7 +556,7 @@ class ProjectAdmin(TimestampsAdminDisplayMixin, ObjectPermissionsModelAdmin, Nes u'Optionally, you can add default information based on the IATI standard.' ), 'fields': ('default_aid_type', 'default_flow_type', 'default_tied_status','collaboration_type', - 'default_finance_type'), + 'default_finance_type', 'country_budget_vocabulary'), }), (_(u'Contact Information'), { 'description': u'

%s

' % _( @@ -676,7 +676,7 @@ class ProjectAdmin(TimestampsAdminDisplayMixin, ObjectPermissionsModelAdmin, Nes 'description': u'

%s

' % _( u'Optionally, you can add additional information based on the IATI standard.' ), - 'fields': (), + 'fields': ('conditions_attached',), }), (_(u'Keywords'), { 'description': u'

%s

' % _( diff --git a/akvo/rsr/iati/__init__.py b/akvo/rsr/iati/__init__.py index e69de29bb2..3272c19acd 100644 --- a/akvo/rsr/iati/__init__.py +++ b/akvo/rsr/iati/__init__.py @@ -0,0 +1 @@ +__author__ = 'Kasper' diff --git a/akvo/rsr/iati/iati_code_lists.py b/akvo/rsr/iati/iati_code_lists.py index 3f9a697449..4b1502459f 100644 --- a/akvo/rsr/iati/iati_code_lists.py +++ b/akvo/rsr/iati/iati_code_lists.py @@ -286,4 +286,3 @@ (99810, u'Sectors not specified', u'Contributions to general development of the recipient should be included under programme assistance (51010).', 998, u'UNALLOCATED/ UNSPECIFIED', u''), (99820, u'Promotion of development awareness', u'Spending in donor country for heightened awareness/interest in development co-operation (brochures, lectures, special research projects, etc.).', 998, u'UNALLOCATED/ UNSPECIFIED', u'') ) - diff --git a/akvo/rsr/iati/iati_file_generator.py b/akvo/rsr/iati/iati_file_generator.py deleted file mode 100644 index c0e754ea26..0000000000 --- a/akvo/rsr/iati/iati_file_generator.py +++ /dev/null @@ -1,681 +0,0 @@ -# -*- coding: utf-8 -*- -#!/usr/bin/env python - -""" -Script for generating an IATI file of an organisation, taking an organisation as input with -the possibility to select partner types and exclude individual projects. -""" - -import os -os.environ['DJANGO_SETTINGS_MODULE'] = 'akvo.settings' - -from datetime import datetime -from akvo.rsr.iati.iati_code_lists import IATI_LIST_ACTIVITY_STATUS, IATI_LIST_ORGANISATION_ROLE, IATI_LIST_SECTOR -from akvo.rsr.models import (Project, Organisation, Partnership, Goal, ProjectLocation, Country, BudgetItem, - BudgetItemLabel, InternalOrganisationID, Link, Benchmark, Benchmarkname, Category) - -import sys, argparse, os.path, cgi -import akvo.rsr.iati.iati_schema as schema - - -class MandatoryError(Exception): - """Exception raised for mandatory field errors in a project. - - Attributes: - title -- Project title - project_id -- Project id - node -- Node or information that is missing - """ - - def __init__(self, title, project_id, node): - self.msg = "Error on project '%s' (id: %s); Mandatory information on '%s' is missing..." % \ - (title, project_id, node) - -def check_mandatory_fields(project, fields): - """Checks whether the fields in the fields dict are not NULL. Raises a MandatoryError if so.""" - - for field_key in fields: - if fields[field_key] == "" or fields[field_key] is None: - raise MandatoryError(project.title, project.pk, field_key) - -def check_value(value): - if value == "" or value is None: - return False - else: - return True - -def xml_enc(string): - return cgi.escape(string, True).encode('utf-8') - -def sector_mapping(category_id): - """Returns a IATI sector based on the RSR category.""" - - MAPPING = { - 1: 140, - 2: 140, - 4: 14081, - 5: 111, - 10: 22040, - 11: 22040, - 12: 32130, - 13: 32130, - 14: 15110, - 15: 12261, - 16: 13040, - 17: 12191, - 18: 11120, - 19: 12261, - 20: 121, - 21: 22040, - 22: 311, - 23: 12191, - 24: 11230, - 25: 122, - 26: 12261, - 27: 121, - 28: 121, - 32: 41040, - 33: 111, - 34: 12191, - 35: 11330, - 36: 22040, - 37: 220, - 38: 14010, - 39: 140, - 40: 240 - } - - try: - sector_id = MAPPING[category_id] - except: - return "", "" - - if sector_id > 9999: - for count, sector in enumerate(IATI_LIST_SECTOR): - if sector[0] == sector_id: - return sector_id, IATI_LIST_SECTOR[count][1] - - else: - for count, sector in enumerate(IATI_LIST_SECTOR): - if sector[3] == sector_id: - return sector_id, IATI_LIST_SECTOR[count][4] - - - -def iati_outcome(activity, benchmarks, benchmark_names, categories): - """Collects all RSR benchmark information and adds them to the activity as results.""" - - bm_categories = benchmarks.values_list('category_id', flat=True) - categories_distinct = list() - map(lambda x: not x in categories_distinct and categories_distinct.append(x), bm_categories) - - for category in categories_distinct: - sector_id, sector_name = sector_mapping(category) - if check_value(sector_id): - sector_node = schema.sector(valueOf_=sector_name) - sector_node.set_code(sector_id) - activity.add_sector(sector_node) - - result_title = schema.textType(valueOf_=xml_enc(categories.get(id=category).name)) - result = schema.result(type_="2") - result.add_title(result_title) - - for benchmark in benchmarks.filter(category_id=category): - result_text = str(benchmark.value) + " " + benchmark_names.get(id=benchmark.name_id).name - result_description = schema.textType(valueOf_=xml_enc(result_text)) - result.add_description(result_description) - - activity.add_result(result) - - return activity - -def iati_links(activity, links): - """Collects the website links of the RSR project and adds them to the activity.""" - - for link in links: - if check_value(link.url): - website = schema.activity_website() - website.set_valueOf_(xml_enc(link.url)) - - if check_value(link.caption): - website.set_anyAttributes_({"akvo:url-caption": xml_enc(link.caption)}) - - activity.add_activity_website(website) - - return activity - -def iati_participating_org(activity, project, participating_orgs): - """Collects the participating organisations of the RSR project and adds it to the activity.""" - - def organisation_role(role): - """Converts the role of an RSR organisation to IATI codes and description. - - Participating organisation roles mapped to the RSR Organisation Roles: - Accountable => Support, Implementing => Field, Funding => Funding, Extending => Sponsor""" - - if role == 'support': - return IATI_LIST_ORGANISATION_ROLE[0][0] - elif role == 'field': - return IATI_LIST_ORGANISATION_ROLE[3][0] - elif role == 'funding': - return IATI_LIST_ORGANISATION_ROLE[2][0] - elif role == 'sponsor': - return IATI_LIST_ORGANISATION_ROLE[1][0] - else: - # This should never fire, the status of the project has been checked beforehand. - raise MandatoryError(project.title, project.pk, "organisation role") - - for participating_org in participating_orgs: - partnerships = Partnership.objects.filter(organisation_id=participating_org.pk, project_id=project.pk) - - for partnership in partnerships: - - participating_org_node = schema.participating_org() - participating_org_node.set_role(organisation_role(xml_enc(partnership.partner_type))) - - if check_value(participating_org.long_name): - participating_org_node.set_valueOf_(xml_enc(participating_org.long_name)) - elif check_value(participating_org.name): - participating_org_node.set_valueOf_(xml_enc(participating_org.name)) - - if check_value(participating_org.iati_org_id): - participating_org_node.set_ref(xml_enc(participating_org.iati_org_id)) - - if check_value(partnership.iati_url): - participating_org_node.set_anyAttributes_({"akvo:iati": xml_enc(partnership.iati_url)}) - - activity.add_participating_org(participating_org_node) - - return activity - -def iati_budget(activity, budgets, project): - """Collects budget of the RSR project and adds it to the activity.""" - - # Ignore total budgets -- label 13 or 14 -- if not all budgets are a total budget - if not all(budget.get_label() == 13 or 14 for budget in budgets): - budgets = filter(lambda x: x.get_label() == 13 or 14, budgets) - - for budget in budgets: - budget_node = schema.budget() - - budget_label = budget.get_label() - - if check_value(budget.amount): - budget_value = schema.textType(valueOf_=budget.amount) - - if check_value(project.date_start_actual): - budget_value.set_anyAttributes_({"value-date": project.date_start_actual}) - elif check_value(project.date_start_planned): - budget_value.set_anyAttributes_({"value-date": project.date_start_planned}) - - budget_node.add_value(budget_value) - - if check_value(budget_label): - budget_node.set_anyAttributes_({"akvo:type": xml_enc(budget_label)}) - - if check_value(budget.other_extra): - budget_node.set_anyAttributes_({"akvo:description": xml_enc(budget.other_extra)}) - - activity.add_budget(budget_node) - - return activity - - -def iati_location(activity, location, country): - """Collects location of the RSR project and adds it to the activity.""" - - location_node = schema.location() - - # Set value of location node. ", " if both are available. - if check_value(location.city): - if check_value(location.state): - location_name = schema.textType(valueOf_=xml_enc(location.city + ", " + location.state)) - location_node.add_name(location_name) - - else: - location_name = schema.textType(valueOf_=xml_enc(location.city)) - location_node.add_name(location_name) - - location_type = schema.textType(valueOf_="populated place") - location_type.set_anyAttributes_({"code": "PPL"}) - location_node.add_location_type(location_type) - - elif check_value(location.state): - location_name = schema.textType(valueOf_=xml_enc(location.state)) - location_node.add_name(location_name) - - location_type = schema.textType(valueOf_="first-order administrative division") - location_type.set_anyAttributes_({"code": "ADM1"}) - location_node.add_location_type(location_type) - - coordinates = schema.coordinatesType(latitude=location.latitude, longitude=location.longitude) - location_node.add_coordinates(coordinates) - - if check_value(country.name) and check_value(country.iso_code): - administrative = schema.administrativeType(country=country.iso_code.upper(), valueOf_=xml_enc(country.name)) - - location_node.add_administrative(administrative) - - # Add recipient-country node - recipient_country_node = schema.recipient_country(code=country.iso_code.upper(), valueOf_=xml_enc(country.name)) - activity.add_recipient_country(recipient_country_node) - - if check_value(location.address_1): - location_node.set_anyAttributes_({"akvo:address-1": xml_enc(location.address_1)}) - - if check_value(location.address_2): - location_node.set_anyAttributes_({"akvo:address-2": xml_enc(location.address_2)}) - - if check_value(location.postcode): - location_node.set_anyAttributes_({"akvo:post-code": xml_enc(location.postcode)}) - - activity.add_location(location_node) - - return activity - -def iati_photo(activity, project): - """Collects the actual photo of the RSR project and adds it to the activity.""" - - photo_url = "http://rsr.akvo.org/media/" + str(project.current_image) - - allowed_extensions = ["jpg", "jpeg", "png", "gif", "tiff", "bmp"] - try: - extension = str(project.current_image).rsplit('.',1)[1].lower() - except: - extension = "" - - document_link = schema.document_link(url=xml_enc(photo_url)) - - if check_value(extension) and extension in allowed_extensions: - document_link.set_format(xml_enc("image/" + extension)) - - if check_value(project.current_image_caption): - caption = schema.textType(valueOf_=xml_enc(project.current_image_caption)) - document_link.add_title(caption) - - if check_value(project.current_image_credit): - document_link.set_anyAttributes_({"akvo:photo-credit": xml_enc(project.current_image_credit)}) - - activity.add_document_link(document_link) - - return activity - -def iati_goals(activity, goals): - """Collects all goals as specified in the RSR project and adds them to the activity.""" - - for goal in goals: - if check_value(goal.text): - goal_text = schema.textType(valueOf_=xml_enc(goal.text)) - result = schema.result(type_="1") - result.add_title(goal_text) - activity.add_result(result) - - return activity - -def iati_contact(activity, organisation): - """Collects contact information of the RSR organisation and adds it to the activity.""" - - contact_node = schema.contact_info() - - if check_value(organisation.long_name): - long_name = schema.textType(valueOf_=xml_enc(organisation.long_name)) - contact_node.add_organisation(long_name) - elif check_value(organisation.name): - org_name = schema.textType(valueOf_=xml_enc(organisation.name)) - contact_node.add_organisation(org_name) - - if check_value(organisation.url): - contact_node.add_website(xml_enc(organisation.url)) - - if check_value(organisation.phone): - phone = schema.textType(valueOf_=xml_enc(organisation.phone)) - contact_node.add_telephone(phone) - elif check_value(organisation.mobile): - mobile = schema.textType(valueOf_=xml_enc(organisation.mobile)) - contact_node.add_telephone(mobile) - - if check_value(organisation.contact_person): - person = schema.textType(valueOf_=xml_enc(organisation.contact_person)) - contact_node.add_person_name(person) - - if check_value(organisation.contact_email): - email = schema.textType(valueOf_=xml_enc(organisation.contact_email)) - contact_node.add_email(email) - - activity.add_contact_info(contact_node) - - return activity - -def iati_activity(activity, project): - """Collects all underlying nodes of the node and adds them to the activity.""" - - def project_status(): - """Converts the status of the RSR project to IATI codes and description. - - Mapped to the RSR Project Status: Pipeline/identification => Needs Funding, - Implementation => Active, Completion => Completed, Post-completion => Completed, Cancelled => Cancelled.""" - - if project.status == Project.STATUS_NEEDS_FUNDING: - return IATI_LIST_ACTIVITY_STATUS[0][0], IATI_LIST_ACTIVITY_STATUS[0][1] - elif project.status == Project.STATUS_ACTIVE: - return IATI_LIST_ACTIVITY_STATUS[1][0], IATI_LIST_ACTIVITY_STATUS[1][1] - elif project.status == Project.STATUS_COMPLETE: - return IATI_LIST_ACTIVITY_STATUS[2][0], IATI_LIST_ACTIVITY_STATUS[2][1] - elif project.status == Project.STATUS_ARCHIVED: - return IATI_LIST_ACTIVITY_STATUS[3][0], IATI_LIST_ACTIVITY_STATUS[3][1] - elif project.status == Project.STATUS_CANCELLED: - return IATI_LIST_ACTIVITY_STATUS[4][0], IATI_LIST_ACTIVITY_STATUS[4][1] - else: - # Impossible to have another status - raise MandatoryError(project.title, project.pk, "status") - - # Title - activity.add_title(schema.textType(valueOf_=xml_enc(project.title))) - - # Subtitle - subtitle = schema.description(type_="1",valueOf_=xml_enc(project.subtitle)) - subtitle.set_anyAttributes_({"akvo:type":"4"}) - activity.add_description(subtitle) - - # Project plan summary - pps = schema.description(type_="1",valueOf_=xml_enc(project.project_plan_summary)) - pps.set_anyAttributes_({"akvo:type":"5"}) - activity.add_description(pps) - - # Background - if check_value(project.background): - background = schema.description(type_="1",valueOf_=xml_enc(project.background)) - background.set_anyAttributes_({"akvo:type":"6"}) - activity.add_description(background) - - # Project plan - if check_value(project.project_plan): - project_plan = schema.description(type_="1",valueOf_=xml_enc(project.project_plan)) - project_plan.set_anyAttributes_({"akvo:type":"7"}) - activity.add_description(project_plan) - - # Current status - if check_value(project.current_status): - current_status = schema.description(type_="1",valueOf_=xml_enc(project.current_status)) - current_status.set_anyAttributes_({"akvo:type":"9"}) - activity.add_description(current_status) - - # Sustainability - sustainability = schema.description(type_="1",valueOf_=xml_enc(project.sustainability)) - sustainability.set_anyAttributes_({"akvo:type":"10"}) - activity.add_description(sustainability) - - # Project status - status_code, status_description = project_status() - project_status = schema.textType(valueOf_=xml_enc(status_description)) - project_status.set_anyAttributes_({"code": status_code}) - activity.add_activity_status(project_status) - - # Goals overview - goals_overview = schema.description(type_="2",valueOf_=xml_enc(project.goals_overview)) - goals_overview.set_anyAttributes_({"akvo:type":"8"}) - activity.add_description(goals_overview) - - # Date start (actual) - if check_value(project.date_start_actual): - start_actual = schema.activity_date(iso_date=project.date_start_actual, type_="start-actual", - valueOf_=project.date_start_actual) - activity.add_activity_date(start_actual) - - # Date start (planned) - if check_value(project.date_start_planned): - start_planned = schema.activity_date(iso_date=project.date_start_planned, type_="start-planned", - valueOf_=project.date_start_planned) - activity.add_activity_date(start_planned) - - # Date end (actual) - if check_value(project.date_end_actual): - end_actual = schema.activity_date(iso_date=project.date_end_actual, type_="end-actual", - valueOf_=project.date_end_actual) - activity.add_activity_date(end_actual) - - # Date end (planned) - if check_value(project.date_end_planned): - end_planned = schema.activity_date(iso_date=project.date_end_planned, type_="end-planned", - valueOf_=project.date_end_planned) - activity.add_activity_date(end_planned) - - return activity - -def iati_reporting_org(activity, organisation): - """Collects the reporting organisation from the RSR project and adds it to the activity.""" - - reporting_org = schema.reporting_org() - - # Use long name if available and short name otherwise - if check_value(organisation.long_name): - reporting_org.set_valueOf_(xml_enc(organisation.long_name)) - else: - reporting_org.set_valueOf_(xml_enc(organisation.name)) - - if check_value(organisation.iati_org_id): - reporting_org.set_ref(xml_enc(organisation.iati_org_id)) - - activity.add_reporting_org(reporting_org) - - return activity - -def iati_identifier(activity, partnerships, organisation): - """Collects the IATI identifier from the RSR project and adds it to the activity.""" - - identifier = "" - support_partner_has_id = False - - # First look for activity ID of support partner partnership - for partnership in partnerships: - if partnership.partner_type == partnership.SUPPORT_PARTNER and partnership.iati_activity_id: - identifier = partnership.iati_activity_id - internal_id = partnership.internal_id - support_partner_has_id = True - - # Additional IDs that are entered into other partnerships should be added as related activities. - elif not partnership.partner_type == partnership.SUPPORT_PARTNER and partnership.iati_activity_id: - related_activity_node = schema.iati_identifier(valueOf_=xml_enc(partnership.iati_activity_id)) - activity.add_related_activity(related_activity_node) - # Also add 'related activity id' of every partnership as a related activity id - if partnership.related_activity_id: - related_activity_node = schema.iati_identifier(valueOf_=xml_enc(partnership.iati_activity_id)) - activity.add_related_activity(related_activity_node) - - # When no IATI activity ID is specified for the support partner, the ID this should be generated by - # taking the IATI Org ID of the partner and affixing the Project ID. - if not support_partner_has_id: - for partnership in partnerships: - if partnership.partner_type == partnership.SUPPORT_PARTNER and partnership.organisation.iati_org_id: - identifier = partnership.organisation.iati_org_id - identifier += "-" + str(partnership.project.pk) - internal_id = partnership.internal_id - - if check_value(identifier): - identifier_node = schema.iati_identifier(valueOf_=xml_enc(identifier)) - activity.add_iati_identifier(identifier_node) - - if check_value(internal_id): - other_identifier = schema.other_identifier(valueOf_=xml_enc(internal_id)) - if check_value(organisation.iati_org_id): - other_identifier.set_owner_ref(xml_enc(organisation.iati_org_id)) - if check_value(organisation.long_name): - other_identifier.set_owner_name(xml_enc(organisation.long_name)) - elif check_value(organisation.name): - other_identifier.set_owner_name(xml_enc(organisation.name)) - - activity.add_other_identifier(other_identifier) - - return activity - -def process_project(xml, project, org_id): - """Convert a project to an IATI XML.""" - - # Get all necessary data - partnerships = Partnership.objects.filter(project_id=project.pk) - goals = Goal.objects.filter(project_id=project.pk) - try: - location = project.primary_location - country = Country.objects.get(id=location.country_id) - except: - raise MandatoryError(project.title, project.pk, "location") - budgets = BudgetItem.objects.filter(project_id=project.pk) - participating_orgs = project.all_partners() - links = Link.objects.filter(project_id=project.pk) - benchmarks = Benchmark.objects.filter(project_id=project.pk).filter(value__gt=0) - benchmark_names = Benchmarkname.objects.all() - categories = Category.objects.all() - - # Check mandatory fields - check_mandatory_fields(project, {"title": project.title, - "subtitle": project.subtitle, - "status": project.status, - "project plan summary": project.project_plan_summary, - "sustainability": project.sustainability, - "goals overview": project.goals_overview, - "status": project.status, - "photo": project.current_image, - "latitude": location.latitude, - "longitude": location.longitude, - "country": location.country_id}) - - for participating_org in participating_orgs: - partnerships_orgs = Partnership.objects.filter(organisation_id=participating_org.pk, project_id=project.pk) - for partnership in partnerships_orgs: - check_mandatory_fields(project, {"partner type of a participating organisation": partnership.partner_type}) - - # Create the activity - activity = schema.iati_activity() - - # Set arguments - if check_value(project.language): activity.set_lang(project.language) - if check_value(project.currency): activity.set_default_currency(project.currency) - - # Add nodes - activity = iati_identifier(activity, partnerships, organisation) - activity = iati_reporting_org(activity, organisation) - activity = iati_activity(activity, project) - activity = iati_contact(activity, organisation) - activity = iati_goals(activity, goals) - activity = iati_photo(activity, project) - activity = iati_location(activity, location, country) - activity = iati_budget(activity, budgets, project) - activity = iati_participating_org(activity, project, participating_orgs) - activity = iati_links(activity, links) - activity = iati_outcome(activity, benchmarks, benchmark_names, categories) - - # Add the activity to the xml - xml.add_iati_activity(activity) - - return xml - -def generate_file(projects, org_id, iati_version): - """Generates the IATI XML file based on the projects and the organisation ID.""" - - dt = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") - iati_file = schema.iati_activities(dt, iati_version) - iati_file.set_anyAttributes_({"xmlns:akvo": "http://akvo.org/iati-activities"}) - - for project in projects: - try: - iati_file = process_project(iati_file, project, org_id) - except MandatoryError as e: - print e.msg - else: - print "Successfully processed project '%s' (id: %s)" % (project.title, project.pk) - - return iati_file - -def project_selection(organisation, partner_types, ignore_list): - """Returns list of projects connected to an organisation. Add project id to ignore list - to ignore a project.""" - - # Retrieve all active projects of the organisation - active_projects = organisation.published_projects() - - # Check every project whether organisation has one of the selected partner types - project_list = [] - for project in active_projects: - for partner_type in partner_types: - if partner_type[0] and (organisation in getattr(project, partner_type[1])()): - project_list.append(project) - break - - # Filter out ignored projects - if not ignore_list is None: - for id in ignore_list: - try: - project = Project.objects.get(id=id) - if project in project_list: - project_list.remove(project) - except: - pass - - return project_list - -def export_file(path, file, organisation): - """Exports the XML to a file using the name of the organisation.""" - - name = organisation.name - file_name = path + name + ".xml" - - # Check if file exists and make sure the file has a unique name - increment = True - count = 1 - - while increment: - if os.path.isfile(file_name): - file_name = path + name + " (" + str(count) + ").xml" - count += 1 - else: - with open(file_name, 'w') as f: - f.write('\n') - file.export(f, 0) - increment = False - - print "\nIATI XML available at: " + str(file_name) + "\n" - - -if __name__ == '__main__': - # Parse arguments - parser = argparse.ArgumentParser() - parser.add_argument("-o", "--organisation", help="organisation id (required)", type=int, required=True) - parser.add_argument("-fi", "--field", help="select field partners", action="store_true") - parser.add_argument("-fu", "--funding", help="select funding partners", action="store_true") - parser.add_argument("-sp", "--sponsor", help="select sponsor partners", action="store_true") - parser.add_argument("-su", "--support", help="select support partners", action="store_true") - parser.add_argument("-i", "--ignore", help="project id's to be ignored", type=int, nargs='*') - args = parser.parse_args() - - # At least one of the partner types has to be selected, if not the program is terminated - if not (args.field or args.funding or args.sponsor or args.support): - print "Error; choose at least one of the partner types:\n" - print "- Field partner (-fi)" - print "- Funding partner (-fu)" - print "- Sponsor partner (-sp)" - print "- Support partner (-su)\n" - sys.exit() - - # Check if organisation exists, if not the program is terminated - try: - organisation = Organisation.objects.get(id=args.organisation) - except: - print "Error; organisation with id " + str(args.organisation) + " does not exist\n" - sys.exit() - - # Variables - PARTNER_TYPES = ((args.field, "field_partners"), - (args.funding, "funding_partners"), - (args.sponsor, "sponsor_partners"), - (args.support, "support_partners")) - IATI_VERSION = "1.03" - PATH = "/var/iati_files/" - - # Project selection based on organisation ID, partner types and the projects to be ignored - projects = project_selection(organisation, PARTNER_TYPES, args.ignore) - - # Convert selected projects to XML - iati_file = generate_file(projects, args.organisation, IATI_VERSION) - - # Output file - export_file(PATH, iati_file, organisation) \ No newline at end of file diff --git a/akvo/rsr/iati/iati_schema.py b/akvo/rsr/iati/iati_schema.py deleted file mode 100644 index 47a7f6ff68..0000000000 --- a/akvo/rsr/iati/iati_schema.py +++ /dev/null @@ -1,12303 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# Generated Thu Mar 13 10:45:54 2014 by generateDS.py version 2.12b. -# - -import sys -import getopt -import re as re_ -import base64 -import datetime as datetime_ - -etree_ = None -Verbose_import_ = False -( - XMLParser_import_none, XMLParser_import_lxml, - XMLParser_import_elementtree -) = range(3) -XMLParser_import_library = None -try: - # lxml - from lxml import etree as etree_ - XMLParser_import_library = XMLParser_import_lxml - if Verbose_import_: - print("running with lxml.etree") -except ImportError: - try: - # cElementTree from Python 2.5+ - import xml.etree.cElementTree as etree_ - XMLParser_import_library = XMLParser_import_elementtree - if Verbose_import_: - print("running with cElementTree on Python 2.5+") - except ImportError: - try: - # ElementTree from Python 2.5+ - import xml.etree.ElementTree as etree_ - XMLParser_import_library = XMLParser_import_elementtree - if Verbose_import_: - print("running with ElementTree on Python 2.5+") - except ImportError: - try: - # normal cElementTree install - import cElementTree as etree_ - XMLParser_import_library = XMLParser_import_elementtree - if Verbose_import_: - print("running with cElementTree") - except ImportError: - try: - # normal ElementTree install - import elementtree.ElementTree as etree_ - XMLParser_import_library = XMLParser_import_elementtree - if Verbose_import_: - print("running with ElementTree") - except ImportError: - raise ImportError( - "Failed to import ElementTree from any known place") - - -def parsexml_(*args, **kwargs): - if (XMLParser_import_library == XMLParser_import_lxml and - 'parser' not in kwargs): - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - kwargs['parser'] = etree_.ETCompatXMLParser() - doc = etree_.parse(*args, **kwargs) - return doc - -# -# User methods -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ImportError, exp: - - class GeneratedsSuper(object): - tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$') - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - def utcoffset(self, dt): - return self.__offset - def tzname(self, dt): - return self.__name - def dst(self, dt): - return None - def gds_format_string(self, input_data, input_name=''): - return input_data - def gds_validate_string(self, input_data, node, input_name=''): - if not input_data: - return '' - else: - return input_data - def gds_format_base64(self, input_data, input_name=''): - return base64.b64encode(input_data) - def gds_validate_base64(self, input_data, node, input_name=''): - return input_data - def gds_format_integer(self, input_data, input_name=''): - return '%d' % input_data - def gds_validate_integer(self, input_data, node, input_name=''): - return input_data - def gds_format_integer_list(self, input_data, input_name=''): - return '%s' % input_data - def gds_validate_integer_list(self, input_data, node, input_name=''): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, 'Requires sequence of integers') - return input_data - def gds_format_float(self, input_data, input_name=''): - return ('%.15f' % input_data).rstrip('0') - def gds_validate_float(self, input_data, node, input_name=''): - return input_data - def gds_format_float_list(self, input_data, input_name=''): - return '%s' % input_data - def gds_validate_float_list(self, input_data, node, input_name=''): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, 'Requires sequence of floats') - return input_data - def gds_format_double(self, input_data, input_name=''): - return '%e' % input_data - def gds_validate_double(self, input_data, node, input_name=''): - return input_data - def gds_format_double_list(self, input_data, input_name=''): - return '%s' % input_data - def gds_validate_double_list(self, input_data, node, input_name=''): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, 'Requires sequence of doubles') - return input_data - def gds_format_boolean(self, input_data, input_name=''): - return ('%s' % input_data).lower() - def gds_validate_boolean(self, input_data, node, input_name=''): - return input_data - def gds_format_boolean_list(self, input_data, input_name=''): - return '%s' % input_data - def gds_validate_boolean_list(self, input_data, node, input_name=''): - values = input_data.split() - for value in values: - if value not in ('true', '1', 'false', '0', ): - raise_parse_error( - node, - 'Requires sequence of booleans ' - '("true", "1", "false", "0")') - return input_data - def gds_validate_datetime(self, input_data, node, input_name=''): - return input_data - def gds_format_datetime(self, input_data, input_name=''): - if input_data.microsecond == 0: - _svalue = '%04d-%02d-%02dT%02d:%02d:%02d' % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = '%04d-%02d-%02dT%02d:%02d:%02d.%s' % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ('%f' % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += 'Z' - else: - if total_seconds < 0: - _svalue += '-' - total_seconds *= -1 - else: - _svalue += '+' - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += '{0:02d}:{1:02d}'.format(hours, minutes) - return _svalue - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == 'Z': - tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC') - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(':') - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == '-': - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ( - tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split('.')) > 1: - dt = datetime_.datetime.strptime( - input_data, '%Y-%m-%dT%H:%M:%S.%f') - else: - dt = datetime_.datetime.strptime( - input_data, '%Y-%m-%dT%H:%M:%S') - dt = dt.replace(tzinfo=tz) - return dt - def gds_validate_date(self, input_data, node, input_name=''): - return input_data - def gds_format_date(self, input_data, input_name=''): - _svalue = '%04d-%02d-%02d' % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += 'Z' - else: - if total_seconds < 0: - _svalue += '-' - total_seconds *= -1 - else: - _svalue += '+' - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += '{0:02d}:{1:02d}'.format(hours, minutes) - except AttributeError: - pass - return _svalue - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == 'Z': - tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC') - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(':') - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == '-': - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ( - tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, '%Y-%m-%d') - dt = dt.replace(tzinfo=tz) - return dt.date() - def gds_validate_time(self, input_data, node, input_name=''): - return input_data - def gds_format_time(self, input_data, input_name=''): - if input_data.microsecond == 0: - _svalue = '%02d:%02d:%02d' % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = '%02d:%02d:%02d.%s' % ( - input_data.hour, - input_data.minute, - input_data.second, - ('%f' % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += 'Z' - else: - if total_seconds < 0: - _svalue += '-' - total_seconds *= -1 - else: - _svalue += '+' - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += '{0:02d}:{1:02d}'.format(hours, minutes) - return _svalue - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == 'Z': - tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC') - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(':') - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == '-': - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ( - tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split('.')) > 1: - dt = datetime_.datetime.strptime(input_data, '%H:%M:%S.%f') - else: - dt = datetime_.datetime.strptime(input_data, '%H:%M:%S') - dt = dt.replace(tzinfo=tz) - return dt.time() - def gds_str_lower(self, instring): - return instring.lower() - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = '/'.join(path_list) - return path - Tag_strip_pattern_ = re_.compile(r'\{.*\}') - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub('', node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if 'xsi' in node.nsmap: - classname = node.get('{%s}type' % node.nsmap['xsi']) - if classname is not None: - names = classname.split(':') - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - def gds_build_any(self, node, type_name=None): - return None - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.iteritems())) - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = 'ascii' -Tag_pattern_ = re_.compile(r'({.*})?(.*)') -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r'{(.*)}(.*)') - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(' ') - - -def quote_xml(inStr): - if not inStr: - return '' - s1 = (isinstance(inStr, basestring) and inStr or - '%s' % inStr) - s1 = s1.replace('&', '&') - s1 = s1.replace('<', '<') - s1 = s1.replace('>', '>') - return s1 - - -def quote_attrib(inStr): - s1 = (isinstance(inStr, basestring) and inStr or - '%s' % inStr) - s1 = s1.replace('&', '&') - s1 = s1.replace('<', '<') - s1 = s1.replace('>', '>') - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find('\n') == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find('\n') == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = '' - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(':') - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get('{%s}%s' % (namespace, name, )) - return value - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if XMLParser_import_library == XMLParser_import_lxml: - msg = '%s (element %s/line %d)' % ( - msg, node.tag, node.sourceline, ) - else: - msg = '%s (element %s)' % (msg, node.tag, ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - def getCategory(self): - return self.category - def getContenttype(self, content_type): - return self.content_type - def getValue(self): - return self.value - def getName(self): - return self.name - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export(outfile, level, namespace, name, pretty_print) - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write('<%s>%s' % ( - self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeInteger or \ - self.content_type == MixedContainer.TypeBoolean: - outfile.write('<%s>%d' % ( - self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeFloat or \ - self.content_type == MixedContainer.TypeDecimal: - outfile.write('<%s>%f' % ( - self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write('<%s>%g' % ( - self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write('<%s>%s' % ( - self.name, base64.b64encode(self.value), self.name)) - def to_etree(self, element): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, '%s' % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - def to_etree_simple(self): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif (self.content_type == MixedContainer.TypeInteger or - self.content_type == MixedContainer.TypeBoolean): - text = '%d' % self.value - elif (self.content_type == MixedContainer.TypeFloat or - self.content_type == MixedContainer.TypeDecimal): - text = '%f' % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = '%g' % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = '%s' % base64.b64encode(self.value) - return text - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % ( - self.category, self.content_type, self.name, self.value)) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % ( - self.category, self.content_type, self.name, self.value)) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' % ( - self.category, self.content_type, self.name,)) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(')\n') - - -class MemberSpec_(object): - def __init__(self, name='', data_type='', container=0): - self.name = name - self.data_type = data_type - self.container = container - def set_name(self, name): self.name = name - def get_name(self): return self.name - def set_data_type(self, data_type): self.data_type = data_type - def get_data_type_chain(self): return self.data_type - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return 'xs:string' - else: - return self.data_type - def set_container(self, container): self.container = container - def get_container(self): return self.container - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - -# -# Data representation classes. -# - - -class iati_activities(GeneratedsSuper): - """Top-level list of one or more IATI activity records. A number - indicating the IATI specification version in use. A date/time - stamp for when this file was generated. This is not necessarily - the last-updated date for the individual activity records in it. - Uses ISO 8601 date format, e.g. "2010-03-12T18:45:00+01:00". Use - of this attribute is highly recommended, to allow recipients to - know when a file has been updated. IATI publishers are not - obliged to publish their own Linked Data. However, if a - publisher chooses to publish linked data about their IATI - activities then allowing them to declare where this data is - published would support discovery of it, and any additional - information they may choose to publish as Linked Data alongside - it. This attribute is URI path upon which an activity identifier - can be appended to get a dereferenceable URI for any activity - contained within a file. Where a publisher declares using one of - these properties that authoritative linked data is accessible - for an activity then consuming applications that are generating - Linked Data from an IATI XML file should assert an owl:sameAs - relationship to the relevant URI.""" - subclass = None - superclass = None - def __init__(self, generated_datetime=None, version=None, linked_data_default=None, iati_activity=None, anytypeobjs_=None): - if isinstance(generated_datetime, basestring): - initvalue_ = datetime_.datetime.strptime(generated_datetime, '%Y-%m-%dT%H:%M:%S') - else: - initvalue_ = generated_datetime - self.generated_datetime = initvalue_ - self.version = _cast(float, version) - self.linked_data_default = _cast(None, linked_data_default) - if iati_activity is None: - self.iati_activity = [] - else: - self.iati_activity = iati_activity - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if iati_activities.subclass: - return iati_activities.subclass(*args_, **kwargs_) - else: - return iati_activities(*args_, **kwargs_) - factory = staticmethod(factory) - def get_iati_activity(self): return self.iati_activity - def set_iati_activity(self, iati_activity): self.iati_activity = iati_activity - def add_iati_activity(self, value): self.iati_activity.append(value) - def insert_iati_activity(self, index, value): self.iati_activity[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_generated_datetime(self): return self.generated_datetime - def set_generated_datetime(self, generated_datetime): self.generated_datetime = generated_datetime - def get_version(self): return self.version - def set_version(self, version): self.version = version - def get_linked_data_default(self): return self.linked_data_default - def set_linked_data_default(self, linked_data_default): self.linked_data_default = linked_data_default - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.iati_activity or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='iati-activities', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='iati-activities') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='iati-activities', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='iati-activities'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.generated_datetime is not None and 'generated_datetime' not in already_processed: - already_processed.add('generated_datetime') - outfile.write(' generated-datetime="%s"' % self.gds_format_datetime(self.generated_datetime, input_name='generated-datetime')) - if self.version is not None and 'version' not in already_processed: - already_processed.add('version') - outfile.write(' version="%s"' % self.gds_format_float(self.version, input_name='version')) - if self.linked_data_default is not None and 'linked_data_default' not in already_processed: - already_processed.add('linked_data_default') - outfile.write(' linked-data-default=%s' % (self.gds_format_string(quote_attrib(self.linked_data_default).encode(ExternalEncoding), input_name='linked-data-default'), )) - def exportChildren(self, outfile, level, namespace_='', name_='iati-activities', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for iati_activity_ in self.iati_activity: - iati_activity_.export(outfile, level, namespace_, name_='iati-activity', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='iati-activities'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.generated_datetime is not None and 'generated_datetime' not in already_processed: - already_processed.add('generated_datetime') - showIndent(outfile, level) - outfile.write('generated-datetime=model_.GeneratedsSuper.gds_parse_datetime("%s"),\n' % self.gds_format_datetime(self.generated_datetime, input_name='generated-datetime')) - if self.version is not None and 'version' not in already_processed: - already_processed.add('version') - showIndent(outfile, level) - outfile.write('version=%f,\n' % (self.version,)) - if self.linked_data_default is not None and 'linked_data_default' not in already_processed: - already_processed.add('linked_data_default') - showIndent(outfile, level) - outfile.write('linked_data_default="%s",\n' % (self.linked_data_default,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('iati_activity=[\n') - level += 1 - for iati_activity_ in self.iati_activity: - showIndent(outfile, level) - outfile.write('model_.iati_activity(\n') - iati_activity_.exportLiteral(outfile, level, name_='iati-activity') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('generated-datetime', node) - if value is not None and 'generated-datetime' not in already_processed: - already_processed.add('generated-datetime') - try: - self.generated_datetime = self.gds_parse_datetime(value) - except ValueError, exp: - raise ValueError('Bad date-time attribute (generated-datetime): %s' % exp) - value = find_attr_value_('version', node) - if value is not None and 'version' not in already_processed: - already_processed.add('version') - try: - self.version = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (version): %s' % exp) - value = find_attr_value_('linked-data-default', node) - if value is not None and 'linked-data-default' not in already_processed: - already_processed.add('linked-data-default') - self.linked_data_default = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'iati-activity': - obj_ = iati_activity.factory() - obj_.build(child_) - self.iati_activity.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'iati-activities') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class iati_activities - - -class iati_activity(GeneratedsSuper): - """Top-level element for a single IATI activity report. A number - indicating the IATI specification version in use. Defaults to - "1.0" if not specified. It is required to specify this attribute - if the document is using features specific to an IATI - specification other than the initial 1.0 version. The last - date/time that the data for this specific activity was updated. - This date must change whenever the value of any field changes. - Default ISO 4217 currency code for all financial values in this - activity report. See http://iatistandard.org/codelists/currency - The hierarchical level within the reporting organisation's - subdivision of its units of aid. (eg activity = 1; sub-activity - = 2; sub-sub-activity = 3). If hierarchy is not reported then 1 - is assumed. If multiple levels are reported then, to avoid - double counting, financial transactions should only be reported - at the lowest hierarchical level. A Linked Data URI for a given - activity (overrides iati-activities/@linked-data-default if set)""" - subclass = None - superclass = None - def __init__(self, lang=None, linked_data_uri=None, hierarchy=None, default_currency=None, last_updated_datetime=None, version=None, activity_website=None, reporting_org=None, participating_org=None, activity_scope=None, recipient_country=None, recipient_region=None, collaboration_type=None, default_flow_type=None, default_aid_type=None, default_finance_type=None, iati_identifier=None, other_identifier=None, title=None, description=None, sector=None, activity_date=None, activity_status=None, contact_info=None, default_tied_status=None, policy_marker=None, location=None, capital_spend=None, transaction=None, result=None, conditions=None, budget=None, planned_disbursement=None, country_budget_items=None, related_activity=None, document_link=None, legacy_data=None, crs_add=None, fss=None, anytypeobjs_=None): - self.lang = _cast(None, lang) - self.linked_data_uri = _cast(None, linked_data_uri) - self.hierarchy = _cast(int, hierarchy) - self.default_currency = _cast(None, default_currency) - if isinstance(last_updated_datetime, basestring): - initvalue_ = datetime_.datetime.strptime(last_updated_datetime, '%Y-%m-%dT%H:%M:%S') - else: - initvalue_ = last_updated_datetime - self.last_updated_datetime = initvalue_ - self.version = _cast(float, version) - if activity_website is None: - self.activity_website = [] - else: - self.activity_website = activity_website - if reporting_org is None: - self.reporting_org = [] - else: - self.reporting_org = reporting_org - if participating_org is None: - self.participating_org = [] - else: - self.participating_org = participating_org - if activity_scope is None: - self.activity_scope = [] - else: - self.activity_scope = activity_scope - if recipient_country is None: - self.recipient_country = [] - else: - self.recipient_country = recipient_country - if recipient_region is None: - self.recipient_region = [] - else: - self.recipient_region = recipient_region - if collaboration_type is None: - self.collaboration_type = [] - else: - self.collaboration_type = collaboration_type - if default_flow_type is None: - self.default_flow_type = [] - else: - self.default_flow_type = default_flow_type - if default_aid_type is None: - self.default_aid_type = [] - else: - self.default_aid_type = default_aid_type - if default_finance_type is None: - self.default_finance_type = [] - else: - self.default_finance_type = default_finance_type - if iati_identifier is None: - self.iati_identifier = [] - else: - self.iati_identifier = iati_identifier - if other_identifier is None: - self.other_identifier = [] - else: - self.other_identifier = other_identifier - if title is None: - self.title = [] - else: - self.title = title - if description is None: - self.description = [] - else: - self.description = description - if sector is None: - self.sector = [] - else: - self.sector = sector - if activity_date is None: - self.activity_date = [] - else: - self.activity_date = activity_date - if activity_status is None: - self.activity_status = [] - else: - self.activity_status = activity_status - if contact_info is None: - self.contact_info = [] - else: - self.contact_info = contact_info - if default_tied_status is None: - self.default_tied_status = [] - else: - self.default_tied_status = default_tied_status - if policy_marker is None: - self.policy_marker = [] - else: - self.policy_marker = policy_marker - if location is None: - self.location = [] - else: - self.location = location - if capital_spend is None: - self.capital_spend = [] - else: - self.capital_spend = capital_spend - if transaction is None: - self.transaction = [] - else: - self.transaction = transaction - if result is None: - self.result = [] - else: - self.result = result - if conditions is None: - self.conditions = [] - else: - self.conditions = conditions - if budget is None: - self.budget = [] - else: - self.budget = budget - if planned_disbursement is None: - self.planned_disbursement = [] - else: - self.planned_disbursement = planned_disbursement - if country_budget_items is None: - self.country_budget_items = [] - else: - self.country_budget_items = country_budget_items - if related_activity is None: - self.related_activity = [] - else: - self.related_activity = related_activity - if document_link is None: - self.document_link = [] - else: - self.document_link = document_link - if legacy_data is None: - self.legacy_data = [] - else: - self.legacy_data = legacy_data - if crs_add is None: - self.crs_add = [] - else: - self.crs_add = crs_add - if fss is None: - self.fss = [] - else: - self.fss = fss - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if iati_activity.subclass: - return iati_activity.subclass(*args_, **kwargs_) - else: - return iati_activity(*args_, **kwargs_) - factory = staticmethod(factory) - def get_activity_website(self): return self.activity_website - def set_activity_website(self, activity_website): self.activity_website = activity_website - def add_activity_website(self, value): self.activity_website.append(value) - def insert_activity_website(self, index, value): self.activity_website[index] = value - def get_reporting_org(self): return self.reporting_org - def set_reporting_org(self, reporting_org): self.reporting_org = reporting_org - def add_reporting_org(self, value): self.reporting_org.append(value) - def insert_reporting_org(self, index, value): self.reporting_org[index] = value - def get_participating_org(self): return self.participating_org - def set_participating_org(self, participating_org): self.participating_org = participating_org - def add_participating_org(self, value): self.participating_org.append(value) - def insert_participating_org(self, index, value): self.participating_org[index] = value - def get_activity_scope(self): return self.activity_scope - def set_activity_scope(self, activity_scope): self.activity_scope = activity_scope - def add_activity_scope(self, value): self.activity_scope.append(value) - def insert_activity_scope(self, index, value): self.activity_scope[index] = value - def get_recipient_country(self): return self.recipient_country - def set_recipient_country(self, recipient_country): self.recipient_country = recipient_country - def add_recipient_country(self, value): self.recipient_country.append(value) - def insert_recipient_country(self, index, value): self.recipient_country[index] = value - def get_recipient_region(self): return self.recipient_region - def set_recipient_region(self, recipient_region): self.recipient_region = recipient_region - def add_recipient_region(self, value): self.recipient_region.append(value) - def insert_recipient_region(self, index, value): self.recipient_region[index] = value - def get_collaboration_type(self): return self.collaboration_type - def set_collaboration_type(self, collaboration_type): self.collaboration_type = collaboration_type - def add_collaboration_type(self, value): self.collaboration_type.append(value) - def insert_collaboration_type(self, index, value): self.collaboration_type[index] = value - def get_default_flow_type(self): return self.default_flow_type - def set_default_flow_type(self, default_flow_type): self.default_flow_type = default_flow_type - def add_default_flow_type(self, value): self.default_flow_type.append(value) - def insert_default_flow_type(self, index, value): self.default_flow_type[index] = value - def get_default_aid_type(self): return self.default_aid_type - def set_default_aid_type(self, default_aid_type): self.default_aid_type = default_aid_type - def add_default_aid_type(self, value): self.default_aid_type.append(value) - def insert_default_aid_type(self, index, value): self.default_aid_type[index] = value - def get_default_finance_type(self): return self.default_finance_type - def set_default_finance_type(self, default_finance_type): self.default_finance_type = default_finance_type - def add_default_finance_type(self, value): self.default_finance_type.append(value) - def insert_default_finance_type(self, index, value): self.default_finance_type[index] = value - def get_iati_identifier(self): return self.iati_identifier - def set_iati_identifier(self, iati_identifier): self.iati_identifier = iati_identifier - def add_iati_identifier(self, value): self.iati_identifier.append(value) - def insert_iati_identifier(self, index, value): self.iati_identifier[index] = value - def get_other_identifier(self): return self.other_identifier - def set_other_identifier(self, other_identifier): self.other_identifier = other_identifier - def add_other_identifier(self, value): self.other_identifier.append(value) - def insert_other_identifier(self, index, value): self.other_identifier[index] = value - def get_title(self): return self.title - def set_title(self, title): self.title = title - def add_title(self, value): self.title.append(value) - def insert_title(self, index, value): self.title[index] = value - def get_description(self): return self.description - def set_description(self, description): self.description = description - def add_description(self, value): self.description.append(value) - def insert_description(self, index, value): self.description[index] = value - def get_sector(self): return self.sector - def set_sector(self, sector): self.sector = sector - def add_sector(self, value): self.sector.append(value) - def insert_sector(self, index, value): self.sector[index] = value - def get_activity_date(self): return self.activity_date - def set_activity_date(self, activity_date): self.activity_date = activity_date - def add_activity_date(self, value): self.activity_date.append(value) - def insert_activity_date(self, index, value): self.activity_date[index] = value - def get_activity_status(self): return self.activity_status - def set_activity_status(self, activity_status): self.activity_status = activity_status - def add_activity_status(self, value): self.activity_status.append(value) - def insert_activity_status(self, index, value): self.activity_status[index] = value - def get_contact_info(self): return self.contact_info - def set_contact_info(self, contact_info): self.contact_info = contact_info - def add_contact_info(self, value): self.contact_info.append(value) - def insert_contact_info(self, index, value): self.contact_info[index] = value - def get_default_tied_status(self): return self.default_tied_status - def set_default_tied_status(self, default_tied_status): self.default_tied_status = default_tied_status - def add_default_tied_status(self, value): self.default_tied_status.append(value) - def insert_default_tied_status(self, index, value): self.default_tied_status[index] = value - def get_policy_marker(self): return self.policy_marker - def set_policy_marker(self, policy_marker): self.policy_marker = policy_marker - def add_policy_marker(self, value): self.policy_marker.append(value) - def insert_policy_marker(self, index, value): self.policy_marker[index] = value - def get_location(self): return self.location - def set_location(self, location): self.location = location - def add_location(self, value): self.location.append(value) - def insert_location(self, index, value): self.location[index] = value - def get_capital_spend(self): return self.capital_spend - def set_capital_spend(self, capital_spend): self.capital_spend = capital_spend - def add_capital_spend(self, value): self.capital_spend.append(value) - def insert_capital_spend(self, index, value): self.capital_spend[index] = value - def get_transaction(self): return self.transaction - def set_transaction(self, transaction): self.transaction = transaction - def add_transaction(self, value): self.transaction.append(value) - def insert_transaction(self, index, value): self.transaction[index] = value - def get_result(self): return self.result - def set_result(self, result): self.result = result - def add_result(self, value): self.result.append(value) - def insert_result(self, index, value): self.result[index] = value - def get_conditions(self): return self.conditions - def set_conditions(self, conditions): self.conditions = conditions - def add_conditions(self, value): self.conditions.append(value) - def insert_conditions(self, index, value): self.conditions[index] = value - def get_budget(self): return self.budget - def set_budget(self, budget): self.budget = budget - def add_budget(self, value): self.budget.append(value) - def insert_budget(self, index, value): self.budget[index] = value - def get_planned_disbursement(self): return self.planned_disbursement - def set_planned_disbursement(self, planned_disbursement): self.planned_disbursement = planned_disbursement - def add_planned_disbursement(self, value): self.planned_disbursement.append(value) - def insert_planned_disbursement(self, index, value): self.planned_disbursement[index] = value - def get_country_budget_items(self): return self.country_budget_items - def set_country_budget_items(self, country_budget_items): self.country_budget_items = country_budget_items - def add_country_budget_items(self, value): self.country_budget_items.append(value) - def insert_country_budget_items(self, index, value): self.country_budget_items[index] = value - def get_related_activity(self): return self.related_activity - def set_related_activity(self, related_activity): self.related_activity = related_activity - def add_related_activity(self, value): self.related_activity.append(value) - def insert_related_activity(self, index, value): self.related_activity[index] = value - def get_document_link(self): return self.document_link - def set_document_link(self, document_link): self.document_link = document_link - def add_document_link(self, value): self.document_link.append(value) - def insert_document_link(self, index, value): self.document_link[index] = value - def get_legacy_data(self): return self.legacy_data - def set_legacy_data(self, legacy_data): self.legacy_data = legacy_data - def add_legacy_data(self, value): self.legacy_data.append(value) - def insert_legacy_data(self, index, value): self.legacy_data[index] = value - def get_crs_add(self): return self.crs_add - def set_crs_add(self, crs_add): self.crs_add = crs_add - def add_crs_add(self, value): self.crs_add.append(value) - def insert_crs_add(self, index, value): self.crs_add[index] = value - def get_fss(self): return self.fss - def set_fss(self, fss): self.fss = fss - def add_fss(self, value): self.fss.append(value) - def insert_fss(self, index, value): self.fss[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_linked_data_uri(self): return self.linked_data_uri - def set_linked_data_uri(self, linked_data_uri): self.linked_data_uri = linked_data_uri - def get_hierarchy(self): return self.hierarchy - def set_hierarchy(self, hierarchy): self.hierarchy = hierarchy - def get_default_currency(self): return self.default_currency - def set_default_currency(self, default_currency): self.default_currency = default_currency - def get_last_updated_datetime(self): return self.last_updated_datetime - def set_last_updated_datetime(self, last_updated_datetime): self.last_updated_datetime = last_updated_datetime - def get_version(self): return self.version - def set_version(self, version): self.version = version - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.activity_website or - self.reporting_org or - self.participating_org or - self.activity_scope or - self.recipient_country or - self.recipient_region or - self.collaboration_type or - self.default_flow_type or - self.default_aid_type or - self.default_finance_type or - self.iati_identifier or - self.other_identifier or - self.title or - self.description or - self.sector or - self.activity_date or - self.activity_status or - self.contact_info or - self.default_tied_status or - self.policy_marker or - self.location or - self.capital_spend or - self.transaction or - self.result or - self.conditions or - self.budget or - self.planned_disbursement or - self.country_budget_items or - self.related_activity or - self.document_link or - self.legacy_data or - self.crs_add or - self.fss or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='iati-activity', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='iati-activity') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='iati-activity', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='iati-activity'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' xml:lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.linked_data_uri is not None and 'linked_data_uri' not in already_processed: - already_processed.add('linked_data_uri') - outfile.write(' linked-data-uri=%s' % (self.gds_format_string(quote_attrib(self.linked_data_uri).encode(ExternalEncoding), input_name='linked-data-uri'), )) - if self.hierarchy is not None and 'hierarchy' not in already_processed: - already_processed.add('hierarchy') - outfile.write(' hierarchy="%s"' % self.gds_format_integer(self.hierarchy, input_name='hierarchy')) - if self.default_currency is not None and 'default_currency' not in already_processed: - already_processed.add('default_currency') - outfile.write(' default-currency=%s' % (self.gds_format_string(quote_attrib(self.default_currency).encode(ExternalEncoding), input_name='default-currency'), )) - if self.last_updated_datetime is not None and 'last_updated_datetime' not in already_processed: - already_processed.add('last_updated_datetime') - outfile.write(' last-updated-datetime="%s"' % self.gds_format_datetime(self.last_updated_datetime, input_name='last-updated-datetime')) - if self.version is not None and 'version' not in already_processed: - already_processed.add('version') - outfile.write(' version="%s"' % self.gds_format_float(self.version, input_name='version')) - def exportChildren(self, outfile, level, namespace_='', name_='iati-activity', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for activity_website_ in self.activity_website: - activity_website_.export(outfile, level, namespace_, name_='activity-website', pretty_print=pretty_print) - for reporting_org_ in self.reporting_org: - reporting_org_.export(outfile, level, namespace_, name_='reporting-org', pretty_print=pretty_print) - for participating_org_ in self.participating_org: - participating_org_.export(outfile, level, namespace_, name_='participating-org', pretty_print=pretty_print) - for activity_scope_ in self.activity_scope: - activity_scope_.export(outfile, level, namespace_, name_='activity-scope', pretty_print=pretty_print) - for recipient_country_ in self.recipient_country: - recipient_country_.export(outfile, level, namespace_, name_='recipient-country', pretty_print=pretty_print) - for recipient_region_ in self.recipient_region: - recipient_region_.export(outfile, level, namespace_, name_='recipient-region', pretty_print=pretty_print) - for collaboration_type_ in self.collaboration_type: - collaboration_type_.export(outfile, level, namespace_, name_='collaboration-type', pretty_print=pretty_print) - for default_flow_type_ in self.default_flow_type: - default_flow_type_.export(outfile, level, namespace_, name_='default-flow-type', pretty_print=pretty_print) - for default_aid_type_ in self.default_aid_type: - default_aid_type_.export(outfile, level, namespace_, name_='default-aid-type', pretty_print=pretty_print) - for default_finance_type_ in self.default_finance_type: - default_finance_type_.export(outfile, level, namespace_, name_='default-finance-type', pretty_print=pretty_print) - for iati_identifier_ in self.iati_identifier: - iati_identifier_.export(outfile, level, namespace_, name_='iati-identifier', pretty_print=pretty_print) - for other_identifier_ in self.other_identifier: - other_identifier_.export(outfile, level, namespace_, name_='other-identifier', pretty_print=pretty_print) - for title_ in self.title: - title_.export(outfile, level, namespace_, name_='title', pretty_print=pretty_print) - for description_ in self.description: - description_.export(outfile, level, namespace_, name_='description', pretty_print=pretty_print) - for sector_ in self.sector: - sector_.export(outfile, level, namespace_, name_='sector', pretty_print=pretty_print) - for activity_date_ in self.activity_date: - activity_date_.export(outfile, level, namespace_, name_='activity-date', pretty_print=pretty_print) - for activity_status_ in self.activity_status: - activity_status_.export(outfile, level, namespace_, name_='activity-status', pretty_print=pretty_print) - for contact_info_ in self.contact_info: - contact_info_.export(outfile, level, namespace_, name_='contact-info', pretty_print=pretty_print) - for default_tied_status_ in self.default_tied_status: - default_tied_status_.export(outfile, level, namespace_, name_='default-tied-status', pretty_print=pretty_print) - for policy_marker_ in self.policy_marker: - policy_marker_.export(outfile, level, namespace_, name_='policy-marker', pretty_print=pretty_print) - for location_ in self.location: - location_.export(outfile, level, namespace_, name_='location', pretty_print=pretty_print) - for capital_spend_ in self.capital_spend: - capital_spend_.export(outfile, level, namespace_, name_='capital-spend', pretty_print=pretty_print) - for transaction_ in self.transaction: - transaction_.export(outfile, level, namespace_, name_='transaction', pretty_print=pretty_print) - for result_ in self.result: - result_.export(outfile, level, namespace_, name_='result', pretty_print=pretty_print) - for conditions_ in self.conditions: - conditions_.export(outfile, level, namespace_, name_='conditions', pretty_print=pretty_print) - for budget_ in self.budget: - budget_.export(outfile, level, namespace_, name_='budget', pretty_print=pretty_print) - for planned_disbursement_ in self.planned_disbursement: - planned_disbursement_.export(outfile, level, namespace_, name_='planned-disbursement', pretty_print=pretty_print) - for country_budget_items_ in self.country_budget_items: - country_budget_items_.export(outfile, level, namespace_, name_='country-budget-items', pretty_print=pretty_print) - for related_activity_ in self.related_activity: - related_activity_.export(outfile, level, namespace_, name_='related-activity', pretty_print=pretty_print) - for document_link_ in self.document_link: - document_link_.export(outfile, level, namespace_, name_='document-link', pretty_print=pretty_print) - for legacy_data_ in self.legacy_data: - legacy_data_.export(outfile, level, namespace_, name_='legacy-data', pretty_print=pretty_print) - for crs_add_ in self.crs_add: - crs_add_.export(outfile, level, namespace_, name_='crs-add', pretty_print=pretty_print) - for fss_ in self.fss: - fss_.export(outfile, level, namespace_, name_='fss', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='iati-activity'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('xml:lang="%s",\n' % (self.lang,)) - if self.linked_data_uri is not None and 'linked_data_uri' not in already_processed: - already_processed.add('linked_data_uri') - showIndent(outfile, level) - outfile.write('linked_data_uri="%s",\n' % (self.linked_data_uri,)) - if self.hierarchy is not None and 'hierarchy' not in already_processed: - already_processed.add('hierarchy') - showIndent(outfile, level) - outfile.write('hierarchy=%d,\n' % (self.hierarchy,)) - if self.default_currency is not None and 'default_currency' not in already_processed: - already_processed.add('default_currency') - showIndent(outfile, level) - outfile.write('default_currency="%s",\n' % (self.default_currency,)) - if self.last_updated_datetime is not None and 'last_updated_datetime' not in already_processed: - already_processed.add('last_updated_datetime') - showIndent(outfile, level) - outfile.write('last-updated-datetime=model_.GeneratedsSuper.gds_parse_datetime("%s"),\n' % self.gds_format_datetime(self.last_updated_datetime, input_name='last-updated-datetime')) - if self.version is not None and 'version' not in already_processed: - already_processed.add('version') - showIndent(outfile, level) - outfile.write('version=%f,\n' % (self.version,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('activity_website=[\n') - level += 1 - for activity_website_ in self.activity_website: - showIndent(outfile, level) - outfile.write('model_.activity_website(\n') - activity_website_.exportLiteral(outfile, level, name_='activity-website') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('reporting_org=[\n') - level += 1 - for reporting_org_ in self.reporting_org: - showIndent(outfile, level) - outfile.write('model_.reporting_org(\n') - reporting_org_.exportLiteral(outfile, level, name_='reporting-org') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('participating_org=[\n') - level += 1 - for participating_org_ in self.participating_org: - showIndent(outfile, level) - outfile.write('model_.participating_org(\n') - participating_org_.exportLiteral(outfile, level, name_='participating-org') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('activity_scope=[\n') - level += 1 - for activity_scope_ in self.activity_scope: - showIndent(outfile, level) - outfile.write('model_.activity_scope(\n') - activity_scope_.exportLiteral(outfile, level, name_='activity-scope') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('recipient_country=[\n') - level += 1 - for recipient_country_ in self.recipient_country: - showIndent(outfile, level) - outfile.write('model_.recipient_country(\n') - recipient_country_.exportLiteral(outfile, level, name_='recipient-country') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('recipient_region=[\n') - level += 1 - for recipient_region_ in self.recipient_region: - showIndent(outfile, level) - outfile.write('model_.recipient_region(\n') - recipient_region_.exportLiteral(outfile, level, name_='recipient-region') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('collaboration_type=[\n') - level += 1 - for collaboration_type_ in self.collaboration_type: - showIndent(outfile, level) - outfile.write('model_.collaboration_type(\n') - collaboration_type_.exportLiteral(outfile, level, name_='collaboration-type') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('default_flow_type=[\n') - level += 1 - for default_flow_type_ in self.default_flow_type: - showIndent(outfile, level) - outfile.write('model_.default_flow_type(\n') - default_flow_type_.exportLiteral(outfile, level, name_='default-flow-type') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('default_aid_type=[\n') - level += 1 - for default_aid_type_ in self.default_aid_type: - showIndent(outfile, level) - outfile.write('model_.default_aid_type(\n') - default_aid_type_.exportLiteral(outfile, level, name_='default-aid-type') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('default_finance_type=[\n') - level += 1 - for default_finance_type_ in self.default_finance_type: - showIndent(outfile, level) - outfile.write('model_.default_finance_type(\n') - default_finance_type_.exportLiteral(outfile, level, name_='default-finance-type') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('iati_identifier=[\n') - level += 1 - for iati_identifier_ in self.iati_identifier: - showIndent(outfile, level) - outfile.write('model_.iati_identifier(\n') - iati_identifier_.exportLiteral(outfile, level, name_='iati-identifier') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('other_identifier=[\n') - level += 1 - for other_identifier_ in self.other_identifier: - showIndent(outfile, level) - outfile.write('model_.other_identifier(\n') - other_identifier_.exportLiteral(outfile, level, name_='other-identifier') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('title=[\n') - level += 1 - for title_ in self.title: - showIndent(outfile, level) - outfile.write('model_.title(\n') - title_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('description=[\n') - level += 1 - for description_ in self.description: - showIndent(outfile, level) - outfile.write('model_.description(\n') - description_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('sector=[\n') - level += 1 - for sector_ in self.sector: - showIndent(outfile, level) - outfile.write('model_.sector(\n') - sector_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('activity_date=[\n') - level += 1 - for activity_date_ in self.activity_date: - showIndent(outfile, level) - outfile.write('model_.activity_date(\n') - activity_date_.exportLiteral(outfile, level, name_='activity-date') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('activity_status=[\n') - level += 1 - for activity_status_ in self.activity_status: - showIndent(outfile, level) - outfile.write('model_.activity_status(\n') - activity_status_.exportLiteral(outfile, level, name_='activity-status') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('contact_info=[\n') - level += 1 - for contact_info_ in self.contact_info: - showIndent(outfile, level) - outfile.write('model_.contact_info(\n') - contact_info_.exportLiteral(outfile, level, name_='contact-info') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('default_tied_status=[\n') - level += 1 - for default_tied_status_ in self.default_tied_status: - showIndent(outfile, level) - outfile.write('model_.default_tied_status(\n') - default_tied_status_.exportLiteral(outfile, level, name_='default-tied-status') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('policy_marker=[\n') - level += 1 - for policy_marker_ in self.policy_marker: - showIndent(outfile, level) - outfile.write('model_.policy_marker(\n') - policy_marker_.exportLiteral(outfile, level, name_='policy-marker') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('location=[\n') - level += 1 - for location_ in self.location: - showIndent(outfile, level) - outfile.write('model_.location(\n') - location_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('capital_spend=[\n') - level += 1 - for capital_spend_ in self.capital_spend: - showIndent(outfile, level) - outfile.write('model_.capital_spend(\n') - capital_spend_.exportLiteral(outfile, level, name_='capital-spend') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('transaction=[\n') - level += 1 - for transaction_ in self.transaction: - showIndent(outfile, level) - outfile.write('model_.transaction(\n') - transaction_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('result=[\n') - level += 1 - for result_ in self.result: - showIndent(outfile, level) - outfile.write('model_.result(\n') - result_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('conditions=[\n') - level += 1 - for conditions_ in self.conditions: - showIndent(outfile, level) - outfile.write('model_.conditions(\n') - conditions_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('budget=[\n') - level += 1 - for budget_ in self.budget: - showIndent(outfile, level) - outfile.write('model_.budget(\n') - budget_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('planned_disbursement=[\n') - level += 1 - for planned_disbursement_ in self.planned_disbursement: - showIndent(outfile, level) - outfile.write('model_.planned_disbursement(\n') - planned_disbursement_.exportLiteral(outfile, level, name_='planned-disbursement') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('country_budget_items=[\n') - level += 1 - for country_budget_items_ in self.country_budget_items: - showIndent(outfile, level) - outfile.write('model_.country_budget_items(\n') - country_budget_items_.exportLiteral(outfile, level, name_='country-budget-items') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('related_activity=[\n') - level += 1 - for related_activity_ in self.related_activity: - showIndent(outfile, level) - outfile.write('model_.related_activity(\n') - related_activity_.exportLiteral(outfile, level, name_='related-activity') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('document_link=[\n') - level += 1 - for document_link_ in self.document_link: - showIndent(outfile, level) - outfile.write('model_.document_link(\n') - document_link_.exportLiteral(outfile, level, name_='document-link') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('legacy_data=[\n') - level += 1 - for legacy_data_ in self.legacy_data: - showIndent(outfile, level) - outfile.write('model_.legacy_data(\n') - legacy_data_.exportLiteral(outfile, level, name_='legacy-data') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('crs_add=[\n') - level += 1 - for crs_add_ in self.crs_add: - showIndent(outfile, level) - outfile.write('model_.crs_add(\n') - crs_add_.exportLiteral(outfile, level, name_='crs-add') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('fss=[\n') - level += 1 - for fss_ in self.fss: - showIndent(outfile, level) - outfile.write('model_.fss(\n') - fss_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('linked-data-uri', node) - if value is not None and 'linked-data-uri' not in already_processed: - already_processed.add('linked-data-uri') - self.linked_data_uri = value - value = find_attr_value_('hierarchy', node) - if value is not None and 'hierarchy' not in already_processed: - already_processed.add('hierarchy') - try: - self.hierarchy = int(value) - except ValueError, exp: - raise_parse_error(node, 'Bad integer attribute: %s' % exp) - value = find_attr_value_('default-currency', node) - if value is not None and 'default-currency' not in already_processed: - already_processed.add('default-currency') - self.default_currency = value - value = find_attr_value_('last-updated-datetime', node) - if value is not None and 'last-updated-datetime' not in already_processed: - already_processed.add('last-updated-datetime') - try: - self.last_updated_datetime = self.gds_parse_datetime(value) - except ValueError, exp: - raise ValueError('Bad date-time attribute (last-updated-datetime): %s' % exp) - value = find_attr_value_('version', node) - if value is not None and 'version' not in already_processed: - already_processed.add('version') - try: - self.version = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (version): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'activity-website': - obj_ = activity_website.factory() - obj_.build(child_) - self.activity_website.append(obj_) - elif nodeName_ == 'reporting-org': - obj_ = reporting_org.factory() - obj_.build(child_) - self.reporting_org.append(obj_) - elif nodeName_ == 'participating-org': - obj_ = participating_org.factory() - obj_.build(child_) - self.participating_org.append(obj_) - elif nodeName_ == 'activity-scope': - obj_ = codeType.factory() - obj_.build(child_) - self.activity_scope.append(obj_) - elif nodeName_ == 'recipient-country': - obj_ = recipient_country.factory() - obj_.build(child_) - self.recipient_country.append(obj_) - elif nodeName_ == 'recipient-region': - obj_ = recipient_region.factory() - obj_.build(child_) - self.recipient_region.append(obj_) - elif nodeName_ == 'collaboration-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.collaboration_type.append(obj_) - elif nodeName_ == 'default-flow-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.default_flow_type.append(obj_) - elif nodeName_ == 'default-aid-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.default_aid_type.append(obj_) - elif nodeName_ == 'default-finance-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.default_finance_type.append(obj_) - elif nodeName_ == 'iati-identifier': - obj_ = iati_identifier.factory() - obj_.build(child_) - self.iati_identifier.append(obj_) - elif nodeName_ == 'other-identifier': - obj_ = other_identifier.factory() - obj_.build(child_) - self.other_identifier.append(obj_) - elif nodeName_ == 'title': - obj_ = textType.factory() - obj_.build(child_) - self.title.append(obj_) - elif nodeName_ == 'description': - obj_ = description.factory() - obj_.build(child_) - self.description.append(obj_) - elif nodeName_ == 'sector': - obj_ = sector.factory() - obj_.build(child_) - self.sector.append(obj_) - elif nodeName_ == 'activity-date': - obj_ = activity_date.factory() - obj_.build(child_) - self.activity_date.append(obj_) - elif nodeName_ == 'activity-status': - obj_ = codeType.factory() - obj_.build(child_) - self.activity_status.append(obj_) - elif nodeName_ == 'contact-info': - obj_ = contact_info.factory() - obj_.build(child_) - self.contact_info.append(obj_) - elif nodeName_ == 'default-tied-status': - obj_ = codeReqType.factory() - obj_.build(child_) - self.default_tied_status.append(obj_) - elif nodeName_ == 'policy-marker': - obj_ = policy_marker.factory() - obj_.build(child_) - self.policy_marker.append(obj_) - elif nodeName_ == 'location': - obj_ = location.factory() - obj_.build(child_) - self.location.append(obj_) - elif nodeName_ == 'capital-spend': - obj_ = capital_spend.factory() - obj_.build(child_) - self.capital_spend.append(obj_) - elif nodeName_ == 'transaction': - obj_ = transaction.factory() - obj_.build(child_) - self.transaction.append(obj_) - elif nodeName_ == 'result': - obj_ = result.factory() - obj_.build(child_) - self.result.append(obj_) - elif nodeName_ == 'conditions': - obj_ = conditions.factory() - obj_.build(child_) - self.conditions.append(obj_) - elif nodeName_ == 'budget': - obj_ = budget.factory() - obj_.build(child_) - self.budget.append(obj_) - elif nodeName_ == 'planned-disbursement': - obj_ = planned_disbursement.factory() - obj_.build(child_) - self.planned_disbursement.append(obj_) - elif nodeName_ == 'country-budget-items': - obj_ = country_budget_items.factory() - obj_.build(child_) - self.country_budget_items.append(obj_) - elif nodeName_ == 'related-activity': - obj_ = related_activity.factory() - obj_.build(child_) - self.related_activity.append(obj_) - elif nodeName_ == 'document-link': - obj_ = document_link.factory() - obj_.build(child_) - self.document_link.append(obj_) - elif nodeName_ == 'legacy-data': - obj_ = legacy_data.factory() - obj_.build(child_) - self.legacy_data.append(obj_) - elif nodeName_ == 'crs-add': - obj_ = crs_add.factory() - obj_.build(child_) - self.crs_add.append(obj_) - elif nodeName_ == 'fss': - obj_ = fss.factory() - obj_.build(child_) - self.fss.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'iati-activity') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class iati_activity - - -class activity_website(GeneratedsSuper): - """A link to a web site providing more information about the aid - activity. Multiple versions of the link may appear for different - languages.""" - subclass = None - superclass = None - def __init__(self, valueOf_=None): - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if activity_website.subclass: - return activity_website.subclass(*args_, **kwargs_) - else: - return activity_website(*args_, **kwargs_) - factory = staticmethod(factory) - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='activity-website', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='activity-website') - if self.hasContent_(): - outfile.write('>') - outfile.write(str(self.valueOf_).encode(ExternalEncoding)) - self.exportChildren(outfile, level + 1, namespace_='', name_='activity-website', pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='activity-website'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - pass - def exportChildren(self, outfile, level, namespace_='', name_='activity-website', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='activity-website'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - pass -# end class activity_website - - -class participating_org(GeneratedsSuper): - """An organisation (including the reporting organisation) involved with - the activity. May be a donor, fund, agency, etc. Specifying the - @identifier and @role attributes is strongly recommended. May - contain the organisation name as content. For the value of the - @type attribute, see http://iatistandard.org/codelists - /organisation-type For the value of the @ref attribute, see the - list of officially-registered organizations at - http://iatistandard.org/codelists/organisation A code describing - the organisation's role in the activity (donor, agency, etc.). - See http://iatistandard.org/codelists/organisation_role""" - subclass = None - superclass = None - def __init__(self, lang=None, type_=None, role=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.type_ = _cast(None, type_) - self.role = _cast(None, role) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if participating_org.subclass: - return participating_org.subclass(*args_, **kwargs_) - else: - return participating_org(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_role(self): return self.role - def set_role(self, role): self.role = role - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='participating-org', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='participating-org') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile, level) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='participating-org'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - if self.role is not None and 'role' not in already_processed: - already_processed.add('role') - outfile.write(' role=%s' % (self.gds_format_string(quote_attrib(self.role).encode(ExternalEncoding), input_name='role'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='participating-org', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='participating-org'): - #level += 1 - #already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - if self.role is not None and 'role' not in already_processed: - already_processed.add('role') - showIndent(outfile, level) - outfile.write('role="%s",\n' % (self.role,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - value = find_attr_value_('role', node) - if value is not None and 'role' not in already_processed: - already_processed.add('role') - self.role = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class participating_org - - -class recipient_country(GeneratedsSuper): - """A partner country that will benefit from this activity. This element - is primarily for administrative and geopolitical purposes. If a - specific country is not known, the activity report can use the - recipient-region element instead. For geographical location, use - the location element. For the value of the @code attribute, see - http://iatistandard.org/codelists/country""" - subclass = None - superclass = None - def __init__(self, lang=None, percentage=None, code=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.percentage = _cast(None, percentage) - self.code = _cast(None, code) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if recipient_country.subclass: - return recipient_country.subclass(*args_, **kwargs_) - else: - return recipient_country(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_percentage(self): return self.percentage - def set_percentage(self, percentage): self.percentage = percentage - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='recipient-country', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='recipient-country') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile, level) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='recipient-country'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - outfile.write(' percentage=%s' % (self.gds_format_string(quote_attrib(self.percentage).encode(ExternalEncoding), input_name='percentage'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - def exportChildren(self, outfile, level, namespace_='', name_='recipient-country', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='recipient-country'): - #level += 1 - #already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - showIndent(outfile, level) - outfile.write('percentage="%s",\n' % (self.percentage,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('percentage', node) - if value is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - self.percentage = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class recipient_country - - -class recipient_region(GeneratedsSuper): - """A geopolitical region (above the country level) that will benefit - from this activity. This element is primarily for administrative - and geopolitical purposes. If the specific country/-ies are - known, the activity report can use the recipient-country element - instead. For geographical location, use the location element. - For the value of the @code attribute, see - http://iatistandard.org/codelists/region The vocabulary from - which the region code is drawn. If it is not present 1 - 'OECD - DAC' is assumed.""" - subclass = None - superclass = None - def __init__(self, lang=None, percentage=None, code=None, vocabulary=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.percentage = _cast(None, percentage) - self.code = _cast(None, code) - self.vocabulary = _cast(None, vocabulary) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if recipient_region.subclass: - return recipient_region.subclass(*args_, **kwargs_) - else: - return recipient_region(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_percentage(self): return self.percentage - def set_percentage(self, percentage): self.percentage = percentage - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_vocabulary(self): return self.vocabulary - def set_vocabulary(self, vocabulary): self.vocabulary = vocabulary - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='recipient-region', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='recipient-region') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='recipient-region', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='recipient-region'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - outfile.write(' percentage=%s' % (self.gds_format_string(quote_attrib(self.percentage).encode(ExternalEncoding), input_name='percentage'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - outfile.write(' vocabulary=%s' % (self.gds_format_string(quote_attrib(self.vocabulary).encode(ExternalEncoding), input_name='vocabulary'), )) - def exportChildren(self, outfile, level, namespace_='', name_='recipient-region', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='recipient-region'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - showIndent(outfile, level) - outfile.write('percentage="%s",\n' % (self.percentage,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - showIndent(outfile, level) - outfile.write('vocabulary="%s",\n' % (self.vocabulary,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('percentage', node) - if value is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - self.percentage = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - value = find_attr_value_('vocabulary', node) - if value is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - self.vocabulary = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class recipient_region - - -class other_identifier(GeneratedsSuper): - """An alternative, non-IATI identifier for the activity. This - identifier is not guaranteed to be unique or persistent (it - depends on the owner organisation's policies, not IATI's). If - other-identifier is present then either @owner-ref or @owner- - name must be present An identifier for the owner of this - identifier, in URI format. See the list of officially-registered - organizations at http://iatistandard.org/codelists/organisation - Free text providing a human-readable name for the owner of this - identifier.""" - subclass = None - superclass = None - def __init__(self, owner_ref=None, owner_name=None, valueOf_=None, mixedclass_=None, content_=None): - self.owner_ref = _cast(None, owner_ref) - self.owner_name = _cast(None, owner_name) - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if other_identifier.subclass: - return other_identifier.subclass(*args_, **kwargs_) - else: - return other_identifier(*args_, **kwargs_) - factory = staticmethod(factory) - def get_owner_ref(self): return self.owner_ref - def set_owner_ref(self, owner_ref): self.owner_ref = owner_ref - def get_owner_name(self): return self.owner_name - def set_owner_name(self, owner_name): self.owner_name = owner_name - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='other-identifier', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='other-identifier') - outfile.write('>') - self.exportLiteral(outfile, level) - outfile.write('%s' % (namespace_, name_, eol_)) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='other-identifier'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.owner_ref is not None and 'owner_ref' not in already_processed: - already_processed.add('owner_ref') - outfile.write(' owner-ref=%s' % (self.gds_format_string(quote_attrib(self.owner_ref).encode(ExternalEncoding), input_name='owner-ref'), )) - if self.owner_name is not None and 'owner_name' not in already_processed: - already_processed.add('owner_name') - outfile.write(' owner-name=%s' % (self.gds_format_string(quote_attrib(self.owner_name).encode(ExternalEncoding), input_name='owner-name'), )) - def exportChildren(self, outfile, level, namespace_='', name_='other-identifier', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='other-identifier'): - #level += 1 - #already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.owner_ref is not None and 'owner_ref' not in already_processed: - already_processed.add('owner_ref') - showIndent(outfile, level) - outfile.write('owner_ref="%s",\n' % (self.owner_ref,)) - if self.owner_name is not None and 'owner_name' not in already_processed: - already_processed.add('owner_name') - showIndent(outfile, level) - outfile.write('owner_name="%s",\n' % (self.owner_name,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('owner-ref', node) - if value is not None and 'owner-ref' not in already_processed: - already_processed.add('owner-ref') - self.owner_ref = value - value = find_attr_value_('owner-name', node) - if value is not None and 'owner-name' not in already_processed: - already_processed.add('owner-name') - self.owner_name = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) - pass -# end class other_identifier - - -class sector(GeneratedsSuper): - """Sector code and name. For the value of the @code attribute, see - http://iatistandard.org/codelists/sector Either the @code - attribute or descriptive text content must be present. The code - for the sector. If the vocabulary is "DAC" or missing then the - CRS Sector Code should be used. Code is not mandatory but highly - recommended. Either code or description must be present. The - vocabulary (codelist) used for sector classifications. If - omitted, assume DAC. "DAC" codes should be used wherever - possible. It is also recommended that if a publisher has its own - classification system then the vocabulary "RO" (Reporting - Organisation's own vocabulary" should be used in addition to - "DAC". NB that if multiple sector codes are used in multiple - vocabularies then each vocabulary's percentages should add up to - 100%. See http://iatistandard.org/codelists/vocabulary""" - subclass = None - superclass = None - def __init__(self, lang=None, percentage=None, code=None, vocabulary=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.percentage = _cast(None, percentage) - self.code = _cast(None, code) - self.vocabulary = _cast(None, vocabulary) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if sector.subclass: - return sector.subclass(*args_, **kwargs_) - else: - return sector(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_percentage(self): return self.percentage - def set_percentage(self, percentage): self.percentage = percentage - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_vocabulary(self): return self.vocabulary - def set_vocabulary(self, vocabulary): self.vocabulary = vocabulary - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='sector', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='sector') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile, level) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='sector'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - outfile.write(' percentage=%s' % (self.gds_format_string(quote_attrib(self.percentage).encode(ExternalEncoding), input_name='percentage'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - outfile.write(' vocabulary=%s' % (self.gds_format_string(quote_attrib(self.vocabulary).encode(ExternalEncoding), input_name='vocabulary'), )) - def exportChildren(self, outfile, level, namespace_='', name_='sector', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='sector'): - # level += 1 - # already_processed = set() - # self.exportLiteralAttributes(outfile, level, already_processed, name_) - # if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - # showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - showIndent(outfile, level) - outfile.write('percentage="%s",\n' % (self.percentage,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - showIndent(outfile, level) - outfile.write('vocabulary="%s",\n' % (self.vocabulary,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('percentage', node) - if value is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - self.percentage = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - value = find_attr_value_('vocabulary', node) - if value is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - self.vocabulary = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class sector - - -class activity_date(GeneratedsSuper): - """The planned and actual start and completion dates of the activity. - Start dates may reflect either the commencement of funding, - planning or physical activity. End dates should, wherever - possible, reflect the ending of physical activity. Dates should - be in ISO 8601 date YYYY-MM-DD format, e.g. 2010-10-01. For the - value of the @type attribute, see - http://iatistandard.org/codelists/activity_date_type The text - content may contain a general date text (e.g. 2011Q1) for - recording less specific dates such as month, quarter, or year. - An activity milestone date in ISO 8601 date format, e.g. - "2010-12-01".""" - subclass = None - superclass = None - def __init__(self, lang=None, iso_date=None, type_=None, valueOf_=None): - self.lang = _cast(None, lang) - if isinstance(iso_date, basestring): - initvalue_ = datetime_.datetime.strptime(iso_date, '%Y-%m-%d').date() - else: - initvalue_ = iso_date - self.iso_date = initvalue_ - self.type_ = _cast(None, type_) - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if activity_date.subclass: - return activity_date.subclass(*args_, **kwargs_) - else: - return activity_date(*args_, **kwargs_) - factory = staticmethod(factory) - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_iso_date(self): return self.iso_date - def set_iso_date(self, iso_date): self.iso_date = iso_date - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='activity-date', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='activity-date') - if self.hasContent_(): - outfile.write('>') - outfile.write(str(self.valueOf_).encode(ExternalEncoding)) - self.exportChildren(outfile, level + 1, namespace_='', name_='activity-date', pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='activity-date'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - outfile.write(' iso-date="%s"' % self.gds_format_date(self.iso_date, input_name='iso-date')) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - def exportChildren(self, outfile, level, namespace_='', name_='activity-date', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='activity-date'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - showIndent(outfile, level) - outfile.write('iso-date=model_.GeneratedsSuper.gds_parse_date("%s"),\n' % self.gds_format_date(self.iso_date, input_name='iso-date')) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('iso-date', node) - if value is not None and 'iso-date' not in already_processed: - already_processed.add('iso-date') - try: - self.iso_date = self.gds_parse_date(value) - except ValueError, exp: - raise ValueError('Bad date attribute (iso-date): %s' % exp) - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - pass -# end class activity_date - - -class contact_info(GeneratedsSuper): - """Contact information for the project. Specify whatever is available. - You may repeat this element for each contact person.""" - subclass = None - superclass = None - def __init__(self, type_=None, organisation=None, person_name=None, job_title=None, telephone=None, email=None, mailing_address=None, website=None, anytypeobjs_=None): - self.type_ = _cast(None, type_) - if organisation is None: - self.organisation = [] - else: - self.organisation = organisation - if person_name is None: - self.person_name = [] - else: - self.person_name = person_name - if job_title is None: - self.job_title = [] - else: - self.job_title = job_title - if telephone is None: - self.telephone = [] - else: - self.telephone = telephone - if email is None: - self.email = [] - else: - self.email = email - if mailing_address is None: - self.mailing_address = [] - else: - self.mailing_address = mailing_address - if website is None: - self.website = [] - else: - self.website = website - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if contact_info.subclass: - return contact_info.subclass(*args_, **kwargs_) - else: - return contact_info(*args_, **kwargs_) - factory = staticmethod(factory) - def get_organisation(self): return self.organisation - def set_organisation(self, organisation): self.organisation = organisation - def add_organisation(self, value): self.organisation.append(value) - def insert_organisation(self, index, value): self.organisation[index] = value - def get_person_name(self): return self.person_name - def set_person_name(self, person_name): self.person_name = person_name - def add_person_name(self, value): self.person_name.append(value) - def insert_person_name(self, index, value): self.person_name[index] = value - def get_job_title(self): return self.job_title - def set_job_title(self, job_title): self.job_title = job_title - def add_job_title(self, value): self.job_title.append(value) - def insert_job_title(self, index, value): self.job_title[index] = value - def get_telephone(self): return self.telephone - def set_telephone(self, telephone): self.telephone = telephone - def add_telephone(self, value): self.telephone.append(value) - def insert_telephone(self, index, value): self.telephone[index] = value - def get_email(self): return self.email - def set_email(self, email): self.email = email - def add_email(self, value): self.email.append(value) - def insert_email(self, index, value): self.email[index] = value - def get_mailing_address(self): return self.mailing_address - def set_mailing_address(self, mailing_address): self.mailing_address = mailing_address - def add_mailing_address(self, value): self.mailing_address.append(value) - def insert_mailing_address(self, index, value): self.mailing_address[index] = value - def get_website(self): return self.website - def set_website(self, website): self.website = website - def add_website(self, value): self.website.append(value) - def insert_website(self, index, value): self.website[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.organisation or - self.person_name or - self.job_title or - self.telephone or - self.email or - self.mailing_address or - self.website or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='contact-info', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='contact-info') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='contact-info', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='contact-info'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - def exportChildren(self, outfile, level, namespace_='', name_='contact-info', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for organisation_ in self.organisation: - organisation_.export(outfile, level, namespace_, name_='organisation', pretty_print=pretty_print) - for person_name_ in self.person_name: - person_name_.export(outfile, level, namespace_, name_='person-name', pretty_print=pretty_print) - for job_title_ in self.job_title: - job_title_.export(outfile, level, namespace_, name_='job-title', pretty_print=pretty_print) - for telephone_ in self.telephone: - telephone_.export(outfile, level, namespace_, name_='telephone', pretty_print=pretty_print) - for email_ in self.email: - email_.export(outfile, level, namespace_, name_='email', pretty_print=pretty_print) - for mailing_address_ in self.mailing_address: - mailing_address_.export(outfile, level, namespace_, name_='mailing-address', pretty_print=pretty_print) - for website_ in self.website: - showIndent(outfile, level, pretty_print) - outfile.write('<%swebsite>%s%s' % (namespace_, self.gds_format_string(quote_xml(website_).encode(ExternalEncoding), input_name='website'), namespace_, eol_)) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='contact-info'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('organisation=[\n') - level += 1 - for organisation_ in self.organisation: - showIndent(outfile, level) - outfile.write('model_.textType(\n') - organisation_.exportLiteral(outfile, level, name_='textType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('person_name=[\n') - level += 1 - for person_name_ in self.person_name: - showIndent(outfile, level) - outfile.write('model_.textType(\n') - person_name_.exportLiteral(outfile, level, name_='textType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('job_title=[\n') - level += 1 - for job_title_ in self.job_title: - showIndent(outfile, level) - outfile.write('model_.textType(\n') - job_title_.exportLiteral(outfile, level, name_='textType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('telephone=[\n') - level += 1 - for telephone_ in self.telephone: - showIndent(outfile, level) - outfile.write('model_.telephoneType(\n') - telephone_.exportLiteral(outfile, level, name_='telephoneType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('email=[\n') - level += 1 - for email_ in self.email: - showIndent(outfile, level) - outfile.write('model_.plainType(\n') - email_.exportLiteral(outfile, level, name_='plainType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('mailing_address=[\n') - level += 1 - for mailing_address_ in self.mailing_address: - showIndent(outfile, level) - outfile.write('model_.mailing_addressType(\n') - mailing_address_.exportLiteral(outfile, level, name_='mailing-addressType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('website=[\n') - level += 1 - for website_ in self.website: - showIndent(outfile, level) - outfile.write('%s,\n' % quote_python(website_).encode(ExternalEncoding)) - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'organisation': - obj_ = textType.factory() - obj_.build(child_) - self.organisation.append(obj_) - elif nodeName_ == 'person-name': - obj_ = textType.factory() - obj_.build(child_) - self.person_name.append(obj_) - elif nodeName_ == 'job-title': - obj_ = textType.factory() - obj_.build(child_) - self.job_title.append(obj_) - elif nodeName_ == 'telephone': - obj_ = telephoneType.factory() - obj_.build(child_) - self.telephone.append(obj_) - elif nodeName_ == 'email': - obj_ = plainType.factory() - obj_.build(child_) - self.email.append(obj_) - elif nodeName_ == 'mailing-address': - obj_ = mailing_addressType.factory() - obj_.build(child_) - self.mailing_address.append(obj_) - elif nodeName_ == 'website': - website_ = child_.text - website_ = self.gds_validate_string(website_, node, 'website') - self.website.append(website_) - else: - obj_ = self.gds_build_any(child_, 'contact-info') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class contact_info - - -class policy_marker(GeneratedsSuper): - """A policy or theme addressed by the activity. A text description of - the theme appears in the content, and a formal identifier - appears in the @ref attribute. The @vocabulary attribute can - also help to segment the markers into separate vocabularies. - This element can be repeated for each policy marker. For the - value of the @code attribute, see - http://iatistandard.org/codelists/policy_marker Policy marker - code. If vocabulary is missing or "DAC" use the IATI Policy - Marker Code list which is based on columns 20-23 and 28-31 of - the CRS++ reporting format. Policy vocabulary used. Default is - "DAC", but "RO" may also be used for publisher's own markers. - See http://iatistandard.org/codelists/vocabulary The - significance of the policy marker for this activity (e.g. - principal or significant), from a list defined by IATI. If a - marker is not significant, the policy-marker element will not be - present. See - http://iatistandard.org/codelists/policy_significance""" - subclass = None - superclass = None - def __init__(self, lang=None, code=None, vocabulary=None, significance=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.code = _cast(None, code) - self.vocabulary = _cast(None, vocabulary) - self.significance = _cast(None, significance) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if policy_marker.subclass: - return policy_marker.subclass(*args_, **kwargs_) - else: - return policy_marker(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_vocabulary(self): return self.vocabulary - def set_vocabulary(self, vocabulary): self.vocabulary = vocabulary - def get_significance(self): return self.significance - def set_significance(self, significance): self.significance = significance - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='policy-marker', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='policy-marker') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='policy-marker', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='policy-marker'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - outfile.write(' vocabulary=%s' % (self.gds_format_string(quote_attrib(self.vocabulary).encode(ExternalEncoding), input_name='vocabulary'), )) - if self.significance is not None and 'significance' not in already_processed: - already_processed.add('significance') - outfile.write(' significance=%s' % (self.gds_format_string(quote_attrib(self.significance).encode(ExternalEncoding), input_name='significance'), )) - def exportChildren(self, outfile, level, namespace_='', name_='policy-marker', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='policy-marker'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - showIndent(outfile, level) - outfile.write('vocabulary="%s",\n' % (self.vocabulary,)) - if self.significance is not None and 'significance' not in already_processed: - already_processed.add('significance') - showIndent(outfile, level) - outfile.write('significance="%s",\n' % (self.significance,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - value = find_attr_value_('vocabulary', node) - if value is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - self.vocabulary = value - value = find_attr_value_('significance', node) - if value is not None and 'significance' not in already_processed: - already_processed.add('significance') - self.significance = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class policy_marker - - -class capital_spend(GeneratedsSuper): - """The percentage of the total commitment that is for capital spending""" - subclass = None - superclass = None - def __init__(self, percentage=None, anytypeobjs_=None): - self.percentage = _cast(None, percentage) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if capital_spend.subclass: - return capital_spend.subclass(*args_, **kwargs_) - else: - return capital_spend(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_percentage(self): return self.percentage - def set_percentage(self, percentage): self.percentage = percentage - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='capital-spend', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='capital-spend') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='capital-spend', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='capital-spend'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - outfile.write(' percentage=%s' % (self.gds_format_string(quote_attrib(self.percentage).encode(ExternalEncoding), input_name='percentage'), )) - def exportChildren(self, outfile, level, namespace_='', name_='capital-spend', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for obj_ in self.anytypeobjs_: - obj_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='capital-spend'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - showIndent(outfile, level) - outfile.write('percentage="%s",\n' % (self.percentage,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('anytypeobjs_=[\n') - level += 1 - for anytypeobjs_ in self.anytypeobjs_: - anytypeobjs_.exportLiteral(outfile, level) - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('percentage', node) - if value is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - self.percentage = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - obj_ = self.gds_build_any(child_, 'capital-spend') - if obj_ is not None: - self.add_anytypeobjs_(obj_) -# end class capital_spend - - -class transaction(GeneratedsSuper): - """Committed or actual money flowing in or out of an aid activity.The - @ref attribute allows uniquely identifying a transaction, to - match it up with the corresponding in- or outflow in a different - activity.""" - subclass = None - superclass = None - def __init__(self, ref=None, value=None, description=None, transaction_type=None, provider_org=None, receiver_org=None, transaction_date=None, flow_type=None, aid_type=None, finance_type=None, tied_status=None, disbursement_channel=None, anytypeobjs_=None): - self.ref = _cast(None, ref) - if value is None: - self.value = [] - else: - self.value = value - if description is None: - self.description = [] - else: - self.description = description - if transaction_type is None: - self.transaction_type = [] - else: - self.transaction_type = transaction_type - if provider_org is None: - self.provider_org = [] - else: - self.provider_org = provider_org - if receiver_org is None: - self.receiver_org = [] - else: - self.receiver_org = receiver_org - if transaction_date is None: - self.transaction_date = [] - else: - self.transaction_date = transaction_date - if flow_type is None: - self.flow_type = [] - else: - self.flow_type = flow_type - if aid_type is None: - self.aid_type = [] - else: - self.aid_type = aid_type - if finance_type is None: - self.finance_type = [] - else: - self.finance_type = finance_type - if tied_status is None: - self.tied_status = [] - else: - self.tied_status = tied_status - if disbursement_channel is None: - self.disbursement_channel = [] - else: - self.disbursement_channel = disbursement_channel - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if transaction.subclass: - return transaction.subclass(*args_, **kwargs_) - else: - return transaction(*args_, **kwargs_) - factory = staticmethod(factory) - def get_value(self): return self.value - def set_value(self, value): self.value = value - def add_value(self, value): self.value.append(value) - def insert_value(self, index, value): self.value[index] = value - def get_description(self): return self.description - def set_description(self, description): self.description = description - def add_description(self, value): self.description.append(value) - def insert_description(self, index, value): self.description[index] = value - def get_transaction_type(self): return self.transaction_type - def set_transaction_type(self, transaction_type): self.transaction_type = transaction_type - def add_transaction_type(self, value): self.transaction_type.append(value) - def insert_transaction_type(self, index, value): self.transaction_type[index] = value - def get_provider_org(self): return self.provider_org - def set_provider_org(self, provider_org): self.provider_org = provider_org - def add_provider_org(self, value): self.provider_org.append(value) - def insert_provider_org(self, index, value): self.provider_org[index] = value - def get_receiver_org(self): return self.receiver_org - def set_receiver_org(self, receiver_org): self.receiver_org = receiver_org - def add_receiver_org(self, value): self.receiver_org.append(value) - def insert_receiver_org(self, index, value): self.receiver_org[index] = value - def get_transaction_date(self): return self.transaction_date - def set_transaction_date(self, transaction_date): self.transaction_date = transaction_date - def add_transaction_date(self, value): self.transaction_date.append(value) - def insert_transaction_date(self, index, value): self.transaction_date[index] = value - def get_flow_type(self): return self.flow_type - def set_flow_type(self, flow_type): self.flow_type = flow_type - def add_flow_type(self, value): self.flow_type.append(value) - def insert_flow_type(self, index, value): self.flow_type[index] = value - def get_aid_type(self): return self.aid_type - def set_aid_type(self, aid_type): self.aid_type = aid_type - def add_aid_type(self, value): self.aid_type.append(value) - def insert_aid_type(self, index, value): self.aid_type[index] = value - def get_finance_type(self): return self.finance_type - def set_finance_type(self, finance_type): self.finance_type = finance_type - def add_finance_type(self, value): self.finance_type.append(value) - def insert_finance_type(self, index, value): self.finance_type[index] = value - def get_tied_status(self): return self.tied_status - def set_tied_status(self, tied_status): self.tied_status = tied_status - def add_tied_status(self, value): self.tied_status.append(value) - def insert_tied_status(self, index, value): self.tied_status[index] = value - def get_disbursement_channel(self): return self.disbursement_channel - def set_disbursement_channel(self, disbursement_channel): self.disbursement_channel = disbursement_channel - def add_disbursement_channel(self, value): self.disbursement_channel.append(value) - def insert_disbursement_channel(self, index, value): self.disbursement_channel[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.value or - self.description or - self.transaction_type or - self.provider_org or - self.receiver_org or - self.transaction_date or - self.flow_type or - self.aid_type or - self.finance_type or - self.tied_status or - self.disbursement_channel or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='transaction', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='transaction') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='transaction', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='transaction'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='transaction', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for value_ in self.value: - value_.export(outfile, level, namespace_, name_='value', pretty_print=pretty_print) - for description_ in self.description: - description_.export(outfile, level, namespace_, name_='description', pretty_print=pretty_print) - for transaction_type_ in self.transaction_type: - transaction_type_.export(outfile, level, namespace_, name_='transaction-type', pretty_print=pretty_print) - for provider_org_ in self.provider_org: - provider_org_.export(outfile, level, namespace_, name_='provider-org', pretty_print=pretty_print) - for receiver_org_ in self.receiver_org: - receiver_org_.export(outfile, level, namespace_, name_='receiver-org', pretty_print=pretty_print) - for transaction_date_ in self.transaction_date: - transaction_date_.export(outfile, level, namespace_, name_='transaction-date', pretty_print=pretty_print) - for flow_type_ in self.flow_type: - flow_type_.export(outfile, level, namespace_, name_='flow-type', pretty_print=pretty_print) - for aid_type_ in self.aid_type: - aid_type_.export(outfile, level, namespace_, name_='aid-type', pretty_print=pretty_print) - for finance_type_ in self.finance_type: - finance_type_.export(outfile, level, namespace_, name_='finance-type', pretty_print=pretty_print) - for tied_status_ in self.tied_status: - tied_status_.export(outfile, level, namespace_, name_='tied-status', pretty_print=pretty_print) - for disbursement_channel_ in self.disbursement_channel: - disbursement_channel_.export(outfile, level, namespace_, name_='disbursement-channel', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='transaction'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('value=[\n') - level += 1 - for value_ in self.value: - showIndent(outfile, level) - outfile.write('model_.currencyType(\n') - value_.exportLiteral(outfile, level, name_='currencyType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('description=[\n') - level += 1 - for description_ in self.description: - showIndent(outfile, level) - outfile.write('model_.textType(\n') - description_.exportLiteral(outfile, level, name_='textType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('transaction_type=[\n') - level += 1 - for transaction_type_ in self.transaction_type: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - transaction_type_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('provider_org=[\n') - level += 1 - for provider_org_ in self.provider_org: - showIndent(outfile, level) - outfile.write('model_.provider_orgType(\n') - provider_org_.exportLiteral(outfile, level, name_='provider-orgType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('receiver_org=[\n') - level += 1 - for receiver_org_ in self.receiver_org: - showIndent(outfile, level) - outfile.write('model_.receiver_orgType(\n') - receiver_org_.exportLiteral(outfile, level, name_='receiver-orgType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('transaction_date=[\n') - level += 1 - for transaction_date_ in self.transaction_date: - showIndent(outfile, level) - outfile.write('model_.transaction_dateType(\n') - transaction_date_.exportLiteral(outfile, level, name_='transaction-dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('flow_type=[\n') - level += 1 - for flow_type_ in self.flow_type: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - flow_type_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('aid_type=[\n') - level += 1 - for aid_type_ in self.aid_type: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - aid_type_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('finance_type=[\n') - level += 1 - for finance_type_ in self.finance_type: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - finance_type_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('tied_status=[\n') - level += 1 - for tied_status_ in self.tied_status: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - tied_status_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('disbursement_channel=[\n') - level += 1 - for disbursement_channel_ in self.disbursement_channel: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - disbursement_channel_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'value': - obj_ = currencyType.factory() - obj_.build(child_) - self.value.append(obj_) - elif nodeName_ == 'description': - obj_ = textType.factory() - obj_.build(child_) - self.description.append(obj_) - elif nodeName_ == 'transaction-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.transaction_type.append(obj_) - elif nodeName_ == 'provider-org': - obj_ = provider_orgType.factory() - obj_.build(child_) - self.provider_org.append(obj_) - elif nodeName_ == 'receiver-org': - obj_ = receiver_orgType.factory() - obj_.build(child_) - self.receiver_org.append(obj_) - elif nodeName_ == 'transaction-date': - obj_ = transaction_dateType.factory() - obj_.build(child_) - self.transaction_date.append(obj_) - elif nodeName_ == 'flow-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.flow_type.append(obj_) - elif nodeName_ == 'aid-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.aid_type.append(obj_) - elif nodeName_ == 'finance-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.finance_type.append(obj_) - elif nodeName_ == 'tied-status': - obj_ = codeReqType.factory() - obj_.build(child_) - self.tied_status.append(obj_) - elif nodeName_ == 'disbursement-channel': - obj_ = codeReqType.factory() - obj_.build(child_) - self.disbursement_channel.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'transaction') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class transaction - - -class location(GeneratedsSuper): - """A geographical location.""" - subclass = None - superclass = None - def __init__(self, percentage=None, location_type=None, name=None, description=None, administrative=None, coordinates=None, gazetteer_entry=None, anytypeobjs_=None): - self.percentage = _cast(None, percentage) - if location_type is None: - self.location_type = [] - else: - self.location_type = location_type - if name is None: - self.name = [] - else: - self.name = name - if description is None: - self.description = [] - else: - self.description = description - if administrative is None: - self.administrative = [] - else: - self.administrative = administrative - if coordinates is None: - self.coordinates = [] - else: - self.coordinates = coordinates - if gazetteer_entry is None: - self.gazetteer_entry = [] - else: - self.gazetteer_entry = gazetteer_entry - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if location.subclass: - return location.subclass(*args_, **kwargs_) - else: - return location(*args_, **kwargs_) - factory = staticmethod(factory) - def get_location_type(self): return self.location_type - def set_location_type(self, location_type): self.location_type = location_type - def add_location_type(self, value): self.location_type.append(value) - def insert_location_type(self, index, value): self.location_type[index] = value - def get_name(self): return self.name - def set_name(self, name): self.name = name - def add_name(self, value): self.name.append(value) - def insert_name(self, index, value): self.name[index] = value - def get_description(self): return self.description - def set_description(self, description): self.description = description - def add_description(self, value): self.description.append(value) - def insert_description(self, index, value): self.description[index] = value - def get_administrative(self): return self.administrative - def set_administrative(self, administrative): self.administrative = administrative - def add_administrative(self, value): self.administrative.append(value) - def insert_administrative(self, index, value): self.administrative[index] = value - def get_coordinates(self): return self.coordinates - def set_coordinates(self, coordinates): self.coordinates = coordinates - def add_coordinates(self, value): self.coordinates.append(value) - def insert_coordinates(self, index, value): self.coordinates[index] = value - def get_gazetteer_entry(self): return self.gazetteer_entry - def set_gazetteer_entry(self, gazetteer_entry): self.gazetteer_entry = gazetteer_entry - def add_gazetteer_entry(self, value): self.gazetteer_entry.append(value) - def insert_gazetteer_entry(self, index, value): self.gazetteer_entry[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_percentage(self): return self.percentage - def set_percentage(self, percentage): self.percentage = percentage - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.location_type or - self.name or - self.description or - self.administrative or - self.coordinates or - self.gazetteer_entry or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='location', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='location') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='location', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='location'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - outfile.write(' percentage=%s' % (self.gds_format_string(quote_attrib(self.percentage).encode(ExternalEncoding), input_name='percentage'), )) - def exportChildren(self, outfile, level, namespace_='', name_='location', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for location_type_ in self.location_type: - location_type_.export(outfile, level, namespace_, name_='location-type', pretty_print=pretty_print) - for name_ in self.name: - name_.export(outfile, level, namespace_, name_='name', pretty_print=pretty_print) - for description_ in self.description: - description_.export(outfile, level, namespace_, name_='description', pretty_print=pretty_print) - for administrative_ in self.administrative: - administrative_.export(outfile, level, namespace_, name_='administrative', pretty_print=pretty_print) - for coordinates_ in self.coordinates: - coordinates_.export(outfile, level, namespace_, name_='coordinates', pretty_print=pretty_print) - for gazetteer_entry_ in self.gazetteer_entry: - gazetteer_entry_.export(outfile, level, namespace_, name_='gazetteer-entry', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='location'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - showIndent(outfile, level) - outfile.write('percentage="%s",\n' % (self.percentage,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('location_type=[\n') - level += 1 - for location_type_ in self.location_type: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - location_type_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('name=[\n') - level += 1 - for name_ in self.name: - showIndent(outfile, level) - outfile.write('model_.textType(\n') - name_.exportLiteral(outfile, level, name_='textType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('description=[\n') - level += 1 - for description_ in self.description: - showIndent(outfile, level) - outfile.write('model_.textType(\n') - description_.exportLiteral(outfile, level, name_='textType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('administrative=[\n') - level += 1 - for administrative_ in self.administrative: - showIndent(outfile, level) - outfile.write('model_.administrativeType(\n') - administrative_.exportLiteral(outfile, level, name_='administrativeType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('coordinates=[\n') - level += 1 - for coordinates_ in self.coordinates: - showIndent(outfile, level) - outfile.write('model_.coordinatesType(\n') - coordinates_.exportLiteral(outfile, level, name_='coordinatesType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('gazetteer_entry=[\n') - level += 1 - for gazetteer_entry_ in self.gazetteer_entry: - showIndent(outfile, level) - outfile.write('model_.gazetteer_entryType(\n') - gazetteer_entry_.exportLiteral(outfile, level, name_='gazetteer-entryType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('percentage', node) - if value is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - self.percentage = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'location-type': - obj_ = codeReqType.factory() - obj_.build(child_) - self.location_type.append(obj_) - elif nodeName_ == 'name': - obj_ = textType.factory() - obj_.build(child_) - self.name.append(obj_) - elif nodeName_ == 'description': - obj_ = textType.factory() - obj_.build(child_) - self.description.append(obj_) - elif nodeName_ == 'administrative': - obj_ = administrativeType.factory() - obj_.build(child_) - self.administrative.append(obj_) - elif nodeName_ == 'coordinates': - obj_ = coordinatesType.factory() - obj_.build(child_) - self.coordinates.append(obj_) - elif nodeName_ == 'gazetteer-entry': - obj_ = gazetteer_entryType.factory() - obj_.build(child_) - self.gazetteer_entry.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'location') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class location - - -class country_budget_items(GeneratedsSuper): - """Recipient country budget items. This item encodes the alignment of - activities with both the functional and administrative - classifications used in the recipient country's Chart of - Accounts. This applies to both on- and off-budget activities. A - code for the common functional classification or country system - (This allows for common codes, country-specific, or any other - classification agreed between countries and donors).""" - subclass = None - superclass = None - def __init__(self, vocabulary=None, budget_item=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.vocabulary = _cast(None, vocabulary) - if budget_item is None: - self.budget_item = [] - else: - self.budget_item = budget_item - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if country_budget_items.subclass: - return country_budget_items.subclass(*args_, **kwargs_) - else: - return country_budget_items(*args_, **kwargs_) - factory = staticmethod(factory) - def get_budget_item(self): return self.budget_item - def set_budget_item(self, budget_item): self.budget_item = budget_item - def add_budget_item(self, value): self.budget_item.append(value) - def insert_budget_item(self, index, value): self.budget_item[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_vocabulary(self): return self.vocabulary - def set_vocabulary(self, vocabulary): self.vocabulary = vocabulary - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.budget_item or - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='country-budget-items', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='country-budget-items') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='country-budget-items', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='country-budget-items'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - outfile.write(' vocabulary=%s' % (self.gds_format_string(quote_attrib(self.vocabulary).encode(ExternalEncoding), input_name='vocabulary'), )) - def exportChildren(self, outfile, level, namespace_='', name_='country-budget-items', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='country-budget-items'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.vocabulary is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - showIndent(outfile, level) - outfile.write('vocabulary="%s",\n' % (self.vocabulary,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('vocabulary', node) - if value is not None and 'vocabulary' not in already_processed: - already_processed.add('vocabulary') - self.vocabulary = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'budget-item': - obj_ = budget_itemType.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, 'budget-item', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_budget-item'): - self.add_budget-item(obj_.value) - elif hasattr(self, 'set_budget-item'): - self.set_budget-item(obj_.value) - elif nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class country_budget_items - - -class related_activity(GeneratedsSuper): - """XX.XX Related Activity Another IATI activity related to this one. - The 'type' attribute describes the type of relationship (e.g. - parent, sibling). This does not need to be used to express - funding relationships, since those are covered in individual - transactions. For the value of the @type attribute, see - http://iatistandard.org/codelists/related_activity_type""" - subclass = None - superclass = None - def __init__(self, lang=None, type_=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.type_ = _cast(None, type_) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if related_activity.subclass: - return related_activity.subclass(*args_, **kwargs_) - else: - return related_activity(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='related-activity', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='related-activity') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='related-activity', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='related-activity'): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='related-activity', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='related-activity'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class related_activity - - -class legacy_data(GeneratedsSuper): - """Hold a single name=value pair of legacy data. This element is *not* - for adding new data types; instead, it holds the original (non- - IATI) value or code for an existing data type. The original - field name. The original field value. The name of the equivalent - IATI element (if available).""" - subclass = None - superclass = None - def __init__(self, name=None, value=None, iati_equivalent=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.name = _cast(None, name) - self.value = _cast(None, value) - self.iati_equivalent = _cast(None, iati_equivalent) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if legacy_data.subclass: - return legacy_data.subclass(*args_, **kwargs_) - else: - return legacy_data(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_name(self): return self.name - def set_name(self, name): self.name = name - def get_value(self): return self.value - def set_value(self, value): self.value = value - def get_iati_equivalent(self): return self.iati_equivalent - def set_iati_equivalent(self, iati_equivalent): self.iati_equivalent = iati_equivalent - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='legacy-data', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='legacy-data') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='legacy-data', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='legacy-data'): - if self.name is not None and 'name' not in already_processed: - already_processed.add('name') - outfile.write(' name=%s' % (self.gds_format_string(quote_attrib(self.name).encode(ExternalEncoding), input_name='name'), )) - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) - if self.iati_equivalent is not None and 'iati_equivalent' not in already_processed: - already_processed.add('iati_equivalent') - outfile.write(' iati-equivalent=%s' % (self.gds_format_string(quote_attrib(self.iati_equivalent).encode(ExternalEncoding), input_name='iati-equivalent'), )) - def exportChildren(self, outfile, level, namespace_='', name_='legacy-data', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='legacy-data'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.name is not None and 'name' not in already_processed: - already_processed.add('name') - showIndent(outfile, level) - outfile.write('name="%s",\n' % (self.name,)) - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - showIndent(outfile, level) - outfile.write('value="%s",\n' % (self.value,)) - if self.iati_equivalent is not None and 'iati_equivalent' not in already_processed: - already_processed.add('iati_equivalent') - showIndent(outfile, level) - outfile.write('iati_equivalent="%s",\n' % (self.iati_equivalent,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('name', node) - if value is not None and 'name' not in already_processed: - already_processed.add('name') - self.name = value - value = find_attr_value_('value', node) - if value is not None and 'value' not in already_processed: - already_processed.add('value') - self.value = value - value = find_attr_value_('iati-equivalent', node) - if value is not None and 'iati-equivalent' not in already_processed: - already_processed.add('iati-equivalent') - self.iati_equivalent = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class legacy_data - - -class result(GeneratedsSuper): - """A measurable result of aid work. Boolean flag indicating whether the - data in the result set are suitable for aggregation.""" - subclass = None - superclass = None - def __init__(self, type_=None, aggregation_status=None, title=None, description=None, indicator=None, anytypeobjs_=None): - self.type_ = _cast(None, type_) - self.aggregation_status = _cast(bool, aggregation_status) - if title is None: - self.title = [] - else: - self.title = title - if description is None: - self.description = [] - else: - self.description = description - if indicator is None: - self.indicator = [] - else: - self.indicator = indicator - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if result.subclass: - return result.subclass(*args_, **kwargs_) - else: - return result(*args_, **kwargs_) - factory = staticmethod(factory) - def get_title(self): return self.title - def set_title(self, title): self.title = title - def add_title(self, value): self.title.append(value) - def insert_title(self, index, value): self.title[index] = value - def get_description(self): return self.description - def set_description(self, description): self.description = description - def add_description(self, value): self.description.append(value) - def insert_description(self, index, value): self.description[index] = value - def get_indicator(self): return self.indicator - def set_indicator(self, indicator): self.indicator = indicator - def add_indicator(self, value): self.indicator.append(value) - def insert_indicator(self, index, value): self.indicator[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_aggregation_status(self): return self.aggregation_status - def set_aggregation_status(self, aggregation_status): self.aggregation_status = aggregation_status - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.title or - self.description or - self.indicator or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='result', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='result') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='result', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='result'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - if self.aggregation_status is not None and 'aggregation_status' not in already_processed: - already_processed.add('aggregation_status') - outfile.write(' aggregation-status="%s"' % self.gds_format_boolean(self.aggregation_status, input_name='aggregation-status')) - def exportChildren(self, outfile, level, namespace_='', name_='result', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for title_ in self.title: - title_.export(outfile, level, namespace_, name_='title', pretty_print=pretty_print) - for description_ in self.description: - description_.export(outfile, level, namespace_, name_='description', pretty_print=pretty_print) - for indicator_ in self.indicator: - indicator_.export(outfile, level, namespace_, name_='indicator', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='result'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - if self.aggregation_status is not None and 'aggregation_status' not in already_processed: - already_processed.add('aggregation_status') - showIndent(outfile, level) - outfile.write('aggregation_status=%s,\n' % (self.aggregation_status,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('title=[\n') - level += 1 - for title_ in self.title: - showIndent(outfile, level) - outfile.write('model_.title(\n') - title_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('description=[\n') - level += 1 - for description_ in self.description: - showIndent(outfile, level) - outfile.write('model_.description(\n') - description_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('indicator=[\n') - level += 1 - for indicator_ in self.indicator: - showIndent(outfile, level) - outfile.write('model_.indicatorType(\n') - indicator_.exportLiteral(outfile, level, name_='indicatorType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - value = find_attr_value_('aggregation-status', node) - if value is not None and 'aggregation-status' not in already_processed: - already_processed.add('aggregation-status') - if value in ('true', '1'): - self.aggregation_status = True - elif value in ('false', '0'): - self.aggregation_status = False - else: - raise_parse_error(node, 'Bad boolean attribute') - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'title': - obj_ = textType.factory() - obj_.build(child_) - self.title.append(obj_) - elif nodeName_ == 'description': - obj_ = description.factory() - obj_.build(child_) - self.description.append(obj_) - elif nodeName_ == 'indicator': - obj_ = indicatorType.factory() - obj_.build(child_) - self.indicator.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'result') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class result - - -class indicatorOutcomeType(GeneratedsSuper): - """Content type for a baseline or actual/planned outcome for an - indicator. The year of the baseline or outcome. The value of the - baseline or outcome.""" - subclass = None - superclass = None - def __init__(self, lang=None, value=None, year=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.value = _cast(None, value) - self.year = _cast(None, year) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if indicatorOutcomeType.subclass: - return indicatorOutcomeType.subclass(*args_, **kwargs_) - else: - return indicatorOutcomeType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_value(self): return self.value - def set_value(self, value): self.value = value - def get_year(self): return self.year - def set_year(self, year): self.year = year - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='indicatorOutcomeType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='indicatorOutcomeType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='indicatorOutcomeType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='indicatorOutcomeType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - outfile.write(' year=%s' % (self.gds_format_string(quote_attrib(self.year).encode(ExternalEncoding), input_name='year'), )) - def exportChildren(self, outfile, level, namespace_='', name_='indicatorOutcomeType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='indicatorOutcomeType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - showIndent(outfile, level) - outfile.write('value="%s",\n' % (self.value,)) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - showIndent(outfile, level) - outfile.write('year="%s",\n' % (self.year,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('value', node) - if value is not None and 'value' not in already_processed: - already_processed.add('value') - self.value = value - value = find_attr_value_('year', node) - if value is not None and 'year' not in already_processed: - already_processed.add('year') - self.year = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class indicatorOutcomeType - - -class conditions(GeneratedsSuper): - """Conditions attached to the activity. A yes/no (1/0) value stating - whether there are conditions attached to the activity.""" - subclass = None - superclass = None - def __init__(self, attached=None, condition=None, anytypeobjs_=None): - self.attached = _cast(bool, attached) - if condition is None: - self.condition = [] - else: - self.condition = condition - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if conditions.subclass: - return conditions.subclass(*args_, **kwargs_) - else: - return conditions(*args_, **kwargs_) - factory = staticmethod(factory) - def get_condition(self): return self.condition - def set_condition(self, condition): self.condition = condition - def add_condition(self, value): self.condition.append(value) - def insert_condition(self, index, value): self.condition[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_attached(self): return self.attached - def set_attached(self, attached): self.attached = attached - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.condition or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='conditions', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='conditions') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='conditions', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='conditions'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.attached is not None and 'attached' not in already_processed: - already_processed.add('attached') - outfile.write(' attached="%s"' % self.gds_format_boolean(self.attached, input_name='attached')) - def exportChildren(self, outfile, level, namespace_='', name_='conditions', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for condition_ in self.condition: - condition_.export(outfile, level, namespace_, name_='condition', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='conditions'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.attached is not None and 'attached' not in already_processed: - already_processed.add('attached') - showIndent(outfile, level) - outfile.write('attached=%s,\n' % (self.attached,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('condition=[\n') - level += 1 - for condition_ in self.condition: - showIndent(outfile, level) - outfile.write('model_.conditionType(\n') - condition_.exportLiteral(outfile, level, name_='conditionType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('attached', node) - if value is not None and 'attached' not in already_processed: - already_processed.add('attached') - if value in ('true', '1'): - self.attached = True - elif value in ('false', '0'): - self.attached = False - else: - raise_parse_error(node, 'Bad boolean attribute') - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'condition': - obj_ = conditionType.factory() - obj_.build(child_) - self.condition.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'conditions') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class conditions - - -class budget(GeneratedsSuper): - """The value of the aid activity's budget for each financial year as in - the original project document.""" - subclass = None - superclass = None - def __init__(self, type_=None, period_start=None, period_end=None, value=None, anytypeobjs_=None): - self.type_ = _cast(None, type_) - if period_start is None: - self.period_start = [] - else: - self.period_start = period_start - if period_end is None: - self.period_end = [] - else: - self.period_end = period_end - if value is None: - self.value = [] - else: - self.value = value - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if budget.subclass: - return budget.subclass(*args_, **kwargs_) - else: - return budget(*args_, **kwargs_) - factory = staticmethod(factory) - def get_period_start(self): return self.period_start - def set_period_start(self, period_start): self.period_start = period_start - def add_period_start(self, value): self.period_start.append(value) - def insert_period_start(self, index, value): self.period_start[index] = value - def get_period_end(self): return self.period_end - def set_period_end(self, period_end): self.period_end = period_end - def add_period_end(self, value): self.period_end.append(value) - def insert_period_end(self, index, value): self.period_end[index] = value - def get_value(self): return self.value - def set_value(self, value): self.value = value - def add_value(self, value): self.value.append(value) - def insert_value(self, index, value): self.value[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.period_start or - self.period_end or - self.value or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='budget', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='budget') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='budget', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='budget'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - def exportChildren(self, outfile, level, namespace_='', name_='budget', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for period_start_ in self.period_start: - period_start_.export(outfile, level, namespace_, name_='period-start', pretty_print=pretty_print) - for period_end_ in self.period_end: - period_end_.export(outfile, level, namespace_, name_='period-end', pretty_print=pretty_print) - for value_ in self.value: - value_.export(outfile, level, namespace_, name_='value', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='budget'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('period_start=[\n') - level += 1 - for period_start_ in self.period_start: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - period_start_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('period_end=[\n') - level += 1 - for period_end_ in self.period_end: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - period_end_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('value=[\n') - level += 1 - for value_ in self.value: - showIndent(outfile, level) - outfile.write('model_.currencyType(\n') - value_.exportLiteral(outfile, level, name_='currencyType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'period-start': - obj_ = dateType.factory() - obj_.build(child_) - self.period_start.append(obj_) - elif nodeName_ == 'period-end': - obj_ = dateType.factory() - obj_.build(child_) - self.period_end.append(obj_) - elif nodeName_ == 'value': - obj_ = currencyType.factory() - obj_.build(child_) - self.value.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'budget') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class budget - - -class planned_disbursement(GeneratedsSuper): - """The date on which this line of information was last updated. - Previous updates for the same period should also be reported.""" - subclass = None - superclass = None - def __init__(self, updated=None, period_start=None, period_end=None, value=None, anytypeobjs_=None): - if isinstance(updated, basestring): - initvalue_ = datetime_.datetime.strptime(updated, '%Y-%m-%d').date() - else: - initvalue_ = updated - self.updated = initvalue_ - if period_start is None: - self.period_start = [] - else: - self.period_start = period_start - if period_end is None: - self.period_end = [] - else: - self.period_end = period_end - if value is None: - self.value = [] - else: - self.value = value - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if planned_disbursement.subclass: - return planned_disbursement.subclass(*args_, **kwargs_) - else: - return planned_disbursement(*args_, **kwargs_) - factory = staticmethod(factory) - def get_period_start(self): return self.period_start - def set_period_start(self, period_start): self.period_start = period_start - def add_period_start(self, value): self.period_start.append(value) - def insert_period_start(self, index, value): self.period_start[index] = value - def get_period_end(self): return self.period_end - def set_period_end(self, period_end): self.period_end = period_end - def add_period_end(self, value): self.period_end.append(value) - def insert_period_end(self, index, value): self.period_end[index] = value - def get_value(self): return self.value - def set_value(self, value): self.value = value - def add_value(self, value): self.value.append(value) - def insert_value(self, index, value): self.value[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_updated(self): return self.updated - def set_updated(self, updated): self.updated = updated - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.period_start or - self.period_end or - self.value or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='planned-disbursement', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='planned-disbursement') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='planned-disbursement', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='planned-disbursement'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.updated is not None and 'updated' not in already_processed: - already_processed.add('updated') - outfile.write(' updated="%s"' % self.gds_format_date(self.updated, input_name='updated')) - def exportChildren(self, outfile, level, namespace_='', name_='planned-disbursement', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for period_start_ in self.period_start: - period_start_.export(outfile, level, namespace_, name_='period-start', pretty_print=pretty_print) - for period_end_ in self.period_end: - period_end_.export(outfile, level, namespace_, name_='period-end', pretty_print=pretty_print) - for value_ in self.value: - value_.export(outfile, level, namespace_, name_='value', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='planned-disbursement'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.updated is not None and 'updated' not in already_processed: - already_processed.add('updated') - showIndent(outfile, level) - outfile.write('updated=model_.GeneratedsSuper.gds_parse_date("%s"),\n' % self.gds_format_date(self.updated, input_name='updated')) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('period_start=[\n') - level += 1 - for period_start_ in self.period_start: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - period_start_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('period_end=[\n') - level += 1 - for period_end_ in self.period_end: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - period_end_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('value=[\n') - level += 1 - for value_ in self.value: - showIndent(outfile, level) - outfile.write('model_.currencyType(\n') - value_.exportLiteral(outfile, level, name_='currencyType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('updated', node) - if value is not None and 'updated' not in already_processed: - already_processed.add('updated') - try: - self.updated = self.gds_parse_date(value) - except ValueError, exp: - raise ValueError('Bad date attribute (updated): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'period-start': - obj_ = dateType.factory() - obj_.build(child_) - self.period_start.append(obj_) - elif nodeName_ == 'period-end': - obj_ = dateType.factory() - obj_.build(child_) - self.period_end.append(obj_) - elif nodeName_ == 'value': - obj_ = currencyType.factory() - obj_.build(child_) - self.value.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'planned-disbursement') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class planned_disbursement - - -class crs_add(GeneratedsSuper): - """Additional items specific to CRS++ reporting.""" - subclass = None - superclass = None - def __init__(self, aidtype_flag=None, loan_terms=None, loan_status=None, anytypeobjs_=None): - if aidtype_flag is None: - self.aidtype_flag = [] - else: - self.aidtype_flag = aidtype_flag - if loan_terms is None: - self.loan_terms = [] - else: - self.loan_terms = loan_terms - if loan_status is None: - self.loan_status = [] - else: - self.loan_status = loan_status - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if crs_add.subclass: - return crs_add.subclass(*args_, **kwargs_) - else: - return crs_add(*args_, **kwargs_) - factory = staticmethod(factory) - def get_aidtype_flag(self): return self.aidtype_flag - def set_aidtype_flag(self, aidtype_flag): self.aidtype_flag = aidtype_flag - def add_aidtype_flag(self, value): self.aidtype_flag.append(value) - def insert_aidtype_flag(self, index, value): self.aidtype_flag[index] = value - def get_loan_terms(self): return self.loan_terms - def set_loan_terms(self, loan_terms): self.loan_terms = loan_terms - def add_loan_terms(self, value): self.loan_terms.append(value) - def insert_loan_terms(self, index, value): self.loan_terms[index] = value - def get_loan_status(self): return self.loan_status - def set_loan_status(self, loan_status): self.loan_status = loan_status - def add_loan_status(self, value): self.loan_status.append(value) - def insert_loan_status(self, index, value): self.loan_status[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.aidtype_flag or - self.loan_terms or - self.loan_status or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='crs-add', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='crs-add') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='crs-add', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='crs-add'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - pass - def exportChildren(self, outfile, level, namespace_='', name_='crs-add', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for aidtype_flag_ in self.aidtype_flag: - aidtype_flag_.export(outfile, level, namespace_, name_='aidtype-flag', pretty_print=pretty_print) - for loan_terms_ in self.loan_terms: - loan_terms_.export(outfile, level, namespace_, name_='loan-terms', pretty_print=pretty_print) - for loan_status_ in self.loan_status: - loan_status_.export(outfile, level, namespace_, name_='loan-status', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='crs-add'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('aidtype_flag=[\n') - level += 1 - for aidtype_flag_ in self.aidtype_flag: - showIndent(outfile, level) - outfile.write('model_.aidtype_flagType(\n') - aidtype_flag_.exportLiteral(outfile, level, name_='aidtype-flagType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('loan_terms=[\n') - level += 1 - for loan_terms_ in self.loan_terms: - showIndent(outfile, level) - outfile.write('model_.loan_termsType(\n') - loan_terms_.exportLiteral(outfile, level, name_='loan-termsType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('loan_status=[\n') - level += 1 - for loan_status_ in self.loan_status: - showIndent(outfile, level) - outfile.write('model_.loan_statusType(\n') - loan_status_.exportLiteral(outfile, level, name_='loan-statusType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'aidtype-flag': - obj_ = aidtype_flagType.factory() - obj_.build(child_) - self.aidtype_flag.append(obj_) - elif nodeName_ == 'loan-terms': - obj_ = loan_termsType.factory() - obj_.build(child_) - self.loan_terms.append(obj_) - elif nodeName_ == 'loan-status': - obj_ = loan_statusType.factory() - obj_.build(child_) - self.loan_status.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'crs-add') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class crs_add - - -class fss(GeneratedsSuper): - """This section allows entry of data required for the OECD DAC Forward - Spending Survey at an activity level. The exact date when the - information was collected or extracted from donors' aid - management systems. True if the partner country is a priority - partner country. If there are plans to phase out operations from - the partner country, this column shows the projected year of - last disbursements.""" - subclass = None - superclass = None - def __init__(self, priority=None, phaseout_year=None, extraction_date=None, forecast=None, anytypeobjs_=None): - self.priority = _cast(bool, priority) - self.phaseout_year = _cast(float, phaseout_year) - if isinstance(extraction_date, basestring): - initvalue_ = datetime_.datetime.strptime(extraction_date, '%Y-%m-%d').date() - else: - initvalue_ = extraction_date - self.extraction_date = initvalue_ - if forecast is None: - self.forecast = [] - else: - self.forecast = forecast - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if fss.subclass: - return fss.subclass(*args_, **kwargs_) - else: - return fss(*args_, **kwargs_) - factory = staticmethod(factory) - def get_forecast(self): return self.forecast - def set_forecast(self, forecast): self.forecast = forecast - def add_forecast(self, value): self.forecast.append(value) - def insert_forecast(self, index, value): self.forecast[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_priority(self): return self.priority - def set_priority(self, priority): self.priority = priority - def get_phaseout_year(self): return self.phaseout_year - def set_phaseout_year(self, phaseout_year): self.phaseout_year = phaseout_year - def get_extraction_date(self): return self.extraction_date - def set_extraction_date(self, extraction_date): self.extraction_date = extraction_date - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.forecast or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='fss', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='fss') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='fss', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='fss'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.priority is not None and 'priority' not in already_processed: - already_processed.add('priority') - outfile.write(' priority="%s"' % self.gds_format_boolean(self.priority, input_name='priority')) - if self.phaseout_year is not None and 'phaseout_year' not in already_processed: - already_processed.add('phaseout_year') - outfile.write(' phaseout-year="%s"' % self.gds_format_float(self.phaseout_year, input_name='phaseout-year')) - if self.extraction_date is not None and 'extraction_date' not in already_processed: - already_processed.add('extraction_date') - outfile.write(' extraction-date="%s"' % self.gds_format_date(self.extraction_date, input_name='extraction-date')) - def exportChildren(self, outfile, level, namespace_='', name_='fss', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for forecast_ in self.forecast: - forecast_.export(outfile, level, namespace_, name_='forecast', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='fss'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.priority is not None and 'priority' not in already_processed: - already_processed.add('priority') - showIndent(outfile, level) - outfile.write('priority=%s,\n' % (self.priority,)) - if self.phaseout_year is not None and 'phaseout_year' not in already_processed: - already_processed.add('phaseout_year') - showIndent(outfile, level) - outfile.write('phaseout_year=%f,\n' % (self.phaseout_year,)) - if self.extraction_date is not None and 'extraction_date' not in already_processed: - already_processed.add('extraction_date') - showIndent(outfile, level) - outfile.write('extraction-date=model_.GeneratedsSuper.gds_parse_date("%s"),\n' % self.gds_format_date(self.extraction_date, input_name='extraction-date')) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('forecast=[\n') - level += 1 - for forecast_ in self.forecast: - showIndent(outfile, level) - outfile.write('model_.forecastType(\n') - forecast_.exportLiteral(outfile, level, name_='forecastType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('priority', node) - if value is not None and 'priority' not in already_processed: - already_processed.add('priority') - if value in ('true', '1'): - self.priority = True - elif value in ('false', '0'): - self.priority = False - else: - raise_parse_error(node, 'Bad boolean attribute') - value = find_attr_value_('phaseout-year', node) - if value is not None and 'phaseout-year' not in already_processed: - already_processed.add('phaseout-year') - try: - self.phaseout_year = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (phaseout-year): %s' % exp) - value = find_attr_value_('extraction-date', node) - if value is not None and 'extraction-date' not in already_processed: - already_processed.add('extraction-date') - try: - self.extraction_date = self.gds_parse_date(value) - except ValueError, exp: - raise ValueError('Bad date attribute (extraction-date): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'forecast': - obj_ = forecastType.factory() - obj_.build(child_) - self.forecast.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'fss') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class fss - - -class description(GeneratedsSuper): - """A longer, human-readable description. May be repeated for different - languages.""" - subclass = None - superclass = None - def __init__(self, lang=None, type_=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.type_ = _cast(None, type_) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if description.subclass: - return description.subclass(*args_, **kwargs_) - else: - return description(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='description', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='description') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile,level) - #self.exportChildren(outfile, level + 1, namespace_='', name_='description', pretty_print=pretty_print) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='description'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - def exportChildren(self, outfile, level, namespace_='', name_='description', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='description'): - #level += 1 - #already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class description - - -class iati_identifier(GeneratedsSuper): - """A globally unique identifier for this activity. This should be in - the form of the IATI Organisation Identifier (for the reporting - organisation) concatenated to that organisation's activity - identifier. (NB. Two or more reporting organisations may publish - information on the same activity. To cross-reference these - reports the other-identifier element should be used.)""" - subclass = None - superclass = None - def __init__(self, valueOf_=None, mixedclass_=None, content_=None): - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if iati_identifier.subclass: - return iati_identifier.subclass(*args_, **kwargs_) - else: - return iati_identifier(*args_, **kwargs_) - factory = staticmethod(factory) - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='iati-identifier', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='iati-identifier') - outfile.write('>') - self.exportLiteral(outfile, level + 1, name_) - outfile.write('%s' % (namespace_, name_, eol_)) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='iati-identifier'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - pass - def exportChildren(self, outfile, level, namespace_='', name_='iati-identifier', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='iati-identifier'): - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) - pass -# end class iati_identifier - - -class reporting_org(GeneratedsSuper): - """The organisation issuing the report. May be a primary source - (reporting on its own activity as donor, implementing agency, - etc) or a secondary source (reporting on the activities of - another organisation). Specifying the @ref and @role attributes - is strongly recommended. May contain the organisation name as - content. For the value of the @type attribute, see - http://iatistandard.org/codelists/organisation-type. For - guidance on constructing the value of the @ref attribute, see - http://iatistandard.org/org-ref""" - subclass = None - superclass = None - def __init__(self, lang=None, type_=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.type_ = _cast(None, type_) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if reporting_org.subclass: - return reporting_org.subclass(*args_, **kwargs_) - else: - return reporting_org(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='reporting-org', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='reporting-org') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile, level) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='reporting-org'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='reporting-org', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='reporting-org'): - #level += 1 - #already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - #self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class reporting_org - - -class document_link(GeneratedsSuper): - """A categorized link to an external document. The target URL of the - external document, e.g. "http://www.example.org/doc.html". The - MIME type of the external document, e.g. "application/pdf". A - partial list of MIME types appears at - http://iatistandard.org/codelists/file_format""" - subclass = None - superclass = None - def __init__(self, url=None, format=None, title=None, category=None, language=None, anytypeobjs_=None): - self.url = _cast(None, url) - self.format = _cast(None, format) - if title is None: - self.title = [] - else: - self.title = title - if category is None: - self.category = [] - else: - self.category = category - if language is None: - self.language = [] - else: - self.language = language - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if document_link.subclass: - return document_link.subclass(*args_, **kwargs_) - else: - return document_link(*args_, **kwargs_) - factory = staticmethod(factory) - def get_title(self): return self.title - def set_title(self, title): self.title = title - def add_title(self, value): self.title.append(value) - def insert_title(self, index, value): self.title[index] = value - def get_category(self): return self.category - def set_category(self, category): self.category = category - def add_category(self, value): self.category.append(value) - def insert_category(self, index, value): self.category[index] = value - def get_language(self): return self.language - def set_language(self, language): self.language = language - def add_language(self, value): self.language.append(value) - def insert_language(self, index, value): self.language[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_url(self): return self.url - def set_url(self, url): self.url = url - def get_format(self): return self.format - def set_format(self, format): self.format = format - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.title or - self.category or - self.language or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='document-link', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='document-link') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='document-link', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='document-link'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.url is not None and 'url' not in already_processed: - already_processed.add('url') - outfile.write(' url=%s' % (self.gds_format_string(quote_attrib(self.url).encode(ExternalEncoding), input_name='url'), )) - if self.format is not None and 'format' not in already_processed: - already_processed.add('format') - outfile.write(' format=%s' % (self.gds_format_string(quote_attrib(self.format).encode(ExternalEncoding), input_name='format'), )) - def exportChildren(self, outfile, level, namespace_='', name_='document-link', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for title_ in self.title: - title_.export(outfile, level, namespace_, name_='title', pretty_print=pretty_print) - for category_ in self.category: - category_.export(outfile, level, namespace_, name_='category', pretty_print=pretty_print) - for language_ in self.language: - language_.export(outfile, level, namespace_, name_='language', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='document-link'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.url is not None and 'url' not in already_processed: - already_processed.add('url') - showIndent(outfile, level) - outfile.write('url="%s",\n' % (self.url,)) - if self.format is not None and 'format' not in already_processed: - already_processed.add('format') - showIndent(outfile, level) - outfile.write('format="%s",\n' % (self.format,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('title=[\n') - level += 1 - for title_ in self.title: - showIndent(outfile, level) - outfile.write('model_.title(\n') - title_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('category=[\n') - level += 1 - for category_ in self.category: - showIndent(outfile, level) - outfile.write('model_.codeReqType(\n') - category_.exportLiteral(outfile, level, name_='codeReqType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('language=[\n') - level += 1 - for language_ in self.language: - showIndent(outfile, level) - outfile.write('model_.codeType(\n') - language_.exportLiteral(outfile, level, name_='codeType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('url', node) - if value is not None and 'url' not in already_processed: - already_processed.add('url') - self.url = value - value = find_attr_value_('format', node) - if value is not None and 'format' not in already_processed: - already_processed.add('format') - self.format = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'title': - obj_ = textType.factory() - obj_.build(child_) - self.title.append(obj_) - elif nodeName_ == 'category': - obj_ = codeReqType.factory() - obj_.build(child_) - self.category.append(obj_) - elif nodeName_ == 'language': - obj_ = codeType.factory() - obj_.build(child_) - self.language.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'document-link') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class document_link - - -class plainType(GeneratedsSuper): - """Plain text content with no special attributes (e.g. xml:lang), - though extended attributes are still allowed.""" - subclass = None - superclass = None - def __init__(self, valueOf_=None, mixedclass_=None, content_=None): - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if plainType.subclass: - return plainType.subclass(*args_, **kwargs_) - else: - return plainType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='plainType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='plainType') - outfile.write('>') - self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='plainType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - pass - def exportChildren(self, outfile, level, namespace_='', name_='plainType', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='plainType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) - pass -# end class plainType - - -class textType(GeneratedsSuper): - """Data type for an element that may contain human-readable text in - different languages.""" - subclass = None - superclass = None - def __init__(self, lang=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if textType.subclass: - return textType.subclass(*args_, **kwargs_) - else: - return textType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='textType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='textType') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile, level) - #self.exportChildren(outfile, level + 1, namespace_='', name_='textType', pretty_print=pretty_print) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='textType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - def exportChildren(self, outfile, level, namespace_='', name_='textType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='textType'): - #level += 1 - already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class textType - - -class codeType(GeneratedsSuper): - """Data type for an element that refers to an object that can have a - code as well as human-readable text in different languages (e.g. - a country or status).""" - subclass = None - superclass = None - def __init__(self, lang=None, code=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.code = _cast(None, code) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if codeType.subclass: - return codeType.subclass(*args_, **kwargs_) - else: - return codeType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='codeType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='codeType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='codeType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='codeType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - def exportChildren(self, outfile, level, namespace_='', name_='codeType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='codeType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class codeType - - -class codeReqType(GeneratedsSuper): - """Data type for an element that refers to an object that must have a - code.""" - subclass = None - superclass = None - def __init__(self, lang=None, code=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.code = _cast(None, code) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if codeReqType.subclass: - return codeReqType.subclass(*args_, **kwargs_) - else: - return codeReqType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='codeReqType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='codeReqType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='codeReqType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='codeReqType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - def exportChildren(self, outfile, level, namespace_='', name_='codeReqType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='codeReqType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class codeReqType - - -class refType(GeneratedsSuper): - """Data type for an element that refers to a business object that can - have unique identifier as well as human-readable text in - different languages (e.g. an organisation).""" - subclass = None - superclass = None - def __init__(self, lang=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if refType.subclass: - return refType.subclass(*args_, **kwargs_) - else: - return refType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='refType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='refType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='refType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='refType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='refType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='refType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class refType - - -class refReqType(GeneratedsSuper): - """Data type for an element that refers to a business object that can - have unique identifier as well as human-readable text in - different languages (e.g. an organisation), where the identifier - reference is required.""" - subclass = None - superclass = None - def __init__(self, lang=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if refReqType.subclass: - return refReqType.subclass(*args_, **kwargs_) - else: - return refReqType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='refReqType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='refReqType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='refReqType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='refReqType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='refReqType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='refReqType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class refReqType - - -class currencyType(GeneratedsSuper): - """Data type for an element containing a currency value.""" - subclass = None - superclass = None - def __init__(self, currency=None, value_date=None, valueOf_=None): - self.currency = _cast(None, currency) - self.value_date = _cast(None, value_date) - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if currencyType.subclass: - return currencyType.subclass(*args_, **kwargs_) - else: - return currencyType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_currency(self): return self.currency - def set_currency(self, currency): self.currency = currency - def get_value_date(self): return self.value_date - def set_value_date(self, value_date): self.value_date = value_date - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='currencyType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='currencyType') - if self.hasContent_(): - outfile.write('>') - outfile.write(str(self.valueOf_).encode(ExternalEncoding)) - self.exportChildren(outfile, level + 1, namespace_='', name_='currencyType', pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='currencyType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.currency is not None and 'currency' not in already_processed: - already_processed.add('currency') - outfile.write(' currency=%s' % (self.gds_format_string(quote_attrib(self.currency).encode(ExternalEncoding), input_name='currency'), )) - if self.value_date is not None and 'value_date' not in already_processed: - already_processed.add('value_date') - outfile.write(' value-date=%s' % (self.gds_format_string(quote_attrib(self.value_date).encode(ExternalEncoding), input_name='value-date'), )) - def exportChildren(self, outfile, level, namespace_='', name_='currencyType', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='currencyType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.currency is not None and 'currency' not in already_processed: - already_processed.add('currency') - showIndent(outfile, level) - outfile.write('currency="%s",\n' % (self.currency,)) - if self.value_date is not None and 'value_date' not in already_processed: - already_processed.add('value_date') - showIndent(outfile, level) - outfile.write('value_date="%s",\n' % (self.value_date,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('currency', node) - if value is not None and 'currency' not in already_processed: - already_processed.add('currency') - self.currency = value - value = find_attr_value_('value-date', node) - if value is not None and 'value-date' not in already_processed: - already_processed.add('value-date') - self.value_date = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - pass -# end class currencyType - - -class dateType(GeneratedsSuper): - """A date. The ISO 8601 date goes into the @iso-date attribute. The - content may be free-form text. The ISO 8601 date.""" - subclass = None - superclass = None - def __init__(self, iso_date=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - if isinstance(iso_date, basestring): - initvalue_ = datetime_.datetime.strptime(iso_date, '%Y-%m-%d').date() - else: - initvalue_ = iso_date - self.iso_date = initvalue_ - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if dateType.subclass: - return dateType.subclass(*args_, **kwargs_) - else: - return dateType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_iso_date(self): return self.iso_date - def set_iso_date(self, iso_date): self.iso_date = iso_date - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='dateType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='dateType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='dateType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='dateType'): - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - outfile.write(' iso-date="%s"' % self.gds_format_date(self.iso_date, input_name='iso-date')) - def exportChildren(self, outfile, level, namespace_='', name_='dateType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='dateType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - showIndent(outfile, level) - outfile.write('iso-date=model_.GeneratedsSuper.gds_parse_date("%s"),\n' % self.gds_format_date(self.iso_date, input_name='iso-date')) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('iso-date', node) - if value is not None and 'iso-date' not in already_processed: - already_processed.add('iso-date') - try: - self.iso_date = self.gds_parse_date(value) - except ValueError, exp: - raise ValueError('Bad date attribute (iso-date): %s' % exp) - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class dateType - - -class dateReqType(GeneratedsSuper): - """A date. The ISO 8601 date goes into the @iso-date attribute. The - content may be free-form text. The ISO 8601 date.""" - subclass = None - superclass = None - def __init__(self, iso_date=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - if isinstance(iso_date, basestring): - initvalue_ = datetime_.datetime.strptime(iso_date, '%Y-%m-%d').date() - else: - initvalue_ = iso_date - self.iso_date = initvalue_ - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if dateReqType.subclass: - return dateReqType.subclass(*args_, **kwargs_) - else: - return dateReqType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_iso_date(self): return self.iso_date - def set_iso_date(self, iso_date): self.iso_date = iso_date - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='dateReqType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='dateReqType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='dateReqType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='dateReqType'): - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - outfile.write(' iso-date="%s"' % self.gds_format_date(self.iso_date, input_name='iso-date')) - def exportChildren(self, outfile, level, namespace_='', name_='dateReqType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='dateReqType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - showIndent(outfile, level) - outfile.write('iso-date=model_.GeneratedsSuper.gds_parse_date("%s"),\n' % self.gds_format_date(self.iso_date, input_name='iso-date')) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('iso-date', node) - if value is not None and 'iso-date' not in already_processed: - already_processed.add('iso-date') - try: - self.iso_date = self.gds_parse_date(value) - except ValueError, exp: - raise ValueError('Bad date attribute (iso-date): %s' % exp) - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class dateReqType - - -class telephoneType(GeneratedsSuper): - subclass = None - superclass = None - def __init__(self, valueOf_=None, mixedclass_=None, content_=None): - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if telephoneType.subclass: - return telephoneType.subclass(*args_, **kwargs_) - else: - return telephoneType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='telephoneType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='telephoneType') - outfile.write('>') - self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='telephoneType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - pass - def exportChildren(self, outfile, level, namespace_='', name_='telephoneType', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='telephoneType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) - pass -# end class telephoneType - - -class mailing_addressType(GeneratedsSuper): - subclass = None - superclass = None - def __init__(self, lang=None, valueOf_=None, mixedclass_=None, content_=None): - self.lang = _cast(None, lang) - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if mailing_addressType.subclass: - return mailing_addressType.subclass(*args_, **kwargs_) - else: - return mailing_addressType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_lang(self): return self.lang - def set_lang(self, lang): self.lang = lang - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='mailing-addressType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='mailing-addressType') - outfile.write('>') - self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='mailing-addressType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - outfile.write(' lang=%s' % (self.gds_format_string(quote_attrib(self.lang).encode(ExternalEncoding), input_name='lang'), )) - def exportChildren(self, outfile, level, namespace_='', name_='mailing-addressType', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='mailing-addressType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.lang is not None and 'lang' not in already_processed: - already_processed.add('lang') - showIndent(outfile, level) - outfile.write('lang="%s",\n' % (self.lang,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('lang', node) - if value is not None and 'lang' not in already_processed: - already_processed.add('lang') - self.lang = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) - pass -# end class mailing_addressType - - -class provider_orgType(GeneratedsSuper): - """If the funds are being provided from the budget of another activity - that is reported to IATI, this should record the unique IATI - activity identifier for that activity.""" - subclass = None - superclass = None - def __init__(self, provider_activity_id=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.provider_activity_id = _cast(None, provider_activity_id) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if provider_orgType.subclass: - return provider_orgType.subclass(*args_, **kwargs_) - else: - return provider_orgType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_provider_activity_id(self): return self.provider_activity_id - def set_provider_activity_id(self, provider_activity_id): self.provider_activity_id = provider_activity_id - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='provider-orgType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='provider-orgType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='provider-orgType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='provider-orgType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.provider_activity_id is not None and 'provider_activity_id' not in already_processed: - already_processed.add('provider_activity_id') - outfile.write(' provider-activity-id=%s' % (self.gds_format_string(quote_attrib(self.provider_activity_id).encode(ExternalEncoding), input_name='provider-activity-id'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='provider-orgType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='provider-orgType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.provider_activity_id is not None and 'provider_activity_id' not in already_processed: - already_processed.add('provider_activity_id') - showIndent(outfile, level) - outfile.write('provider_activity_id="%s",\n' % (self.provider_activity_id,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('provider-activity-id', node) - if value is not None and 'provider-activity-id' not in already_processed: - already_processed.add('provider-activity-id') - self.provider_activity_id = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class provider_orgType - - -class receiver_orgType(GeneratedsSuper): - """If the funds are being provided to another activity that is reported - to IATI, this should record the unique IATI activity identifier - for that activity.""" - subclass = None - superclass = None - def __init__(self, receiver_activity_id=None, ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.receiver_activity_id = _cast(None, receiver_activity_id) - self.ref = _cast(None, ref) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if receiver_orgType.subclass: - return receiver_orgType.subclass(*args_, **kwargs_) - else: - return receiver_orgType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_receiver_activity_id(self): return self.receiver_activity_id - def set_receiver_activity_id(self, receiver_activity_id): self.receiver_activity_id = receiver_activity_id - def get_ref(self): return self.ref - def set_ref(self, ref): self.ref = ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='receiver-orgType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='receiver-orgType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='receiver-orgType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='receiver-orgType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.receiver_activity_id is not None and 'receiver_activity_id' not in already_processed: - already_processed.add('receiver_activity_id') - outfile.write(' receiver-activity-id=%s' % (self.gds_format_string(quote_attrib(self.receiver_activity_id).encode(ExternalEncoding), input_name='receiver-activity-id'), )) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - outfile.write(' ref=%s' % (self.gds_format_string(quote_attrib(self.ref).encode(ExternalEncoding), input_name='ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='receiver-orgType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='receiver-orgType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.receiver_activity_id is not None and 'receiver_activity_id' not in already_processed: - already_processed.add('receiver_activity_id') - showIndent(outfile, level) - outfile.write('receiver_activity_id="%s",\n' % (self.receiver_activity_id,)) - if self.ref is not None and 'ref' not in already_processed: - already_processed.add('ref') - showIndent(outfile, level) - outfile.write('ref="%s",\n' % (self.ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('receiver-activity-id', node) - if value is not None and 'receiver-activity-id' not in already_processed: - already_processed.add('receiver-activity-id') - self.receiver_activity_id = value - value = find_attr_value_('ref', node) - if value is not None and 'ref' not in already_processed: - already_processed.add('ref') - self.ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class receiver_orgType - - -class transaction_dateType(GeneratedsSuper): - """The ISO 8601 version of the transaction date.""" - subclass = None - superclass = None - def __init__(self, iso_date=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - if isinstance(iso_date, basestring): - initvalue_ = datetime_.datetime.strptime(iso_date, '%Y-%m-%d').date() - else: - initvalue_ = iso_date - self.iso_date = initvalue_ - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if transaction_dateType.subclass: - return transaction_dateType.subclass(*args_, **kwargs_) - else: - return transaction_dateType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_iso_date(self): return self.iso_date - def set_iso_date(self, iso_date): self.iso_date = iso_date - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='transaction-dateType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='transaction-dateType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='transaction-dateType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='transaction-dateType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - outfile.write(' iso-date="%s"' % self.gds_format_date(self.iso_date, input_name='iso-date')) - def exportChildren(self, outfile, level, namespace_='', name_='transaction-dateType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='transaction-dateType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.iso_date is not None and 'iso_date' not in already_processed: - already_processed.add('iso_date') - showIndent(outfile, level) - outfile.write('iso-date=model_.GeneratedsSuper.gds_parse_date("%s"),\n' % self.gds_format_date(self.iso_date, input_name='iso-date')) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('iso-date', node) - if value is not None and 'iso-date' not in already_processed: - already_processed.add('iso-date') - try: - self.iso_date = self.gds_parse_date(value) - except ValueError, exp: - raise ValueError('Bad date attribute (iso-date): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class transaction_dateType - - -class administrativeType(GeneratedsSuper): - """The ISO 3166-1 alpha2 code for the country (e.g. "GB" for the United - Kingdom). For the @code attribute, see - http://iatistandard.org/codelists/country The UNSALB level-one - administrative code for a subdivision of a country. See - http://iatistandard.org/codelists/admin1 The UNSALB level-two - administrative code for a subdivision of a country. See - http://iatistandard.org/codelists/admin2""" - subclass = None - superclass = None - def __init__(self, country=None, adm1=None, adm2=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.country = _cast(None, country) - self.adm1 = _cast(None, adm1) - self.adm2 = _cast(None, adm2) - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if administrativeType.subclass: - return administrativeType.subclass(*args_, **kwargs_) - else: - return administrativeType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_country(self): return self.country - def set_country(self, country): self.country = country - def get_adm1(self): return self.adm1 - def set_adm1(self, adm1): self.adm1 = adm1 - def get_adm2(self): return self.adm2 - def set_adm2(self, adm2): self.adm2 = adm2 - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ is not None or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='administrativeType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='administrativeType') - if self.hasContent_(): - outfile.write('>') - self.exportLiteral(outfile, level) - #showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='administrativeType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.country is not None and 'country' not in already_processed: - already_processed.add('country') - outfile.write(' country=%s' % (self.gds_format_string(quote_attrib(self.country).encode(ExternalEncoding), input_name='country'), )) - if self.adm1 is not None and 'adm1' not in already_processed: - already_processed.add('adm1') - outfile.write(' adm1=%s' % (self.gds_format_string(quote_attrib(self.adm1).encode(ExternalEncoding), input_name='adm1'), )) - if self.adm2 is not None and 'adm2' not in already_processed: - already_processed.add('adm2') - outfile.write(' adm2=%s' % (self.gds_format_string(quote_attrib(self.adm2).encode(ExternalEncoding), input_name='adm2'), )) - def exportChildren(self, outfile, level, namespace_='', name_='administrativeType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='administrativeType'): - #level += 1 - #already_processed = set() - #self.exportLiteralAttributes(outfile, level, already_processed, name_) - #if self.hasContent_(): - # self.exportLiteralChildren(outfile, level, name_) - #showIndent(outfile, level) - outfile.write('%s' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.country is not None and 'country' not in already_processed: - already_processed.add('country') - showIndent(outfile, level) - outfile.write('country="%s",\n' % (self.country,)) - if self.adm1 is not None and 'adm1' not in already_processed: - already_processed.add('adm1') - showIndent(outfile, level) - outfile.write('adm1="%s",\n' % (self.adm1,)) - if self.adm2 is not None and 'adm2' not in already_processed: - already_processed.add('adm2') - showIndent(outfile, level) - outfile.write('adm2="%s",\n' % (self.adm2,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('country', node) - if value is not None and 'country' not in already_processed: - already_processed.add('country') - self.country = value - value = find_attr_value_('adm1', node) - if value is not None and 'adm1' not in already_processed: - already_processed.add('adm1') - self.adm1 = value - value = find_attr_value_('adm2', node) - if value is not None and 'adm2' not in already_processed: - already_processed.add('adm2') - self.adm2 = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class administrativeType - - -class coordinatesType(GeneratedsSuper): - """The decimal latitude (north is positive), e.g. "45.5" for 45.5 - degrees north (45 degrees 30 minutes). The decimal longitude - (east is positive), e.g. "-75.5" for 75.5 degrees west (74 - degrees 30 minutes). An IATI-defined subset of UCPD precision - codes for the location (e.g. "2" for within 25 km of the - specified latitude/longitude). See - http://iatistandard.org/codelists/geographical_precision""" - subclass = None - superclass = None - def __init__(self, latitude=None, precision=None, longitude=None, anytypeobjs_=None): - self.latitude = _cast(float, latitude) - self.precision = _cast(None, precision) - self.longitude = _cast(float, longitude) - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if coordinatesType.subclass: - return coordinatesType.subclass(*args_, **kwargs_) - else: - return coordinatesType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_latitude(self): return self.latitude - def set_latitude(self, latitude): self.latitude = latitude - def get_precision(self): return self.precision - def set_precision(self, precision): self.precision = precision - def get_longitude(self): return self.longitude - def set_longitude(self, longitude): self.longitude = longitude - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='coordinatesType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='coordinatesType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='coordinatesType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='coordinatesType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.latitude is not None and 'latitude' not in already_processed: - already_processed.add('latitude') - outfile.write(' latitude="%s"' % self.gds_format_float(self.latitude, input_name='latitude')) - if self.precision is not None and 'precision' not in already_processed: - already_processed.add('precision') - outfile.write(' precision=%s' % (self.gds_format_string(quote_attrib(self.precision).encode(ExternalEncoding), input_name='precision'), )) - if self.longitude is not None and 'longitude' not in already_processed: - already_processed.add('longitude') - outfile.write(' longitude="%s"' % self.gds_format_float(self.longitude, input_name='longitude')) - def exportChildren(self, outfile, level, namespace_='', name_='coordinatesType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='coordinatesType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.latitude is not None and 'latitude' not in already_processed: - already_processed.add('latitude') - showIndent(outfile, level) - outfile.write('latitude=%f,\n' % (self.latitude,)) - if self.precision is not None and 'precision' not in already_processed: - already_processed.add('precision') - showIndent(outfile, level) - outfile.write('precision="%s",\n' % (self.precision,)) - if self.longitude is not None and 'longitude' not in already_processed: - already_processed.add('longitude') - showIndent(outfile, level) - outfile.write('longitude=%f,\n' % (self.longitude,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('latitude', node) - if value is not None and 'latitude' not in already_processed: - already_processed.add('latitude') - try: - self.latitude = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (latitude): %s' % exp) - value = find_attr_value_('precision', node) - if value is not None and 'precision' not in already_processed: - already_processed.add('precision') - self.precision = value - value = find_attr_value_('longitude', node) - if value is not None and 'longitude' not in already_processed: - already_processed.add('longitude') - try: - self.longitude = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (longitude): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - obj_ = self.gds_build_any(child_, 'coordinatesType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class coordinatesType - - -class gazetteer_entryType(GeneratedsSuper): - """Reference to the gazetteer containing the entry. See - http://iatistandard.org/codelists/gazetteer_agency""" - subclass = None - superclass = None - def __init__(self, gazetteer_ref=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.gazetteer_ref = _cast(None, gazetteer_ref) - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if gazetteer_entryType.subclass: - return gazetteer_entryType.subclass(*args_, **kwargs_) - else: - return gazetteer_entryType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_gazetteer_ref(self): return self.gazetteer_ref - def set_gazetteer_ref(self, gazetteer_ref): self.gazetteer_ref = gazetteer_ref - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ is not None or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='gazetteer-entryType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='gazetteer-entryType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='gazetteer-entryType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='gazetteer-entryType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.gazetteer_ref is not None and 'gazetteer_ref' not in already_processed: - already_processed.add('gazetteer_ref') - outfile.write(' gazetteer-ref=%s' % (self.gds_format_string(quote_attrib(self.gazetteer_ref).encode(ExternalEncoding), input_name='gazetteer-ref'), )) - def exportChildren(self, outfile, level, namespace_='', name_='gazetteer-entryType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='gazetteer-entryType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.gazetteer_ref is not None and 'gazetteer_ref' not in already_processed: - already_processed.add('gazetteer_ref') - showIndent(outfile, level) - outfile.write('gazetteer_ref="%s",\n' % (self.gazetteer_ref,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('gazetteer-ref', node) - if value is not None and 'gazetteer-ref' not in already_processed: - already_processed.add('gazetteer-ref') - self.gazetteer_ref = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class gazetteer_entryType - - -class budget_itemType(GeneratedsSuper): - subclass = None - superclass = None - def __init__(self, percentage=None, code=None, description=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.percentage = _cast(None, percentage) - self.code = _cast(None, code) - if description is None: - self.description = [] - else: - self.description = description - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if budget_itemType.subclass: - return budget_itemType.subclass(*args_, **kwargs_) - else: - return budget_itemType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_description(self): return self.description - def set_description(self, description): self.description = description - def add_description(self, value): self.description.append(value) - def insert_description(self, index, value): self.description[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_percentage(self): return self.percentage - def set_percentage(self, percentage): self.percentage = percentage - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.description or - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='budget-itemType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='budget-itemType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='budget-itemType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='budget-itemType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - outfile.write(' percentage=%s' % (self.gds_format_string(quote_attrib(self.percentage).encode(ExternalEncoding), input_name='percentage'), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - def exportChildren(self, outfile, level, namespace_='', name_='budget-itemType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='budget-itemType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.percentage is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - showIndent(outfile, level) - outfile.write('percentage="%s",\n' % (self.percentage,)) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('percentage', node) - if value is not None and 'percentage' not in already_processed: - already_processed.add('percentage') - self.percentage = value - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'description': - obj_ = description.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, 'description', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_description'): - self.add_description(obj_.value) - elif hasattr(self, 'set_description'): - self.set_description(obj_.value) - elif nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class budget_itemType - - -class indicatorType(GeneratedsSuper): - """The type of measurement for the indicator value e.g. unit, - percentage, NDP. True if the indicator improves from small to - large (e.g. clinics built); false if it improves from large to - small (e.g. cases of a disease). Defaults to true if omitted.""" - subclass = None - superclass = None - def __init__(self, ascending=None, measure=None, title=None, description=None, baseline=None, period=None, anytypeobjs_=None): - self.ascending = _cast(bool, ascending) - self.measure = _cast(None, measure) - if title is None: - self.title = [] - else: - self.title = title - if description is None: - self.description = [] - else: - self.description = description - if baseline is None: - self.baseline = [] - else: - self.baseline = baseline - if period is None: - self.period = [] - else: - self.period = period - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if indicatorType.subclass: - return indicatorType.subclass(*args_, **kwargs_) - else: - return indicatorType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_title(self): return self.title - def set_title(self, title): self.title = title - def add_title(self, value): self.title.append(value) - def insert_title(self, index, value): self.title[index] = value - def get_description(self): return self.description - def set_description(self, description): self.description = description - def add_description(self, value): self.description.append(value) - def insert_description(self, index, value): self.description[index] = value - def get_baseline(self): return self.baseline - def set_baseline(self, baseline): self.baseline = baseline - def add_baseline(self, value): self.baseline.append(value) - def insert_baseline(self, index, value): self.baseline[index] = value - def get_period(self): return self.period - def set_period(self, period): self.period = period - def add_period(self, value): self.period.append(value) - def insert_period(self, index, value): self.period[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_ascending(self): return self.ascending - def set_ascending(self, ascending): self.ascending = ascending - def get_measure(self): return self.measure - def set_measure(self, measure): self.measure = measure - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.title or - self.description or - self.baseline or - self.period or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='indicatorType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='indicatorType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='indicatorType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='indicatorType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.ascending is not None and 'ascending' not in already_processed: - already_processed.add('ascending') - outfile.write(' ascending="%s"' % self.gds_format_boolean(self.ascending, input_name='ascending')) - if self.measure is not None and 'measure' not in already_processed: - already_processed.add('measure') - outfile.write(' measure=%s' % (self.gds_format_string(quote_attrib(self.measure).encode(ExternalEncoding), input_name='measure'), )) - def exportChildren(self, outfile, level, namespace_='', name_='indicatorType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for title_ in self.title: - title_.export(outfile, level, namespace_, name_='title', pretty_print=pretty_print) - for description_ in self.description: - description_.export(outfile, level, namespace_, name_='description', pretty_print=pretty_print) - for baseline_ in self.baseline: - baseline_.export(outfile, level, namespace_, name_='baseline', pretty_print=pretty_print) - for period_ in self.period: - period_.export(outfile, level, namespace_, name_='period', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='indicatorType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.ascending is not None and 'ascending' not in already_processed: - already_processed.add('ascending') - showIndent(outfile, level) - outfile.write('ascending=%s,\n' % (self.ascending,)) - if self.measure is not None and 'measure' not in already_processed: - already_processed.add('measure') - showIndent(outfile, level) - outfile.write('measure="%s",\n' % (self.measure,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('title=[\n') - level += 1 - for title_ in self.title: - showIndent(outfile, level) - outfile.write('model_.title(\n') - title_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('description=[\n') - level += 1 - for description_ in self.description: - showIndent(outfile, level) - outfile.write('model_.description(\n') - description_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('baseline=[\n') - level += 1 - for baseline_ in self.baseline: - showIndent(outfile, level) - outfile.write('model_.baselineType(\n') - baseline_.exportLiteral(outfile, level, name_='baselineType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('period=[\n') - level += 1 - for period_ in self.period: - showIndent(outfile, level) - outfile.write('model_.periodType(\n') - period_.exportLiteral(outfile, level, name_='periodType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('ascending', node) - if value is not None and 'ascending' not in already_processed: - already_processed.add('ascending') - if value in ('true', '1'): - self.ascending = True - elif value in ('false', '0'): - self.ascending = False - else: - raise_parse_error(node, 'Bad boolean attribute') - value = find_attr_value_('measure', node) - if value is not None and 'measure' not in already_processed: - already_processed.add('measure') - self.measure = value - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'title': - obj_ = textType.factory() - obj_.build(child_) - self.title.append(obj_) - elif nodeName_ == 'description': - obj_ = description.factory() - obj_.build(child_) - self.description.append(obj_) - elif nodeName_ == 'baseline': - obj_ = baselineType.factory() - obj_.build(child_) - self.baseline.append(obj_) - elif nodeName_ == 'period': - obj_ = periodType.factory() - obj_.build(child_) - self.period.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'indicatorType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class indicatorType - - -class baselineType(GeneratedsSuper): - """The year the baseline value was taken The baseline value.""" - subclass = None - superclass = None - def __init__(self, value=None, year=None, comment=None, anytypeobjs_=None): - self.value = _cast(None, value) - self.year = _cast(int, year) - if comment is None: - self.comment = [] - else: - self.comment = comment - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if baselineType.subclass: - return baselineType.subclass(*args_, **kwargs_) - else: - return baselineType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_comment(self): return self.comment - def set_comment(self, comment): self.comment = comment - def add_comment(self, value): self.comment.append(value) - def insert_comment(self, index, value): self.comment[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_value(self): return self.value - def set_value(self, value): self.value = value - def get_year(self): return self.year - def set_year(self, year): self.year = year - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.comment or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='baselineType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='baselineType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='baselineType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='baselineType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - outfile.write(' year="%s"' % self.gds_format_integer(self.year, input_name='year')) - def exportChildren(self, outfile, level, namespace_='', name_='baselineType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for comment_ in self.comment: - comment_.export(outfile, level, namespace_, name_='comment', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='baselineType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - showIndent(outfile, level) - outfile.write('value="%s",\n' % (self.value,)) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - showIndent(outfile, level) - outfile.write('year=%d,\n' % (self.year,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('comment=[\n') - level += 1 - for comment_ in self.comment: - showIndent(outfile, level) - outfile.write('model_.comment(\n') - comment_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('value', node) - if value is not None and 'value' not in already_processed: - already_processed.add('value') - self.value = value - value = find_attr_value_('year', node) - if value is not None and 'year' not in already_processed: - already_processed.add('year') - try: - self.year = int(value) - except ValueError, exp: - raise_parse_error(node, 'Bad integer attribute: %s' % exp) - if self.year <= 0: - raise_parse_error(node, 'Invalid PositiveInteger') - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'comment': - obj_ = textType.factory() - obj_.build(child_) - self.comment.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'baselineType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class baselineType - - -class periodType(GeneratedsSuper): - subclass = None - superclass = None - def __init__(self, period_start=None, period_end=None, target=None, actual=None, anytypeobjs_=None): - if period_start is None: - self.period_start = [] - else: - self.period_start = period_start - if period_end is None: - self.period_end = [] - else: - self.period_end = period_end - if target is None: - self.target = [] - else: - self.target = target - if actual is None: - self.actual = [] - else: - self.actual = actual - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if periodType.subclass: - return periodType.subclass(*args_, **kwargs_) - else: - return periodType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_period_start(self): return self.period_start - def set_period_start(self, period_start): self.period_start = period_start - def add_period_start(self, value): self.period_start.append(value) - def insert_period_start(self, index, value): self.period_start[index] = value - def get_period_end(self): return self.period_end - def set_period_end(self, period_end): self.period_end = period_end - def add_period_end(self, value): self.period_end.append(value) - def insert_period_end(self, index, value): self.period_end[index] = value - def get_target(self): return self.target - def set_target(self, target): self.target = target - def add_target(self, value): self.target.append(value) - def insert_target(self, index, value): self.target[index] = value - def get_actual(self): return self.actual - def set_actual(self, actual): self.actual = actual - def add_actual(self, value): self.actual.append(value) - def insert_actual(self, index, value): self.actual[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.period_start or - self.period_end or - self.target or - self.actual or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='periodType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='periodType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='periodType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='periodType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - pass - def exportChildren(self, outfile, level, namespace_='', name_='periodType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for period_start_ in self.period_start: - period_start_.export(outfile, level, namespace_, name_='period-start', pretty_print=pretty_print) - for period_end_ in self.period_end: - period_end_.export(outfile, level, namespace_, name_='period-end', pretty_print=pretty_print) - for target_ in self.target: - target_.export(outfile, level, namespace_, name_='target', pretty_print=pretty_print) - for actual_ in self.actual: - actual_.export(outfile, level, namespace_, name_='actual', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='periodType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('period_start=[\n') - level += 1 - for period_start_ in self.period_start: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - period_start_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('period_end=[\n') - level += 1 - for period_end_ in self.period_end: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - period_end_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('target=[\n') - level += 1 - for target_ in self.target: - showIndent(outfile, level) - outfile.write('model_.targetType(\n') - target_.exportLiteral(outfile, level, name_='targetType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('actual=[\n') - level += 1 - for actual_ in self.actual: - showIndent(outfile, level) - outfile.write('model_.actualType(\n') - actual_.exportLiteral(outfile, level, name_='actualType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'period-start': - obj_ = dateType.factory() - obj_.build(child_) - self.period_start.append(obj_) - elif nodeName_ == 'period-end': - obj_ = dateType.factory() - obj_.build(child_) - self.period_end.append(obj_) - elif nodeName_ == 'target': - obj_ = targetType.factory() - obj_.build(child_) - self.target.append(obj_) - elif nodeName_ == 'actual': - obj_ = actualType.factory() - obj_.build(child_) - self.actual.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'periodType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class periodType - - -class targetType(GeneratedsSuper): - """The target value.""" - subclass = None - superclass = None - def __init__(self, value=None, comment=None, anytypeobjs_=None): - self.value = _cast(None, value) - if comment is None: - self.comment = [] - else: - self.comment = comment - self.anytypeobjs_ = anytypeobjs_ - def factory(*args_, **kwargs_): - if targetType.subclass: - return targetType.subclass(*args_, **kwargs_) - else: - return targetType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_comment(self): return self.comment - def set_comment(self, comment): self.comment = comment - def add_comment(self, value): self.comment.append(value) - def insert_comment(self, index, value): self.comment[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_value(self): return self.value - def set_value(self, value): self.value = value - def hasContent_(self): - if ( - self.comment or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='targetType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='targetType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='targetType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='targetType'): - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) - def exportChildren(self, outfile, level, namespace_='', name_='targetType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for comment_ in self.comment: - comment_.export(outfile, level, namespace_, name_='comment', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='targetType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - showIndent(outfile, level) - outfile.write('value="%s",\n' % (self.value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('comment=[\n') - level += 1 - for comment_ in self.comment: - showIndent(outfile, level) - outfile.write('model_.comment(\n') - comment_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('value', node) - if value is not None and 'value' not in already_processed: - already_processed.add('value') - self.value = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'comment': - obj_ = textType.factory() - obj_.build(child_) - self.comment.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'targetType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class targetType - - -class actualType(GeneratedsSuper): - """The actual measure.""" - subclass = None - superclass = None - def __init__(self, value=None, comment=None, anytypeobjs_=None): - self.value = _cast(None, value) - if comment is None: - self.comment = [] - else: - self.comment = comment - self.anytypeobjs_ = anytypeobjs_ - def factory(*args_, **kwargs_): - if actualType.subclass: - return actualType.subclass(*args_, **kwargs_) - else: - return actualType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_comment(self): return self.comment - def set_comment(self, comment): self.comment = comment - def add_comment(self, value): self.comment.append(value) - def insert_comment(self, index, value): self.comment[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_value(self): return self.value - def set_value(self, value): self.value = value - def hasContent_(self): - if ( - self.comment or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='actualType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='actualType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='actualType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='actualType'): - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - outfile.write(' value=%s' % (self.gds_format_string(quote_attrib(self.value).encode(ExternalEncoding), input_name='value'), )) - def exportChildren(self, outfile, level, namespace_='', name_='actualType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for comment_ in self.comment: - comment_.export(outfile, level, namespace_, name_='comment', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='actualType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.value is not None and 'value' not in already_processed: - already_processed.add('value') - showIndent(outfile, level) - outfile.write('value="%s",\n' % (self.value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('comment=[\n') - level += 1 - for comment_ in self.comment: - showIndent(outfile, level) - outfile.write('model_.comment(\n') - comment_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('value', node) - if value is not None and 'value' not in already_processed: - already_processed.add('value') - self.value = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'comment': - obj_ = textType.factory() - obj_.build(child_) - self.comment.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'actualType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class actualType - - -class conditionType(GeneratedsSuper): - subclass = None - superclass = None - def __init__(self, type_=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.type_ = _cast(None, type_) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if conditionType.subclass: - return conditionType.subclass(*args_, **kwargs_) - else: - return conditionType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_type(self): return self.type_ - def set_type(self, type_): self.type_ = type_ - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='conditionType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='conditionType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='conditionType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='conditionType'): - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - outfile.write(' type=%s' % (self.gds_format_string(quote_attrib(self.type_).encode(ExternalEncoding), input_name='type'), )) - def exportChildren(self, outfile, level, namespace_='', name_='conditionType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='conditionType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.type_ is not None and 'type_' not in already_processed: - already_processed.add('type_') - showIndent(outfile, level) - outfile.write('type_="%s",\n' % (self.type_,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('type', node) - if value is not None and 'type' not in already_processed: - already_processed.add('type') - self.type_ = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class conditionType - - -class aidtype_flagType(GeneratedsSuper): - """Does this flag apply? If 'false' do not report the flag""" - subclass = None - superclass = None - def __init__(self, code=None, significance=None, anytypeobjs_=None, valueOf_=None, mixedclass_=None, content_=None): - self.code = _cast(None, code) - self.significance = _cast(bool, significance) - if anytypeobjs_ is None: - self.anytypeobjs_ = [] - else: - self.anytypeobjs_ = anytypeobjs_ - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - if mixedclass_ is None: - self.mixedclass_ = MixedContainer - else: - self.mixedclass_ = mixedclass_ - if content_ is None: - self.content_ = [] - else: - self.content_ = content_ - self.valueOf_ = valueOf_ - def factory(*args_, **kwargs_): - if aidtype_flagType.subclass: - return aidtype_flagType.subclass(*args_, **kwargs_) - else: - return aidtype_flagType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value) - def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value - def get_code(self): return self.code - def set_code(self, code): self.code = code - def get_significance(self): return self.significance - def set_significance(self, significance): self.significance = significance - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.anytypeobjs_ or - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='aidtype-flagType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='aidtype-flagType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='aidtype-flagType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='aidtype-flagType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - outfile.write(' code=%s' % (self.gds_format_string(quote_attrib(self.code).encode(ExternalEncoding), input_name='code'), )) - if self.significance is not None and 'significance' not in already_processed: - already_processed.add('significance') - outfile.write(' significance="%s"' % self.gds_format_boolean(self.significance, input_name='significance')) - def exportChildren(self, outfile, level, namespace_='', name_='aidtype-flagType', fromsubclass_=False, pretty_print=True): - if not fromsubclass_: - for item_ in self.content_: - item_.export(outfile, level, item_.name, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='aidtype-flagType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.code is not None and 'code' not in already_processed: - already_processed.add('code') - showIndent(outfile, level) - outfile.write('code="%s",\n' % (self.code,)) - if self.significance is not None and 'significance' not in already_processed: - already_processed.add('significance') - showIndent(outfile, level) - outfile.write('significance=%s,\n' % (self.significance,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('content_ = [\n') - for item_ in self.content_: - item_.exportLiteral(outfile, level, name_) - showIndent(outfile, level) - outfile.write('],\n') - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - if node.text is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', node.text) - self.content_.append(obj_) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('code', node) - if value is not None and 'code' not in already_processed: - already_processed.add('code') - self.code = value - value = find_attr_value_('significance', node) - if value is not None and 'significance' not in already_processed: - already_processed.add('significance') - if value in ('true', '1'): - self.significance = True - elif value in ('false', '0'): - self.significance = False - else: - raise_parse_error(node, 'Bad boolean attribute') - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == '': - obj_ = __ANY__.factory() - obj_.build(child_) - obj_ = self.mixedclass_(MixedContainer.CategoryComplex, - MixedContainer.TypeNone, '', obj_) - self.content_.append(obj_) - if hasattr(self, 'add_'): - self.add_(obj_.value) - elif hasattr(self, 'set_'): - self.set_(obj_.value) - if not fromsubclass_ and child_.tail is not None: - obj_ = self.mixedclass_(MixedContainer.CategoryText, - MixedContainer.TypeNone, '', child_.tail) - self.content_.append(obj_) -# end class aidtype_flagType - - -class loan_termsType(GeneratedsSuper): - """Interest Rate. If an ODA loan with variable interest rate, report - the variable rate here and the reference fixed rate as rate-2 - Enter the rate without the percentage sign. Second Interest - Rate. If an ODA loan with variable interest rate, report the - variable rate as rate-1 and the reference fixed rate here Enter - the rate without the percentage sign.""" - subclass = None - superclass = None - def __init__(self, rate_2=None, rate_1=None, repayment_type=None, repayment_plan=None, commitment_date=None, repayment_first_date=None, repayment_final_date=None, anytypeobjs_=None): - self.rate_2 = _cast(float, rate_2) - self.rate_1 = _cast(float, rate_1) - if repayment_type is None: - self.repayment_type = [] - else: - self.repayment_type = repayment_type - if repayment_plan is None: - self.repayment_plan = [] - else: - self.repayment_plan = repayment_plan - if commitment_date is None: - self.commitment_date = [] - else: - self.commitment_date = commitment_date - if repayment_first_date is None: - self.repayment_first_date = [] - else: - self.repayment_first_date = repayment_first_date - if repayment_final_date is None: - self.repayment_final_date = [] - else: - self.repayment_final_date = repayment_final_date - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if loan_termsType.subclass: - return loan_termsType.subclass(*args_, **kwargs_) - else: - return loan_termsType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_repayment_type(self): return self.repayment_type - def set_repayment_type(self, repayment_type): self.repayment_type = repayment_type - def add_repayment_type(self, value): self.repayment_type.append(value) - def insert_repayment_type(self, index, value): self.repayment_type[index] = value - def get_repayment_plan(self): return self.repayment_plan - def set_repayment_plan(self, repayment_plan): self.repayment_plan = repayment_plan - def add_repayment_plan(self, value): self.repayment_plan.append(value) - def insert_repayment_plan(self, index, value): self.repayment_plan[index] = value - def get_commitment_date(self): return self.commitment_date - def set_commitment_date(self, commitment_date): self.commitment_date = commitment_date - def add_commitment_date(self, value): self.commitment_date.append(value) - def insert_commitment_date(self, index, value): self.commitment_date[index] = value - def get_repayment_first_date(self): return self.repayment_first_date - def set_repayment_first_date(self, repayment_first_date): self.repayment_first_date = repayment_first_date - def add_repayment_first_date(self, value): self.repayment_first_date.append(value) - def insert_repayment_first_date(self, index, value): self.repayment_first_date[index] = value - def get_repayment_final_date(self): return self.repayment_final_date - def set_repayment_final_date(self, repayment_final_date): self.repayment_final_date = repayment_final_date - def add_repayment_final_date(self, value): self.repayment_final_date.append(value) - def insert_repayment_final_date(self, index, value): self.repayment_final_date[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_rate_2(self): return self.rate_2 - def set_rate_2(self, rate_2): self.rate_2 = rate_2 - def get_rate_1(self): return self.rate_1 - def set_rate_1(self, rate_1): self.rate_1 = rate_1 - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.repayment_type or - self.repayment_plan or - self.commitment_date or - self.repayment_first_date or - self.repayment_final_date or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='loan-termsType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='loan-termsType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='loan-termsType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='loan-termsType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.rate_2 is not None and 'rate_2' not in already_processed: - already_processed.add('rate_2') - outfile.write(' rate-2="%s"' % self.gds_format_float(self.rate_2, input_name='rate-2')) - if self.rate_1 is not None and 'rate_1' not in already_processed: - already_processed.add('rate_1') - outfile.write(' rate-1="%s"' % self.gds_format_float(self.rate_1, input_name='rate-1')) - def exportChildren(self, outfile, level, namespace_='', name_='loan-termsType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for repayment_type_ in self.repayment_type: - repayment_type_.export(outfile, level, namespace_, name_='repayment-type', pretty_print=pretty_print) - for repayment_plan_ in self.repayment_plan: - repayment_plan_.export(outfile, level, namespace_, name_='repayment-plan', pretty_print=pretty_print) - for commitment_date_ in self.commitment_date: - commitment_date_.export(outfile, level, namespace_, name_='commitment-date', pretty_print=pretty_print) - for repayment_first_date_ in self.repayment_first_date: - repayment_first_date_.export(outfile, level, namespace_, name_='repayment-first-date', pretty_print=pretty_print) - for repayment_final_date_ in self.repayment_final_date: - repayment_final_date_.export(outfile, level, namespace_, name_='repayment-final-date', pretty_print=pretty_print) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='loan-termsType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.rate_2 is not None and 'rate_2' not in already_processed: - already_processed.add('rate_2') - showIndent(outfile, level) - outfile.write('rate_2=%f,\n' % (self.rate_2,)) - if self.rate_1 is not None and 'rate_1' not in already_processed: - already_processed.add('rate_1') - showIndent(outfile, level) - outfile.write('rate_1=%f,\n' % (self.rate_1,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('repayment_type=[\n') - level += 1 - for repayment_type_ in self.repayment_type: - showIndent(outfile, level) - outfile.write('model_.codeType(\n') - repayment_type_.exportLiteral(outfile, level, name_='codeType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('repayment_plan=[\n') - level += 1 - for repayment_plan_ in self.repayment_plan: - showIndent(outfile, level) - outfile.write('model_.codeType(\n') - repayment_plan_.exportLiteral(outfile, level, name_='codeType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('commitment_date=[\n') - level += 1 - for commitment_date_ in self.commitment_date: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - commitment_date_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('repayment_first_date=[\n') - level += 1 - for repayment_first_date_ in self.repayment_first_date: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - repayment_first_date_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('repayment_final_date=[\n') - level += 1 - for repayment_final_date_ in self.repayment_final_date: - showIndent(outfile, level) - outfile.write('model_.dateType(\n') - repayment_final_date_.exportLiteral(outfile, level, name_='dateType') - showIndent(outfile, level) - outfile.write('),\n') - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('rate-2', node) - if value is not None and 'rate-2' not in already_processed: - already_processed.add('rate-2') - try: - self.rate_2 = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (rate-2): %s' % exp) - value = find_attr_value_('rate-1', node) - if value is not None and 'rate-1' not in already_processed: - already_processed.add('rate-1') - try: - self.rate_1 = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (rate-1): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'repayment-type': - obj_ = codeType.factory() - obj_.build(child_) - self.repayment_type.append(obj_) - elif nodeName_ == 'repayment-plan': - obj_ = codeType.factory() - obj_.build(child_) - self.repayment_plan.append(obj_) - elif nodeName_ == 'commitment-date': - obj_ = dateType.factory() - obj_.build(child_) - self.commitment_date.append(obj_) - elif nodeName_ == 'repayment-first-date': - obj_ = dateType.factory() - obj_.build(child_) - self.repayment_first_date.append(obj_) - elif nodeName_ == 'repayment-final-date': - obj_ = dateType.factory() - obj_.build(child_) - self.repayment_final_date.append(obj_) - else: - obj_ = self.gds_build_any(child_, 'loan-termsType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class loan_termsType - - -class loan_statusType(GeneratedsSuper): - """CRS Reporting Year (CRS++ Column 1)""" - subclass = None - superclass = None - def __init__(self, currency=None, value_date=None, year=None, interest_received=None, principal_outstanding=None, principal_arrears=None, interest_arrears=None, anytypeobjs_=None): - self.currency = _cast(None, currency) - self.value_date = _cast(None, value_date) - self.year = _cast(float, year) - if interest_received is None: - self.interest_received = [] - else: - self.interest_received = interest_received - if principal_outstanding is None: - self.principal_outstanding = [] - else: - self.principal_outstanding = principal_outstanding - if principal_arrears is None: - self.principal_arrears = [] - else: - self.principal_arrears = principal_arrears - if interest_arrears is None: - self.interest_arrears = [] - else: - self.interest_arrears = interest_arrears - self.anytypeobjs_ = anytypeobjs_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if loan_statusType.subclass: - return loan_statusType.subclass(*args_, **kwargs_) - else: - return loan_statusType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_interest_received(self): return self.interest_received - def set_interest_received(self, interest_received): self.interest_received = interest_received - def add_interest_received(self, value): self.interest_received.append(value) - def insert_interest_received(self, index, value): self.interest_received[index] = value - def get_principal_outstanding(self): return self.principal_outstanding - def set_principal_outstanding(self, principal_outstanding): self.principal_outstanding = principal_outstanding - def add_principal_outstanding(self, value): self.principal_outstanding.append(value) - def insert_principal_outstanding(self, index, value): self.principal_outstanding[index] = value - def get_principal_arrears(self): return self.principal_arrears - def set_principal_arrears(self, principal_arrears): self.principal_arrears = principal_arrears - def add_principal_arrears(self, value): self.principal_arrears.append(value) - def insert_principal_arrears(self, index, value): self.principal_arrears[index] = value - def get_interest_arrears(self): return self.interest_arrears - def set_interest_arrears(self, interest_arrears): self.interest_arrears = interest_arrears - def add_interest_arrears(self, value): self.interest_arrears.append(value) - def insert_interest_arrears(self, index, value): self.interest_arrears[index] = value - def get_anytypeobjs_(self): return self.anytypeobjs_ - def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_ - def get_currency(self): return self.currency - def set_currency(self, currency): self.currency = currency - def get_value_date(self): return self.value_date - def set_value_date(self, value_date): self.value_date = value_date - def get_year(self): return self.year - def set_year(self, year): self.year = year - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.interest_received or - self.principal_outstanding or - self.principal_arrears or - self.interest_arrears or - self.anytypeobjs_ is not None - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='loan-statusType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='loan-statusType') - if self.hasContent_(): - outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespace_='', name_='loan-statusType', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='loan-statusType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.currency is not None and 'currency' not in already_processed: - already_processed.add('currency') - outfile.write(' currency=%s' % (self.gds_format_string(quote_attrib(self.currency).encode(ExternalEncoding), input_name='currency'), )) - if self.value_date is not None and 'value_date' not in already_processed: - already_processed.add('value_date') - outfile.write(' value-date=%s' % (self.gds_format_string(quote_attrib(self.value_date).encode(ExternalEncoding), input_name='value-date'), )) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - outfile.write(' year="%s"' % self.gds_format_float(self.year, input_name='year')) - def exportChildren(self, outfile, level, namespace_='', name_='loan-statusType', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - for interest_received_ in self.interest_received: - showIndent(outfile, level, pretty_print) - outfile.write('<%sinterest-received>%s%s' % (namespace_, self.gds_format_float(interest_received_, input_name='interest-received'), namespace_, eol_)) - for principal_outstanding_ in self.principal_outstanding: - showIndent(outfile, level, pretty_print) - outfile.write('<%sprincipal-outstanding>%s%s' % (namespace_, self.gds_format_float(principal_outstanding_, input_name='principal-outstanding'), namespace_, eol_)) - for principal_arrears_ in self.principal_arrears: - showIndent(outfile, level, pretty_print) - outfile.write('<%sprincipal-arrears>%s%s' % (namespace_, self.gds_format_float(principal_arrears_, input_name='principal-arrears'), namespace_, eol_)) - for interest_arrears_ in self.interest_arrears: - showIndent(outfile, level, pretty_print) - outfile.write('<%sinterest-arrears>%s%s' % (namespace_, self.gds_format_float(interest_arrears_, input_name='interest-arrears'), namespace_, eol_)) - if self.anytypeobjs_ is not None: - self.anytypeobjs_.export(outfile, level, namespace_, pretty_print=pretty_print) - def exportLiteral(self, outfile, level, name_='loan-statusType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.currency is not None and 'currency' not in already_processed: - already_processed.add('currency') - showIndent(outfile, level) - outfile.write('currency="%s",\n' % (self.currency,)) - if self.value_date is not None and 'value_date' not in already_processed: - already_processed.add('value_date') - showIndent(outfile, level) - outfile.write('value_date="%s",\n' % (self.value_date,)) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - showIndent(outfile, level) - outfile.write('year=%f,\n' % (self.year,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - showIndent(outfile, level) - outfile.write('interest_received=[\n') - level += 1 - for interest_received_ in self.interest_received: - showIndent(outfile, level) - outfile.write('%f,\n' % interest_received_) - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('principal_outstanding=[\n') - level += 1 - for principal_outstanding_ in self.principal_outstanding: - showIndent(outfile, level) - outfile.write('%f,\n' % principal_outstanding_) - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('principal_arrears=[\n') - level += 1 - for principal_arrears_ in self.principal_arrears: - showIndent(outfile, level) - outfile.write('%f,\n' % principal_arrears_) - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - showIndent(outfile, level) - outfile.write('interest_arrears=[\n') - level += 1 - for interest_arrears_ in self.interest_arrears: - showIndent(outfile, level) - outfile.write('%f,\n' % interest_arrears_) - level -= 1 - showIndent(outfile, level) - outfile.write('],\n') - if self.anytypeobjs_ is not None: - showIndent(outfile, level) - outfile.write('anytypeobjs_=model_.anytypeobjs_(\n') - self.anytypeobjs_.exportLiteral(outfile, level) - showIndent(outfile, level) - outfile.write('),\n') - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('currency', node) - if value is not None and 'currency' not in already_processed: - already_processed.add('currency') - self.currency = value - value = find_attr_value_('value-date', node) - if value is not None and 'value-date' not in already_processed: - already_processed.add('value-date') - self.value_date = value - value = find_attr_value_('year', node) - if value is not None and 'year' not in already_processed: - already_processed.add('year') - try: - self.year = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (year): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'interest-received': - sval_ = child_.text - try: - fval_ = float(sval_) - except (TypeError, ValueError), exp: - raise_parse_error(child_, 'requires float or double: %s' % exp) - fval_ = self.gds_validate_float(fval_, node, 'interest_received') - self.interest_received.append(fval_) - elif nodeName_ == 'principal-outstanding': - sval_ = child_.text - try: - fval_ = float(sval_) - except (TypeError, ValueError), exp: - raise_parse_error(child_, 'requires float or double: %s' % exp) - fval_ = self.gds_validate_float(fval_, node, 'principal_outstanding') - self.principal_outstanding.append(fval_) - elif nodeName_ == 'principal-arrears': - sval_ = child_.text - try: - fval_ = float(sval_) - except (TypeError, ValueError), exp: - raise_parse_error(child_, 'requires float or double: %s' % exp) - fval_ = self.gds_validate_float(fval_, node, 'principal_arrears') - self.principal_arrears.append(fval_) - elif nodeName_ == 'interest-arrears': - sval_ = child_.text - try: - fval_ = float(sval_) - except (TypeError, ValueError), exp: - raise_parse_error(child_, 'requires float or double: %s' % exp) - fval_ = self.gds_validate_float(fval_, node, 'interest_arrears') - self.interest_arrears.append(fval_) - else: - obj_ = self.gds_build_any(child_, 'loan-statusType') - if obj_ is not None: - self.set_anytypeobjs_(obj_) -# end class loan_statusType - - -class forecastType(GeneratedsSuper): - """The calendar year that the forward spend covers""" - subclass = None - superclass = None - def __init__(self, currency=None, value_date=None, year=None, valueOf_=None): - self.currency = _cast(None, currency) - self.value_date = _cast(None, value_date) - self.year = _cast(float, year) - self.valueOf_ = valueOf_ - self.anyAttributes_ = {} - def factory(*args_, **kwargs_): - if forecastType.subclass: - return forecastType.subclass(*args_, **kwargs_) - else: - return forecastType(*args_, **kwargs_) - factory = staticmethod(factory) - def get_currency(self): return self.currency - def set_currency(self, currency): self.currency = currency - def get_value_date(self): return self.value_date - def set_value_date(self, value_date): self.value_date = value_date - def get_year(self): return self.year - def set_year(self, year): self.year = year - def get_valueOf_(self): return self.valueOf_ - def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_ - def get_anyAttributes_(self): return self.anyAttributes_ - def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_ - def hasContent_(self): - if ( - self.valueOf_ - ): - return True - else: - return False - def export(self, outfile, level, namespace_='', name_='forecastType', namespacedef_='', pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - showIndent(outfile, level, pretty_print) - outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) - already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespace_, name_='forecastType') - if self.hasContent_(): - outfile.write('>') - outfile.write(str(self.valueOf_).encode(ExternalEncoding)) - self.exportChildren(outfile, level + 1, namespace_='', name_='forecastType', pretty_print=pretty_print) - outfile.write('%s' % (namespace_, name_, eol_)) - else: - outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='forecastType'): - unique_counter = 0 - for name, value in self.anyAttributes_.items(): - xsinamespaceprefix = 'xsi' - xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance' - xsinamespace2 = '{%s}' % (xsinamespace1, ) - if name.startswith(xsinamespace2): - name1 = name[len(xsinamespace2):] - name2 = '%s:%s' % (xsinamespaceprefix, name1, ) - if name2 not in already_processed: - already_processed.add(name2) - outfile.write(' %s=%s' % (name2, quote_attrib(value), )) - else: - mo = re_.match(Namespace_extract_pat_, name) - if mo is not None: - namespace, name = mo.group(1, 2) - if name not in already_processed: - already_processed.add(name) - if namespace == 'http://www.w3.org/XML/1998/namespace': - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - else: - unique_counter += 1 - outfile.write(' xmlns:yyy%d="%s"' % ( - unique_counter, namespace, )) - outfile.write(' yyy%d:%s=%s' % ( - unique_counter, name, quote_attrib(value), )) - else: - if name not in already_processed: - already_processed.add(name) - outfile.write(' %s=%s' % ( - name, quote_attrib(value), )) - if self.currency is not None and 'currency' not in already_processed: - already_processed.add('currency') - outfile.write(' currency=%s' % (self.gds_format_string(quote_attrib(self.currency).encode(ExternalEncoding), input_name='currency'), )) - if self.value_date is not None and 'value_date' not in already_processed: - already_processed.add('value_date') - outfile.write(' value-date=%s' % (self.gds_format_string(quote_attrib(self.value_date).encode(ExternalEncoding), input_name='value-date'), )) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - outfile.write(' year="%s"' % self.gds_format_float(self.year, input_name='year')) - def exportChildren(self, outfile, level, namespace_='', name_='forecastType', fromsubclass_=False, pretty_print=True): - pass - def exportLiteral(self, outfile, level, name_='forecastType'): - level += 1 - already_processed = set() - self.exportLiteralAttributes(outfile, level, already_processed, name_) - if self.hasContent_(): - self.exportLiteralChildren(outfile, level, name_) - showIndent(outfile, level) - outfile.write('valueOf_ = """%s""",\n' % (self.valueOf_,)) - def exportLiteralAttributes(self, outfile, level, already_processed, name_): - if self.currency is not None and 'currency' not in already_processed: - already_processed.add('currency') - showIndent(outfile, level) - outfile.write('currency="%s",\n' % (self.currency,)) - if self.value_date is not None and 'value_date' not in already_processed: - already_processed.add('value_date') - showIndent(outfile, level) - outfile.write('value_date="%s",\n' % (self.value_date,)) - if self.year is not None and 'year' not in already_processed: - already_processed.add('year') - showIndent(outfile, level) - outfile.write('year=%f,\n' % (self.year,)) - for name, value in self.anyAttributes_.items(): - showIndent(outfile, level) - outfile.write('%s="%s",\n' % (name, value,)) - def exportLiteralChildren(self, outfile, level, name_): - pass - def build(self, node): - already_processed = set() - self.buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self.buildChildren(child, node, nodeName_) - return self - def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('currency', node) - if value is not None and 'currency' not in already_processed: - already_processed.add('currency') - self.currency = value - value = find_attr_value_('value-date', node) - if value is not None and 'value-date' not in already_processed: - already_processed.add('value-date') - self.value_date = value - value = find_attr_value_('year', node) - if value is not None and 'year' not in already_processed: - already_processed.add('year') - try: - self.year = float(value) - except ValueError, exp: - raise ValueError('Bad float/double attribute (year): %s' % exp) - self.anyAttributes_ = {} - for name, value in attrs.items(): - if name not in already_processed: - self.anyAttributes_[name] = value - def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - pass -# end class forecastType - - -GDSClassesMapping = { - 'comment': textType, - 'person-name': textType, - 'default-tied-status': codeReqType, - 'telephone': telephoneType, - 'repayment-plan': codeType, - 'budget-item': budget_itemType, - 'repayment-first-date': dateType, - 'period-start': dateType, - 'loan-status': loan_statusType, - 'transaction-date': transaction_dateType, - 'forecast': forecastType, - 'loan-terms': loan_termsType, - 'category': codeReqType, - 'indicator': indicatorType, - 'aid-type': codeReqType, - 'baseline': baselineType, - 'receiver-org': receiver_orgType, - 'title': textType, - 'period-end': dateType, - 'organisation': textType, - 'aidtype-flag': aidtype_flagType, - 'coordinates': coordinatesType, - 'finance-type': codeReqType, - 'repayment-type': codeType, - 'commitment-date': dateType, - 'administrative': administrativeType, - 'email': plainType, - 'flow-type': codeReqType, - 'description': textType, - 'repayment-final-date': dateType, - 'disbursement-channel': codeReqType, - 'gazetteer-entry': gazetteer_entryType, - 'language': codeType, - 'collaboration-type': codeReqType, - 'default-finance-type': codeReqType, - 'job-title': textType, - 'default-aid-type': codeReqType, - 'transaction-type': codeReqType, - 'condition': conditionType, - 'target': targetType, - 'activity-scope': codeType, - 'mailing-address': mailing_addressType, - 'actual': actualType, - 'name': textType, - 'provider-org': provider_orgType, - 'value': currencyType, - 'tied-status': codeReqType, - 'period': periodType, - 'location-type': codeReqType, - 'activity-status': codeType, - 'default-flow-type': codeReqType, -} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print USAGE_TEXT - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - rootClass = GDSClassesMapping.get(tag) - if rootClass is None: - rootClass = globals().get(tag) - return tag, rootClass - - -def parse(inFileName, silence=False): - doc = parsexml_(inFileName) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = 'iati-activities' - rootClass = iati_activities - rootObj = rootClass.factory() - rootObj.build(rootNode) - # Enable Python to collect the space used by the DOM. - doc = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, - namespacedef_='', - pretty_print=True) - return rootObj - - -def parseEtree(inFileName, silence=False): - doc = parsexml_(inFileName) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = 'iati-activities' - rootClass = iati_activities - rootObj = rootClass.factory() - rootObj.build(rootNode) - # Enable Python to collect the space used by the DOM. - doc = None - mapping = {} - rootElement = rootObj.to_etree(None, name_=rootTag, mapping_=mapping) - reverse_mapping = rootObj.gds_reverse_node_mapping(mapping) - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, - xml_declaration=True, encoding="utf-8") - sys.stdout.write(content) - sys.stdout.write('\n') - return rootObj, rootElement, mapping, reverse_mapping - - -def parseString(inString, silence=False): - from StringIO import StringIO - doc = parsexml_(StringIO(inString)) - rootNode = doc.getroot() - roots = get_root_tag(rootNode) - rootClass = roots[1] - if rootClass is None: - rootClass = iati_activities - rootObj = rootClass.factory() - rootObj.build(rootNode) - # Enable Python to collect the space used by the DOM. - doc = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_="iati-activities", - namespacedef_='') - return rootObj - - -def parseLiteral(inFileName, silence=False): - doc = parsexml_(inFileName) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = 'iati-activities' - rootClass = iati_activities - rootObj = rootClass.factory() - rootObj.build(rootNode) - # Enable Python to collect the space used by the DOM. - doc = None - if not silence: - sys.stdout.write('#from gendstest import *\n\n') - sys.stdout.write('import gendstest as model_\n\n') - sys.stdout.write('rootObj = model_.rootTag(\n') - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(')\n') - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == '__main__': - #import pdb; pdb.set_trace() - main() - - -__all__ = [ - "activity_date", - "activity_website", - "actualType", - "administrativeType", - "aidtype_flagType", - "baselineType", - "budget", - "budget_itemType", - "capital_spend", - "codeReqType", - "codeType", - "conditionType", - "conditions", - "contact_info", - "coordinatesType", - "country_budget_items", - "crs_add", - "currencyType", - "dateReqType", - "dateType", - "description", - "document_link", - "forecastType", - "fss", - "gazetteer_entryType", - "iati_activities", - "iati_activity", - "iati_identifier", - "indicatorOutcomeType", - "indicatorType", - "legacy_data", - "loan_statusType", - "loan_termsType", - "location", - "mailing_addressType", - "other_identifier", - "participating_org", - "periodType", - "plainType", - "planned_disbursement", - "policy_marker", - "provider_orgType", - "receiver_orgType", - "recipient_country", - "recipient_region", - "refReqType", - "refType", - "related_activity", - "reporting_org", - "result", - "sector", - "targetType", - "telephoneType", - "textType", - "transaction", - "transaction_dateType" -] diff --git a/akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py b/akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py new file mode 100644 index 0000000000..4b799cee06 --- /dev/null +++ b/akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py @@ -0,0 +1,842 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'FssForecast' + db.create_table(u'rsr_fssforecast', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('fss', self.gf('django.db.models.fields.related.ForeignKey')(related_name='forecasts', to=orm['rsr.Fss'])), + ('year', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=4, null=True, blank=True)), + ('value_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('currency', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=3, blank=True)), + ('value', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), + )) + db.send_create_signal('rsr', ['FssForecast']) + + # Adding model 'Fss' + db.create_table(u'rsr_fss', ( + ('project', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['rsr.Project'], unique=True, primary_key=True)), + ('extraction_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('priority', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), + ('phaseout_year', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=4, null=True, blank=True)), + )) + db.send_create_signal('rsr', ['Fss']) + + # Adding model 'CrsAdd' + db.create_table(u'rsr_crsadd', ( + ('project', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['rsr.Project'], unique=True, primary_key=True)), + ('loan_terms_rate1', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2, blank=True)), + ('loan_terms_rate2', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2, blank=True)), + ('repayment_type', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=1)), + ('repayment_plan', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=2)), + ('commitment_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('repayment_first_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('repayment_final_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('loan_status_year', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=4, null=True, blank=True)), + ('loan_status_currency', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=3, blank=True)), + ('loan_status_value_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('interest_received', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), + ('principal_outstanding', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), + ('principal_arrears', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), + ('interest_arrears', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), + )) + db.send_create_signal('rsr', ['CrsAdd']) + + # Adding model 'CrsAddOtherFlag' + db.create_table(u'rsr_crsaddotherflag', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('crs', self.gf('django.db.models.fields.related.ForeignKey')(related_name='other_flags', to=orm['rsr.CrsAdd'])), + ('code', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=1)), + ('significance', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), + )) + db.send_create_signal('rsr', ['CrsAddOtherFlag']) + + # Deleting field 'Result.description_type' + db.delete_column(u'rsr_result', 'description_type') + + # Deleting field 'Indicator.description_type' + db.delete_column(u'rsr_indicator', 'description_type') + + # Adding field 'RelatedProject.related_iati_id' + db.add_column(u'rsr_relatedproject', 'related_iati_id', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + + # Changing field 'RelatedProject.related_project' + db.alter_column(u'rsr_relatedproject', 'related_project_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, on_delete=models.SET_NULL, to=orm['rsr.Project'])) + # Adding field 'Project.conditions_attached' + db.add_column(u'rsr_project', 'conditions_attached', + self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True), + keep_default=False) + + # Adding field 'Project.country_budget_vocabulary' + db.add_column(u'rsr_project', 'country_budget_vocabulary', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), + keep_default=False) + + # Deleting field 'CountryBudgetItem.vocabulary' + db.delete_column(u'rsr_countrybudgetitem', 'vocabulary') + + # Deleting field 'Transaction.finance_type_text' + db.delete_column(u'rsr_transaction', 'finance_type_text') + + # Deleting field 'Transaction.aid_type_text' + db.delete_column(u'rsr_transaction', 'aid_type_text') + + # Deleting field 'Transaction.transaction_type_text' + db.delete_column(u'rsr_transaction', 'transaction_type_text') + + # Deleting field 'Transaction.flow_type_text' + db.delete_column(u'rsr_transaction', 'flow_type_text') + + # Deleting field 'Transaction.disbursement_channel_text' + db.delete_column(u'rsr_transaction', 'disbursement_channel_text') + + # Deleting field 'Transaction.tied_status_text' + db.delete_column(u'rsr_transaction', 'tied_status_text') + + # Adding field 'Transaction.recipient_country' + db.add_column(u'rsr_transaction', 'recipient_country', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=2, blank=True), + keep_default=False) + + # Adding field 'Transaction.recipient_region' + db.add_column(u'rsr_transaction', 'recipient_region', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=3, blank=True), + keep_default=False) + + # Adding field 'Transaction.recipient_region_vocabulary' + db.add_column(u'rsr_transaction', 'recipient_region_vocabulary', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), + keep_default=False) + + # Adding field 'Transaction.sector' + db.add_column(u'rsr_transaction', 'sector', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=5, blank=True), + keep_default=False) + + # Adding field 'Transaction.sector_category' + db.add_column(u'rsr_transaction', 'sector_category', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=3, blank=True), + keep_default=False) + + # Adding field 'Transaction.sector_other' + db.add_column(u'rsr_transaction', 'sector_other', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=50, blank=True), + keep_default=False) + + # Deleting field 'ProjectCondition.attached' + db.delete_column(u'rsr_projectcondition', 'attached') + + + def backwards(self, orm): + # Deleting model 'FssForecast' + db.delete_table(u'rsr_fssforecast') + + # Deleting model 'Fss' + db.delete_table(u'rsr_fss') + + # Deleting model 'CrsAdd' + db.delete_table(u'rsr_crsadd') + + # Deleting model 'CrsAddOtherFlag' + db.delete_table(u'rsr_crsaddotherflag') + + # Adding field 'Result.description_type' + db.add_column(u'rsr_result', 'description_type', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), + keep_default=False) + + # Adding field 'Indicator.description_type' + db.add_column(u'rsr_indicator', 'description_type', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), + keep_default=False) + + # Deleting field 'RelatedProject.related_iati_id' + db.delete_column(u'rsr_relatedproject', 'related_iati_id') + + + # Changing field 'RelatedProject.related_project' + db.alter_column(u'rsr_relatedproject', 'related_project_id', self.gf('django.db.models.fields.related.ForeignKey')(default='', to=orm['rsr.Project'])) + # Deleting field 'Project.conditions_attached' + db.delete_column(u'rsr_project', 'conditions_attached') + + # Deleting field 'Project.country_budget_vocabulary' + db.delete_column(u'rsr_project', 'country_budget_vocabulary') + + # Adding field 'CountryBudgetItem.vocabulary' + db.add_column(u'rsr_countrybudgetitem', 'vocabulary', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), + keep_default=False) + + # Adding field 'Transaction.finance_type_text' + db.add_column(u'rsr_transaction', 'finance_type_text', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + # Adding field 'Transaction.aid_type_text' + db.add_column(u'rsr_transaction', 'aid_type_text', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + # Adding field 'Transaction.transaction_type_text' + db.add_column(u'rsr_transaction', 'transaction_type_text', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + # Adding field 'Transaction.flow_type_text' + db.add_column(u'rsr_transaction', 'flow_type_text', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + # Adding field 'Transaction.disbursement_channel_text' + db.add_column(u'rsr_transaction', 'disbursement_channel_text', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + # Adding field 'Transaction.tied_status_text' + db.add_column(u'rsr_transaction', 'tied_status_text', + self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), + keep_default=False) + + # Deleting field 'Transaction.recipient_country' + db.delete_column(u'rsr_transaction', 'recipient_country') + + # Deleting field 'Transaction.recipient_region' + db.delete_column(u'rsr_transaction', 'recipient_region') + + # Deleting field 'Transaction.recipient_region_vocabulary' + db.delete_column(u'rsr_transaction', 'recipient_region_vocabulary') + + # Deleting field 'Transaction.sector' + db.delete_column(u'rsr_transaction', 'sector') + + # Deleting field 'Transaction.sector_category' + db.delete_column(u'rsr_transaction', 'sector_category') + + # Deleting field 'Transaction.sector_other' + db.delete_column(u'rsr_transaction', 'sector_other') + + # Adding field 'ProjectCondition.attached' + db.add_column(u'rsr_projectcondition', 'attached', + self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True), + keep_default=False) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'rsr.benchmark': { + 'Meta': {'ordering': "('category__name', 'name__order')", 'object_name': 'Benchmark'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Category']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Benchmarkname']"}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'benchmarks'", 'to': "orm['rsr.Project']"}), + 'value': ('django.db.models.fields.IntegerField', [], {}) + }, + 'rsr.benchmarkname': { + 'Meta': {'ordering': "['order', 'name']", 'object_name': 'Benchmarkname'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '80'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + 'rsr.budgetitem': { + 'Meta': {'ordering': "('label',)", 'unique_together': "(('project', 'label'),)", 'object_name': 'BudgetItem'}, + 'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}), + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.BudgetItemLabel']"}), + 'other_extra': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), + 'period_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'period_end_text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'period_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'period_start_text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'budget_items'", 'to': "orm['rsr.Project']"}), + 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'rsr.budgetitemlabel': { + 'Meta': {'ordering': "('label',)", 'object_name': 'BudgetItemLabel'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '20', 'db_index': 'True'}) + }, + 'rsr.category': { + 'Meta': {'ordering': "['name']", 'object_name': 'Category'}, + 'benchmarknames': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['rsr.Benchmarkname']", 'symmetrical': 'False', 'blank': 'True'}), + 'focus_area': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'categories'", 'symmetrical': 'False', 'to': "orm['rsr.FocusArea']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'db_index': 'True'}) + }, + 'rsr.country': { + 'Meta': {'ordering': "['name']", 'object_name': 'Country'}, + 'continent': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'db_index': 'True'}), + 'continent_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'db_index': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iso_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '2', 'db_index': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}) + }, + 'rsr.countrybudgetitem': { + 'Meta': {'object_name': 'CountryBudgetItem'}, + 'code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '6', 'blank': 'True'}), + 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'country_budget_items'", 'to': "orm['rsr.Project']"}) + }, + 'rsr.crsadd': { + 'Meta': {'object_name': 'CrsAdd'}, + 'commitment_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'interest_arrears': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'interest_received': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'loan_status_currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'loan_status_value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'loan_status_year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'loan_terms_rate1': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2', 'blank': 'True'}), + 'loan_terms_rate2': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2', 'blank': 'True'}), + 'principal_arrears': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'principal_outstanding': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True', 'primary_key': 'True'}), + 'repayment_final_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'repayment_first_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'repayment_plan': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2'}), + 'repayment_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}) + }, + 'rsr.crsaddotherflag': { + 'Meta': {'object_name': 'CrsAddOtherFlag'}, + 'code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}), + 'crs': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'other_flags'", 'to': "orm['rsr.CrsAdd']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'significance': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}) + }, + 'rsr.employment': { + 'Meta': {'object_name': 'Employment'}, + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']", 'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'employments'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'job_title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'organisation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'employees'", 'to': "orm['rsr.Organisation']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'employers'", 'to': "orm['rsr.User']"}) + }, + 'rsr.focusarea': { + 'Meta': {'ordering': "['name']", 'object_name': 'FocusArea'}, + 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'max_length': '500'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100'}), + 'link_to': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}) + }, + 'rsr.fss': { + 'Meta': {'object_name': 'Fss'}, + 'extraction_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'phaseout_year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'priority': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'rsr.fssforecast': { + 'Meta': {'object_name': 'FssForecast'}, + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'fss': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'forecasts'", 'to': "orm['rsr.Fss']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'value': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}) + }, + 'rsr.goal': { + 'Meta': {'object_name': 'Goal'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'goals'", 'to': "orm['rsr.Project']"}), + 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}) + }, + 'rsr.indicator': { + 'Meta': {'object_name': 'Indicator'}, + 'ascending': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'baseline_comment': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'baseline_value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'baseline_year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'measure': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'result': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'indicators'", 'to': "orm['rsr.Result']"}), + 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'rsr.indicatorperiod': { + 'Meta': {'object_name': 'IndicatorPeriod'}, + 'actual_comment': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'actual_value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'indicator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'periods'", 'to': "orm['rsr.Indicator']"}), + 'period_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'period_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'target_comment': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'target_value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) + }, + 'rsr.internalorganisationid': { + 'Meta': {'unique_together': "(('recording_org', 'referenced_org'),)", 'object_name': 'InternalOrganisationID'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'identifier': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '200'}), + 'recording_org': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'internal_ids'", 'to': "orm['rsr.Organisation']"}), + 'referenced_org': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reference_ids'", 'to': "orm['rsr.Organisation']"}) + }, + 'rsr.invoice': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Invoice'}, + 'amount': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'amount_received': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'bank': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '4', 'blank': 'True'}), + 'campaign_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '15', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'engine': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'paypal'", 'max_length': '10'}), + 'http_referer': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ipn': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invoices'", 'to': "orm['rsr.Project']"}), + 'status': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}), + 'test': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'transaction_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.User']", 'null': 'True', 'blank': 'True'}) + }, + 'rsr.keyword': { + 'Meta': {'ordering': "('label',)", 'object_name': 'Keyword'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '30', 'db_index': 'True'}) + }, + 'rsr.legacydata': { + 'Meta': {'object_name': 'LegacyData'}, + 'iati_equivalent': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'legacy_data'", 'to': "orm['rsr.Project']"}), + 'value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}) + }, + 'rsr.link': { + 'Meta': {'object_name': 'Link'}, + 'caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'links'", 'to': "orm['rsr.Project']"}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'rsr.molliegateway': { + 'Meta': {'object_name': 'MollieGateway'}, + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'EUR'", 'max_length': '3'}), + 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255'}), + 'notification_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'partner_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10'}) + }, + 'rsr.organisation': { + 'Meta': {'ordering': "['name']", 'object_name': 'Organisation'}, + 'allow_edit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'contact_email': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'contact_person': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), + 'content_owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Organisation']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), + 'facebook': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'fax': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'blank': 'True'}), + 'iati_org_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '75', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_org_ids': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'recording_organisation'", 'symmetrical': 'False', 'through': "orm['rsr.InternalOrganisationID']", 'to': "orm['rsr.Organisation']"}), + 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '2'}), + 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'linkedin': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'logo': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'long_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), + 'mobile': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'blank': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'db_index': 'True'}), + 'new_organisation_type': ('django.db.models.fields.IntegerField', [], {'default': '22', 'db_index': 'True'}), + 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), + 'organisation_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'db_index': 'True'}), + 'partner_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['rsr.PartnerType']", 'symmetrical': 'False'}), + 'phone': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'blank': 'True'}), + 'primary_location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.OrganisationLocation']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'rsr.organisationaccount': { + 'Meta': {'object_name': 'OrganisationAccount'}, + 'account_level': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'archived'", 'max_length': '12'}), + 'organisation': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Organisation']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'rsr.organisationlocation': { + 'Meta': {'ordering': "['id']", 'object_name': 'OrganisationLocation'}, + 'address_1': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'address_2': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'city': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'latitude': ('akvo.rsr.fields.LatitudeField', [], {'default': '0', 'db_index': 'True'}), + 'location_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'locations'", 'null': 'True', 'to': "orm['rsr.Organisation']"}), + 'longitude': ('akvo.rsr.fields.LongitudeField', [], {'default': '0', 'db_index': 'True'}), + 'postcode': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10', 'blank': 'True'}), + 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'rsr.partnership': { + 'Meta': {'ordering': "['partner_type']", 'object_name': 'Partnership'}, + 'funding_amount': ('django.db.models.fields.DecimalField', [], {'db_index': 'True', 'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'iati_activity_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'iati_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'organisation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'partnerships'", 'to': "orm['rsr.Organisation']"}), + 'partner_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '8', 'db_index': 'True'}), + 'partner_type_extra': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'partnerships'", 'to': "orm['rsr.Project']"}), + 'related_activity_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) + }, + 'rsr.partnersite': { + 'Meta': {'ordering': "('organisation__name',)", 'object_name': 'PartnerSite'}, + 'about_box': ('akvo.rsr.fields.ValidXMLTextField', [], {'max_length': '500', 'blank': 'True'}), + 'about_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'cname': ('akvo.rsr.fields.NullCharField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'custom_css': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'custom_favicon': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'custom_logo': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'custom_return_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'custom_return_url_text': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'default_language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '5'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'exclude_keywords': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'facebook_app_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'facebook_button': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'google_translation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'hostname': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '50'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'keywords': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'partnersites'", 'blank': 'True', 'to': "orm['rsr.Keyword']"}), + 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), + 'organisation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Organisation']"}), + 'partner_projects': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'piwik_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'twitter_button': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ui_translation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'rsr.partnertype': { + 'Meta': {'ordering': "('label',)", 'object_name': 'PartnerType'}, + 'id': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '8', 'primary_key': 'True'}), + 'label': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'rsr.paymentgatewayselector': { + 'Meta': {'object_name': 'PaymentGatewaySelector'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mollie_gateway': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['rsr.MollieGateway']"}), + 'paypal_gateway': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['rsr.PayPalGateway']"}), + 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True'}) + }, + 'rsr.paypalgateway': { + 'Meta': {'object_name': 'PayPalGateway'}, + 'account_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'EUR'", 'max_length': '3'}), + 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'locale': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'US'", 'max_length': '2'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255'}), + 'notification_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}) + }, + 'rsr.planneddisbursement': { + 'Meta': {'object_name': 'PlannedDisbursement'}, + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'period_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'period_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'planned_disbursements'", 'to': "orm['rsr.Project']"}), + 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'value': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), + 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'rsr.policymarker': { + 'Meta': {'object_name': 'PolicyMarker'}, + 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'policy_marker': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'policy_markers'", 'to': "orm['rsr.Project']"}), + 'significance': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}) + }, + 'rsr.project': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Project'}, + 'background': ('akvo.rsr.fields.ProjectLimitedTextField', [], {'blank': 'True'}), + 'budget': ('django.db.models.fields.DecimalField', [], {'decimal_places': '2', 'default': '0', 'max_digits': '10', 'blank': 'True', 'null': 'True', 'db_index': 'True'}), + 'capital_spend_percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'projects'", 'blank': 'True', 'to': "orm['rsr.Category']"}), + 'collaboration_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'conditions_attached': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'country_budget_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'EUR'", 'max_length': '3'}), + 'current_image': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'current_image_caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'current_image_credit': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'current_status': ('akvo.rsr.fields.ProjectLimitedTextField', [], {'blank': 'True'}), + 'date_end_actual': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'date_end_planned': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'date_start_actual': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'date_start_planned': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'default_aid_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'default_finance_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'default_flow_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'default_tied_status': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'donate_button': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'funds': ('django.db.models.fields.DecimalField', [], {'decimal_places': '2', 'default': '0', 'max_digits': '10', 'blank': 'True', 'null': 'True', 'db_index': 'True'}), + 'funds_needed': ('django.db.models.fields.DecimalField', [], {'decimal_places': '2', 'default': '0', 'max_digits': '10', 'blank': 'True', 'null': 'True', 'db_index': 'True'}), + 'goals_overview': ('akvo.rsr.fields.ProjectLimitedTextField', [], {}), + 'hierarchy': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'iati_activity_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'keywords': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'projects'", 'blank': 'True', 'to': "orm['rsr.Keyword']"}), + 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '2'}), + 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'last_update': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'the_project'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.ProjectUpdate']"}), + 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), + 'partners': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'projects'", 'symmetrical': 'False', 'through': "orm['rsr.Partnership']", 'to': "orm['rsr.Organisation']"}), + 'primary_location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.ProjectLocation']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'project_plan': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), + 'project_plan_summary': ('akvo.rsr.fields.ProjectLimitedTextField', [], {}), + 'project_rating': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'project_scope': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'status': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'N'", 'max_length': '1', 'db_index': 'True'}), + 'subtitle': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75'}), + 'sustainability': ('akvo.rsr.fields.ValidXMLTextField', [], {}), + 'sync_owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Organisation']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'sync_owner_secondary_reporter': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'target_group': ('akvo.rsr.fields.ProjectLimitedTextField', [], {'blank': 'True'}), + 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '45', 'db_index': 'True'}) + }, + 'rsr.projectcomment': { + 'Meta': {'ordering': "('-id',)", 'object_name': 'ProjectComment'}, + 'comment': ('akvo.rsr.fields.ValidXMLTextField', [], {}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['rsr.Project']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.User']"}) + }, + 'rsr.projectcondition': { + 'Meta': {'object_name': 'ProjectCondition'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'conditions'", 'to': "orm['rsr.Project']"}), + 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}) + }, + 'rsr.projectcontact': { + 'Meta': {'object_name': 'ProjectContact'}, + 'country': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'contacts'", 'null': 'True', 'to': "orm['rsr.Country']"}), + 'department': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'job_title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'mailing_address': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'organisation': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'person_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'to': "orm['rsr.Project']"}), + 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'telephone': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), + 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'rsr.projectdocument': { + 'Meta': {'ordering': "['-id']", 'object_name': 'ProjectDocument'}, + 'category': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'format': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'to': "orm['rsr.Project']"}), + 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'title_language': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'rsr.projectlocation': { + 'Meta': {'ordering': "['id']", 'object_name': 'ProjectLocation'}, + 'activity_description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'address_1': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'address_2': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'administrative_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), + 'administrative_level': ('django.db.models.fields.PositiveSmallIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'administrative_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'city': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']"}), + 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'exactness': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'feature_designation': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'latitude': ('akvo.rsr.fields.LatitudeField', [], {'default': '0', 'db_index': 'True'}), + 'location_class': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'location_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), + 'location_reach': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'location_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'locations'", 'null': 'True', 'to': "orm['rsr.Project']"}), + 'longitude': ('akvo.rsr.fields.LongitudeField', [], {'default': '0', 'db_index': 'True'}), + 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'postcode': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10', 'blank': 'True'}), + 'reference': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}) + }, + 'rsr.projectupdate': { + 'Meta': {'ordering': "['-id']", 'object_name': 'ProjectUpdate'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '2'}), + 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), + 'photo': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'photo_caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), + 'photo_credit': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), + 'primary_location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.ProjectUpdateLocation']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'project_updates'", 'to': "orm['rsr.Project']"}), + 'text': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), + 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'db_index': 'True'}), + 'update_method': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'W'", 'max_length': '1', 'db_index': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.User']"}), + 'user_agent': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "''", 'max_length': '200', 'blank': 'True'}), + 'uuid': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "''", 'max_length': '40', 'db_index': 'True', 'blank': 'True'}), + 'video': ('embed_video.fields.EmbedVideoField', [], {'max_length': '200', 'blank': 'True'}), + 'video_caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), + 'video_credit': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}) + }, + 'rsr.projectupdatelocation': { + 'Meta': {'ordering': "['id']", 'object_name': 'ProjectUpdateLocation'}, + 'address_1': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'address_2': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'city': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'latitude': ('akvo.rsr.fields.LatitudeField', [], {'default': '0', 'db_index': 'True'}), + 'location_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'locations'", 'null': 'True', 'to': "orm['rsr.ProjectUpdate']"}), + 'longitude': ('akvo.rsr.fields.LongitudeField', [], {'default': '0', 'db_index': 'True'}), + 'postcode': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10', 'blank': 'True'}), + 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'rsr.publishingstatus': { + 'Meta': {'ordering': "('-status', 'project')", 'object_name': 'PublishingStatus'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True'}), + 'status': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'unpublished'", 'max_length': '30', 'db_index': 'True'}) + }, + 'rsr.recipientcountry': { + 'Meta': {'object_name': 'RecipientCountry'}, + 'country': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipient_countries'", 'to': "orm['rsr.Project']"}), + 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) + }, + 'rsr.recipientregion': { + 'Meta': {'object_name': 'RecipientRegion'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipient_regions'", 'to': "orm['rsr.Project']"}), + 'region': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'region_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) + }, + 'rsr.relatedproject': { + 'Meta': {'ordering': "['project']", 'object_name': 'RelatedProject'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'related_projects'", 'to': "orm['rsr.Project']"}), + 'related_iati_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'related_project': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'related_to_projects'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.Project']"}), + 'relation': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}) + }, + 'rsr.result': { + 'Meta': {'object_name': 'Result'}, + 'aggregation_status': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'results'", 'to': "orm['rsr.Project']"}), + 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}) + }, + 'rsr.sector': { + 'Meta': {'object_name': 'Sector'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectors'", 'to': "orm['rsr.Project']"}), + 'sector_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}), + 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), + 'vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}) + }, + 'rsr.transaction': { + 'Meta': {'object_name': 'Transaction'}, + 'aid_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), + 'disbursement_channel': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'finance_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'flow_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transactions'", 'to': "orm['rsr.Project']"}), + 'provider_organisation': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'providing_transactions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.Organisation']"}), + 'provider_organisation_activity': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'receiver_organisation': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'receiving_transactions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.Organisation']"}), + 'receiver_organisation_activity': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'recipient_country': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'recipient_region': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'recipient_region_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'reference': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), + 'sector': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}), + 'sector_category': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), + 'sector_other': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), + 'tied_status': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), + 'transaction_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'transaction_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), + 'value': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '11', 'decimal_places': '2', 'blank': 'True'}), + 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'rsr.user': { + 'Meta': {'ordering': "['username']", 'object_name': 'User'}, + 'avatar': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'null': 'True'}), + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '254'}), + 'first_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_support': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), + 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), + 'organisations': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'users'", 'blank': 'True', 'through': "orm['rsr.Employment']", 'to': "orm['rsr.Organisation']"}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '254'}) + } + } + + complete_apps = ['rsr'] \ No newline at end of file diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py index c2e2b216d4..7dda238cdf 100644 --- a/akvo/rsr/models/__init__.py +++ b/akvo/rsr/models/__init__.py @@ -23,9 +23,11 @@ from .benchmark import Benchmark, Benchmarkname from .budget_item import BudgetItem, BudgetItemLabel, CountryBudgetItem from .country import Country, RecipientCountry +from .crs_add import CrsAdd, CrsAddOtherFlag from .category import Category from .employment import Employment from .focus_area import FocusArea +from .fss import Fss, FssForecast from .goal import Goal from .indicator import Indicator, IndicatorPeriod from .invoice import Invoice @@ -65,8 +67,12 @@ 'Country', 'RecipientCountry', 'Category', + 'CrsAdd', + 'CrsAddOtherFlag', 'Employment', 'FocusArea', + 'Fss', + 'FssForecast', 'Goal', 'Indicator', 'IndicatorPeriod', diff --git a/akvo/rsr/models/budget_item.py b/akvo/rsr/models/budget_item.py index 8a719ad3cb..63e9692f19 100644 --- a/akvo/rsr/models/budget_item.py +++ b/akvo/rsr/models/budget_item.py @@ -90,8 +90,6 @@ class CountryBudgetItem(models.Model): description = ValidXMLCharField( _(u'description'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') ) - vocabulary = ValidXMLCharField(_(u'country budget vocabulary'), blank=True, max_length=1, - choices=codelist_choices(BudgetIdentifierVocabulary)) percentage = models.DecimalField( _(u'percentage'), blank=True, null=True, max_digits=4, decimal_places=1, validators=[MaxValueValidator(100), MinValueValidator(0)] diff --git a/akvo/rsr/models/crs_add.py b/akvo/rsr/models/crs_add.py new file mode 100644 index 0000000000..811fbb34a2 --- /dev/null +++ b/akvo/rsr/models/crs_add.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + + +from django.core.validators import MaxValueValidator, MinValueValidator +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from ..fields import ValidXMLCharField + +from akvo.codelists.models import CRSAddOtherFlags, LoanRepaymentType, LoanRepaymentPeriod, Currency +from akvo.utils import codelist_choices, codelist_value + + +class CrsAdd(models.Model): + """ + Items specific to CRS++ reporting. Can only occur once per project. + """ + project = models.OneToOneField('Project', primary_key=True) + loan_terms_rate1 = models.DecimalField( + _(u'rate 1'), blank=True, null=True, max_digits=5, decimal_places=2, + validators=[MaxValueValidator(100), MinValueValidator(0)] + ) + loan_terms_rate2 = models.DecimalField( + _(u'rate 2'), blank=True, null=True, max_digits=5, decimal_places=2, + validators=[MaxValueValidator(100), MinValueValidator(0)] + ) + repayment_type = ValidXMLCharField(_(u'repayment type'), max_length=1, choices=codelist_choices(LoanRepaymentType)) + repayment_plan = ValidXMLCharField( + _(u'repayment plan'), max_length=2, choices=codelist_choices(LoanRepaymentPeriod) + ) + commitment_date = models.DateField(_(u'commitment date'), null=True, blank=True) + repayment_first_date = models.DateField(_(u'first repayment date'), null=True, blank=True) + repayment_final_date = models.DateField(_(u'final repayment date'), null=True, blank=True) + loan_status_year = models.PositiveIntegerField(_(u'loan status year'), blank=True, null=True, max_length=4) + loan_status_currency = ValidXMLCharField( + _(u'currency'), blank=True, max_length=3, choices=codelist_choices(Currency) + ) + loan_status_value_date = models.DateField(_(u'loan status value date'), blank=True, null=True) + interest_received = models.DecimalField( + _(u'interest received'), max_digits=10, decimal_places=2, blank=True, null=True + ) + principal_outstanding = models.DecimalField( + _(u'principal outstanding'), max_digits=10, decimal_places=2, blank=True, null=True + ) + principal_arrears = models.DecimalField( + _(u'principal arrears'), max_digits=10, decimal_places=2, blank=True, null=True + ) + interest_arrears = models.DecimalField( + _(u'interest arrears'), max_digits=10, decimal_places=2, blank=True, null=True + ) + + def iati_repayment_type(self): + return codelist_value(LoanRepaymentType, self, 'repayment_type') + + def iati_repayment_plan(self): + return codelist_value(LoanRepaymentPeriod, self, 'repayment_plan') + + def iati_currency(self): + return codelist_value(Currency, self, 'loan_status_currency') + + class Meta: + app_label = 'rsr' + verbose_name = _(u'CRS reporting') + verbose_name_plural = _(u'CRS reporting') + + +class CrsAddOtherFlag(models.Model): + """ + Other flag of CRS++ reporting. + """ + crs = models.ForeignKey('CrsAdd', verbose_name=u'crs', related_name='other_flags') + code = ValidXMLCharField(_(u'code'), max_length=1, choices=codelist_choices(CRSAddOtherFlags)) + significance = models.NullBooleanField(_(u'significance'), blank=True) + + def iati_code(self): + return codelist_value(CRSAddOtherFlags, self, 'code') + + class Meta: + app_label = 'rsr' + verbose_name = _(u'CRS other flag') + verbose_name_plural = _(u'CRS other flags') diff --git a/akvo/rsr/models/fss.py b/akvo/rsr/models/fss.py new file mode 100644 index 0000000000..e9c3a7f9a8 --- /dev/null +++ b/akvo/rsr/models/fss.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + + +from django.core.validators import MaxValueValidator, MinValueValidator +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from ..fields import ValidXMLCharField + +from akvo.codelists.models import Currency +from akvo.utils import codelist_choices, codelist_value + + +class Fss(models.Model): + """ + Items specific to OECD DAC Forward Spending Survey. Can only occur once per project. + """ + project = models.OneToOneField('Project', primary_key=True) + extraction_date = models.DateField(_(u'extraction date'), null=True, blank=True) + priority = models.NullBooleanField(_(u'priority'), blank=True) + phaseout_year = models.PositiveIntegerField(_(u'phaseout year'), blank=True, null=True, max_length=4) + + class Meta: + app_label = 'rsr' + verbose_name = _(u'FSS') + verbose_name_plural = _(u'FSS') + + +class FssForecast(models.Model): + """ + Forecast items for an OECD DAC Forward Spending Survey item. + """ + fss = models.ForeignKey('Fss', verbose_name=u'fss', related_name='forecasts') + year = models.PositiveIntegerField(_(u'year'), blank=True, null=True, max_length=4) + value_date = models.DateField(_(u'value date'), blank=True, null=True) + currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, choices=codelist_choices(Currency)) + value = models.DecimalField(_(u'interest received'), max_digits=10, decimal_places=2, blank=True, null=True) + + def iati_currency(self): + return codelist_value(Currency, self, 'loan_status_currency') + + class Meta: + app_label = 'rsr' + verbose_name = _(u'FSS forecast') + verbose_name_plural = _(u'FSS forecasts') diff --git a/akvo/rsr/models/indicator.py b/akvo/rsr/models/indicator.py index 378f2f713c..d4e8a62647 100644 --- a/akvo/rsr/models/indicator.py +++ b/akvo/rsr/models/indicator.py @@ -30,9 +30,6 @@ class Indicator(models.Model): _(u'description'), blank=True, max_length=255, help_text=_(u'You can further define the indicator here. (255 characters)') ) - description_type = ValidXMLCharField( - _(u'description type'), blank=True, max_length=1, choices=codelist_choices(DescriptionType) - ) baseline_year = models.PositiveIntegerField( _(u'baseline year'), blank=True, null=True, max_length=4, help_text=_(u'Enter the year that the baseline information was obtained.') diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py index 1e7ad93e59..2be4ef65ed 100644 --- a/akvo/rsr/models/project.py +++ b/akvo/rsr/models/project.py @@ -7,8 +7,6 @@ import math -from datetime import date - from django.conf import settings from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -23,7 +21,8 @@ from sorl.thumbnail.fields import ImageField -from akvo.codelists.models import AidType, ActivityScope, CollaborationType, FinanceType, FlowType, TiedStatus +from akvo.codelists.models import (AidType, ActivityScope, CollaborationType, FinanceType, FlowType, TiedStatus, + BudgetIdentifierVocabulary) from akvo.utils import codelist_choices, codelist_value, rsr_image_path, rsr_show_keywords from ..fields import ProjectLimitedTextField, ValidXMLCharField, ValidXMLTextField @@ -242,6 +241,9 @@ def image_path(instance, file_name): choices=codelist_choices(FlowType)) default_tied_status = ValidXMLCharField(_(u'default tied status'), blank=True, max_length=1, choices=codelist_choices(TiedStatus)) + conditions_attached = models.NullBooleanField(_(u'attached conditions'), blank=True) + country_budget_vocabulary = ValidXMLCharField(_(u'country budget vocabulary'), blank=True, max_length=1, + choices=codelist_choices(BudgetIdentifierVocabulary)) # denormalized data @@ -777,13 +779,13 @@ def has_relations(self): return self.parents() or self.children() or self.siblings() def parents(self): - return (Project.objects.filter(related_projects__related_project=self, related_projects__relation=1) | - Project.objects.filter(related_to_projects__project=self, related_to_projects__relation=2)).distinct() - - def children(self): return (Project.objects.filter(related_projects__related_project=self, related_projects__relation=2) | Project.objects.filter(related_to_projects__project=self, related_to_projects__relation=1)).distinct() + def children(self): + return (Project.objects.filter(related_projects__related_project=self, related_projects__relation=1) | + Project.objects.filter(related_to_projects__project=self, related_to_projects__relation=2)).distinct() + def siblings(self): return (Project.objects.filter(related_projects__related_project=self, related_projects__relation=3) | Project.objects.filter(related_to_projects__project=self, related_to_projects__relation=3)).distinct() diff --git a/akvo/rsr/models/project_condition.py b/akvo/rsr/models/project_condition.py index 453c12988c..53939ffc1d 100644 --- a/akvo/rsr/models/project_condition.py +++ b/akvo/rsr/models/project_condition.py @@ -18,7 +18,6 @@ class ProjectCondition(models.Model): project = models.ForeignKey('Project', verbose_name=u'project', related_name='conditions') text = ValidXMLCharField(_(u'condition'), blank=True, max_length=100, help_text=_(u'(100 characters)')) type = ValidXMLCharField(_(u'condition type'), blank=True, max_length=1, choices=codelist_choices(ConditionType)) - attached = models.NullBooleanField(_(u'attached'), blank=True) def iati_type(self): return codelist_value(ConditionType, self, 'type') diff --git a/akvo/rsr/models/related_project.py b/akvo/rsr/models/related_project.py index f4d1306ec6..89f9e4d6e9 100644 --- a/akvo/rsr/models/related_project.py +++ b/akvo/rsr/models/related_project.py @@ -15,11 +15,18 @@ class RelatedProject(models.Model): project = models.ForeignKey('Project', related_name='related_projects') - related_project = models.ForeignKey('Project', related_name='related_to_projects') + related_project = models.ForeignKey( + 'Project', related_name='related_to_projects', null=True, blank=True, on_delete=models.SET_NULL + ) + related_iati_id = ValidXMLCharField( + _(u'related project IATI identifier'), max_length=100, blank=True, + help_text=_(u'The IATI Identifier for the related project.
' + u'Fill this in if the related project does not exist in RSR') + ) relation = ValidXMLCharField( _(u'relation'), max_length=1, choices=codelist_choices(RelatedActivityType), help_text=_(u'The relation between a project and related project. ' - u'(E.g. select the \'Parent\' relation when the project is a parent of the related project).') + u'(E.g. select the \'Parent\' relation when the selected project here is the parent of this project).') ) def iati_relation(self): diff --git a/akvo/rsr/models/result.py b/akvo/rsr/models/result.py index a6de3c1f02..bdd60daed4 100644 --- a/akvo/rsr/models/result.py +++ b/akvo/rsr/models/result.py @@ -31,9 +31,6 @@ class Result(models.Model): _(u'description'), blank=True, max_length=255, help_text=_(u'You can provide further information of the result here. (255 characters)') ) - description_type = ValidXMLCharField( - _(u'description type'), blank=True, max_length=1, choices=codelist_choices(DescriptionType) - ) def __unicode__(self): return self.title diff --git a/akvo/rsr/models/transaction.py b/akvo/rsr/models/transaction.py index 220a6266ed..f5d2a8a551 100644 --- a/akvo/rsr/models/transaction.py +++ b/akvo/rsr/models/transaction.py @@ -11,7 +11,7 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import (AidType, Currency, DisbursementChannel, FinanceType, FlowType, TiedStatus, - TransactionType) + TransactionType, Country, Region, RegionVocabulary, Sector, SectorCategory) from akvo.utils import codelist_choices, codelist_value @@ -24,9 +24,6 @@ class Transaction(models.Model): aid_type = ValidXMLCharField( _(u'aid type'), blank=True, max_length=3, choices=codelist_choices(AidType) ) - aid_type_text = ValidXMLCharField( - _(u'aid type text'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') - ) description = ValidXMLCharField( _(u'description'), max_length=255, blank=True, help_text=_(u'Enter a description for the transaction. (255 characters)') @@ -34,23 +31,11 @@ class Transaction(models.Model): disbursement_channel = ValidXMLCharField( _(u'disbursement channel'), blank=True, max_length=1, choices=codelist_choices(DisbursementChannel) ) - disbursement_channel_text = ValidXMLCharField( - _(u'disbursement channel text'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') - ) finance_type = ValidXMLCharField( _(u'finance type'), max_length=3, blank=True, choices=codelist_choices(FinanceType) ) - finance_type_text = ValidXMLCharField( - _(u'finance type text'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') - ) flow_type = ValidXMLCharField(_(u'flow type'), max_length=2, blank=True, choices=codelist_choices(FlowType)) - flow_type_text = ValidXMLCharField( - _(u'flow type text'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') - ) tied_status = ValidXMLCharField(_(u'tied status'), blank=True, max_length=1, choices=codelist_choices(TiedStatus)) - tied_status_text = ValidXMLCharField( - _(u'tied status text'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') - ) transaction_date = models.DateField( _(u'transaction date'), blank=True, null=True, help_text=u'Enter the financial reporting date that the transaction was/will be undertaken.' @@ -59,9 +44,6 @@ class Transaction(models.Model): _(u'transaction type'), blank=True, max_length=2, choices=codelist_choices(TransactionType), help_text=_(u'Select the type of transaction from the list.') ) - transaction_type_text = ValidXMLCharField( - _(u'transaction type text'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') - ) value = models.DecimalField( _(u'value'), blank=True, null=True, max_digits=11, decimal_places=2, help_text=u'Enter the transaction amount.' @@ -82,6 +64,20 @@ class Transaction(models.Model): receiver_organisation_activity = ValidXMLCharField( _(u'receiver organisation activity id'), blank=True, max_length=50 ) + recipient_country = ValidXMLCharField(_(u'recipient country'), blank=True, max_length=2, + choices=codelist_choices(Country)) + recipient_region = ValidXMLCharField( + _(u'recipient region'), blank=True, max_length=3, choices=codelist_choices(Region) + ) + recipient_region_vocabulary = ValidXMLCharField(_(u'recipient region vocabulary'), blank=True, max_length=1, + choices=codelist_choices(RegionVocabulary)) + sector = ValidXMLCharField(_(u'sector'), blank=True, max_length=5, choices=codelist_choices(Sector)) + sector_category = ValidXMLCharField( + _(u'sector category'), blank=True, max_length=3, choices=codelist_choices(SectorCategory) + ) + sector_other = ValidXMLCharField( + _(u'other sector'), blank=True, max_length=50 + ) def __unicode__(self): return self.value @@ -95,6 +91,21 @@ def iati_transaction_type(self): def iati_disbursement_channel(self): return codelist_value(DisbursementChannel, self, 'disbursement_channel') + def iati_recipient_country(self): + return codelist_value(Country, self, 'recipient_country') + + def iati_recipient_region(self): + return codelist_value(Region, self, 'recipient_region') + + def iati_recipient_region_vocabulary(self): + return codelist_value(RegionVocabulary, self, 'recipient_region_vocabulary') + + def iati_sector(self): + return codelist_value(Sector, self, 'sector') + + def iati_sector_category(self): + return codelist_value(SectorCategory, self, 'sector_category') + class Meta: app_label = 'rsr' verbose_name = _(u'transaction') From 1e2891a9b314e8af7829db76b1b4f331b5166f75 Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Mon, 23 Mar 2015 19:55:02 +0100 Subject: [PATCH 02/22] [#1351] Fix baseline comment and add IATI project link --- akvo/iati/elements/result.py | 2 +- akvo/rsr/views/project.py | 15 ++++++++++++++- akvo/urls.py | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/akvo/iati/elements/result.py b/akvo/iati/elements/result.py index 7e3031de76..10ba4d3e17 100644 --- a/akvo/iati/elements/result.py +++ b/akvo/iati/elements/result.py @@ -60,7 +60,7 @@ def result(project): baseline_element.attrib['value'] = indicator.baseline_value if indicator.baseline_comment: - comment_element = etree.SubElement(indicator_element, "comment") + comment_element = etree.SubElement(baseline_element, "comment") narrative_element = etree.SubElement(comment_element, "narrative") narrative_element.text = indicator.baseline_comment diff --git a/akvo/rsr/views/project.py b/akvo/rsr/views/project.py index caa2b7d982..4112eea36d 100644 --- a/akvo/rsr/views/project.py +++ b/akvo/rsr/views/project.py @@ -12,13 +12,15 @@ from sorl.thumbnail import get_thumbnail from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied -from django.http import Http404 +from django.http import Http404, HttpResponse from django.shortcuts import get_object_or_404, redirect, render +from lxml import etree from ..forms import ProjectUpdateForm from ..filters import remove_empty_querydict_items, ProjectFilter from ..models import Invoice, Project, ProjectUpdate from ...utils import pagination, filter_query_string +from ...iati.iati_export import IatiXML from .utils import apply_keywords, org_projects @@ -311,6 +313,17 @@ def report(request, project_id): return render(request, 'project_report.html', context) +############################################################################### +# Project IATI file +############################################################################### + + +def iati(request, project_id): + """Generate the IATI file on-the-fly and return the XML.""" + iati_activities = IatiXML(Project.objects.filter(pk=project_id)).iati_activities + xml_data = etree.tostring(etree.ElementTree(iati_activities)) + return HttpResponse(xml_data, content_type="text/xml") + ############################################################################### # Project widgets diff --git a/akvo/urls.py b/akvo/urls.py index 30dbd2dd10..d0ab43f464 100644 --- a/akvo/urls.py +++ b/akvo/urls.py @@ -43,6 +43,9 @@ url(r'^project/(?P\d+)/report/$', 'akvo.rsr.views.project.report', name='project-report'), + url(r'^project/(?P\d+)/iati/$', + 'akvo.rsr.views.project.iati', name='project-iati'), + url(r'^project/(?P\d+)/widgets/$', 'akvo.rsr.views.project.widgets', name='project-widgets'), From f41c11b82a1956f6f2dff183f7972735e041f7d7 Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Tue, 24 Mar 2015 10:08:37 +0100 Subject: [PATCH 03/22] [#1351] Add attributes on iati-activity element --- akvo/iati/iati_export.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/akvo/iati/iati_export.py b/akvo/iati/iati_export.py index 9c282f962a..e6178132fe 100644 --- a/akvo/iati/iati_export.py +++ b/akvo/iati/iati_export.py @@ -73,6 +73,19 @@ def add_project(self, project): :param project: Project object """ project_element = etree.SubElement(self.iati_activities, "iati-activity") + + if project.last_modified_at: + project_element.attrib['last-updated-datetime'] = project.last_modified_at.strftime("%Y-%m-%dT%H:%M:%SZ") + + if project.language: + project_element.attrib['{http://www.w3.org/XML/1998/namespace}lang'] = project.language + + if project.currency: + project_element.attrib['default-currency'] = project.currency + + if project.hierarchy: + project_element.attrib['hierarchy'] = str(project.hierarchy) + for element in ELEMENTS: tree_elements = getattr(elements, element)(project) for tree_element in tree_elements: From 0ee5a457f47f4eda2f0e9c1bcbb5faa8588d0828 Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Fri, 27 Mar 2015 11:44:29 +0100 Subject: [PATCH 04/22] [#809] First stab at restarting tests - Removed old tests - Added new testrunner to settings - Made rsr postgres user able to create the test database - Added simple test (but only "/" is working at the moment) --- akvo/rsr/tests.py | 66 +++++ akvo/rsr/tests/__init__.py | 14 - akvo/rsr/tests/partner_sites.py | 82 ------ akvo/settings/20-default.conf | 2 + pg_tests.py | 8 +- tests/__init__.py | 1 - tests/akvo/acceptance/all_test_suites.py | 31 --- tests/akvo/acceptance/api/__init__.py | 5 - tests/akvo/acceptance/api/xml/__init__.py | 5 - .../api/xml/all_le_sponsored_projects_test.py | 49 ---- ..._project_updates_for_given_project_test.py | 49 ---- .../acceptance/api/xml/all_projects_test.py | 49 ---- .../acceptance/api/xml/expectedelements.py | 19 -- .../acceptance/api/xml/single_project_test.py | 46 ---- .../api/xml/single_project_update_test.py | 73 ----- .../acceptance/api/xml/xml_api_test_suite.py | 31 --- tests/akvo/acceptance/extensions/__init__.py | 5 - .../acceptance/extensions/xmlextensions.py | 9 - tests/akvo/acceptance/helpers/__init__.py | 5 - tests/akvo/acceptance/helpers/akvopaths.py | 114 -------- tests/akvo/acceptance/helpers/akvourls.py | 29 -- .../acceptance/helpers/constraintmatchers.py | 35 --- .../akvo/acceptance/helpers/elementparsing.py | 28 -- tests/akvo/acceptance/helpers/externalurls.py | 12 - tests/akvo/acceptance/helpers/navigation.py | 97 ------- tests/akvo/acceptance/helpers/rsrapi.py | 14 - tests/akvo/acceptance/helpers/rsrpath.py | 33 --- .../akvo/acceptance/helpers/seleniumclient.py | 36 --- .../akvo/acceptance/helpers/testexecution.py | 26 -- .../acceptance/helpers/unittests/__init__.py | 5 - .../helpers/unittests/akvopaths_test.py | 163 ------------ .../helpers/unittests/akvourls_test.py | 59 ----- .../helpers/unittests/externalurls_test.py | 35 --- .../helpers/unittests/helpers_test_suite.py | 19 -- .../helpers/unittests/rsrpath_test.py | 56 ---- tests/akvo/acceptance/images/kagiso_map.jpg | Bin 26876 -> 0 bytes .../images/project_photo_spring.jpg | Bin 42127 -> 0 bytes tests/akvo/acceptance/internal/__init__.py | 5 - .../internal/internal_unittests_suite.py | 16 -- .../akvo/acceptance/rsr_project_admin_test.py | 249 ------------------ tests/akvo/acceptance/rsr_user_admin_test.py | 104 -------- .../acceptance/rsr_user_registration_test.py | 78 ------ .../akvo/acceptance/test_settings.py.template | 27 -- tests/akvo/acceptance/test_settings_ci.py | 27 -- tests/akvo/acceptance/testcases/__init__.py | 5 - .../testcases/elementparsingtestcase.py | 69 ----- .../acceptance/testcases/seleniumtestcase.py | 104 -------- .../akvo/acceptance/testcases/webtestcase.py | 55 ---- .../akvo/acceptance/testcases/xmltestcase.py | 65 ----- tests/akvo/acceptance/verifiers/__init__.py | 5 - .../verifiers/baseelementparsingverifier.py | 20 -- .../acceptance/verifiers/viewcountrecorder.py | 42 --- .../acceptance/verifiers/viewcountverifier.py | 77 ------ tests/akvo/acceptance/web/__init__.py | 5 - tests/akvo/acceptance/web/general/__init__.py | 5 - .../web/general/general_test_suite.py | 18 -- .../web/general/site_components_smoke_test.py | 75 ------ tests/akvo/acceptance/web/home/__init__.py | 5 - .../acceptance/web/home/footer_links_test.py | 88 ------- .../acceptance/web/home/home_page_test.py | 55 ---- .../web/home/home_page_test_suite.py | 18 -- .../acceptance/web/navigation/__init__.py | 5 - .../web/navigation/menu_navigation_test.py | 70 ----- .../web/navigation/menunavigationverifier.py | 30 --- .../web/navigation/navigation_test_suite.py | 16 -- .../akvo/acceptance/web/projects/__init__.py | 5 - .../projects/project_view_counters_test.py | 63 ----- .../web/projects/projects_test_suite.py | 16 -- tests/akvo/acceptance/web/web_test_suite.py | 22 -- tests/akvo/acceptance/web/widgets/__init__.py | 5 - .../web/widgets/widget_view_counters_test.py | 89 ------- .../web/widgets/widgets_test_suite.py | 16 -- tests/pvw/acceptance/all_test_suites.py | 32 --- tests/pvw/acceptance/extensions/__init__.py | 5 - tests/pvw/acceptance/helpers/__init__.py | 5 - tests/pvw/acceptance/helpers/dwspaths.py | 63 ----- tests/pvw/acceptance/helpers/dwsurls.py | 38 --- .../pvw/acceptance/helpers/elementparsing.py | 28 -- tests/pvw/acceptance/helpers/gmailreader.py | 31 --- tests/pvw/acceptance/helpers/navigation.py | 101 ------- .../pvw/acceptance/helpers/seleniumclient.py | 36 --- tests/pvw/acceptance/helpers/testexecution.py | 26 -- .../acceptance/helpers/unittests/__init__.py | 5 - .../helpers/unittests/dwspaths_test.py | 113 -------- .../helpers/unittests/dwsurls_test.py | 72 ----- .../helpers/unittests/helpers_test_suite.py | 17 -- tests/pvw/acceptance/internal/__init__.py | 5 - .../internal/internal_unittests_suite.py | 16 -- .../pvw/acceptance/test_settings.py.template | 30 --- tests/pvw/acceptance/test_settings_ci.py | 30 --- tests/pvw/acceptance/testcases/__init__.py | 5 - .../acceptance/testcases/seleniumtestcase.py | 104 -------- tests/pvw/acceptance/testcases/webtestcase.py | 56 ---- tests/pvw/acceptance/users/__init__.py | 5 - .../users/organisation_selection_test.py | 56 ---- tests/pvw/acceptance/users/rsruser.py | 18 -- .../users/sign_in_or_register_test.py | 55 ---- .../acceptance/users/user_admin_test_suite.py | 29 -- .../users/user_details_entry_test.py | 85 ------ .../users/user_registration_test.py | 140 ---------- .../pvw/acceptance/users/useradmintestcase.py | 73 ----- tests/pvw/acceptance/verifiers/__init__.py | 5 - .../verifiers/baseelementparsingverifier.py | 20 -- .../verifiers/sharedpagecontentverifier.py | 25 -- tests/pvw/acceptance/web/__init__.py | 5 - tests/pvw/acceptance/web/content/__init__.py | 5 - .../web/content/about_page_content_test.py | 64 ----- .../content/directory_page_content_test.py | 58 ---- .../content/education_page_content_test.py | 59 ----- .../content/focus_areas_page_content_test.py | 81 ------ .../web/content/home_page_content_test.py | 75 ------ .../content/netherlands_page_content_test.py | 54 ---- .../web/content/news_page_content_test.py | 54 ---- .../web/content/page_content_test_suite.py | 27 -- .../web/content/projects_page_content_test.py | 50 ---- tests/pvw/acceptance/web/general/__init__.py | 5 - .../web/general/general_test_suite.py | 16 -- .../web/general/site_components_smoke_test.py | 78 ------ .../pvw/acceptance/web/navigation/__init__.py | 5 - .../web/navigation/footer_navigation_test.py | 83 ------ .../navigation/footernavigationverifier.py | 29 -- .../web/navigation/menu_navigation_test.py | 73 ----- .../web/navigation/menunavigationverifier.py | 29 -- .../web/navigation/navigation_test_suite.py | 17 -- tests/pvw/acceptance/web/web_test_suite.py | 20 -- tests/shared/testing/__init__.py | 5 - tests/shared/testing/helpers/__init__.py | 5 - tests/shared/testing/helpers/execution.py | 40 --- tests/unit/__init__.py | 0 .../middleware/partner_sites_lookup_test.py | 95 ------- tests/unit/test_settings.py | 1 - vagrant/Vagrantfile | 2 +- .../{load_test_db.sh => prepare_test_db.sh} | 3 + 133 files changed, 78 insertions(+), 5153 deletions(-) create mode 100644 akvo/rsr/tests.py delete mode 100644 akvo/rsr/tests/__init__.py delete mode 100644 akvo/rsr/tests/partner_sites.py delete mode 100644 tests/__init__.py delete mode 100755 tests/akvo/acceptance/all_test_suites.py delete mode 100644 tests/akvo/acceptance/api/__init__.py delete mode 100644 tests/akvo/acceptance/api/xml/__init__.py delete mode 100644 tests/akvo/acceptance/api/xml/all_le_sponsored_projects_test.py delete mode 100644 tests/akvo/acceptance/api/xml/all_project_updates_for_given_project_test.py delete mode 100644 tests/akvo/acceptance/api/xml/all_projects_test.py delete mode 100644 tests/akvo/acceptance/api/xml/expectedelements.py delete mode 100644 tests/akvo/acceptance/api/xml/single_project_test.py delete mode 100644 tests/akvo/acceptance/api/xml/single_project_update_test.py delete mode 100644 tests/akvo/acceptance/api/xml/xml_api_test_suite.py delete mode 100644 tests/akvo/acceptance/extensions/__init__.py delete mode 100644 tests/akvo/acceptance/extensions/xmlextensions.py delete mode 100644 tests/akvo/acceptance/helpers/__init__.py delete mode 100644 tests/akvo/acceptance/helpers/akvopaths.py delete mode 100644 tests/akvo/acceptance/helpers/akvourls.py delete mode 100644 tests/akvo/acceptance/helpers/constraintmatchers.py delete mode 100644 tests/akvo/acceptance/helpers/elementparsing.py delete mode 100644 tests/akvo/acceptance/helpers/externalurls.py delete mode 100644 tests/akvo/acceptance/helpers/navigation.py delete mode 100644 tests/akvo/acceptance/helpers/rsrapi.py delete mode 100644 tests/akvo/acceptance/helpers/rsrpath.py delete mode 100644 tests/akvo/acceptance/helpers/seleniumclient.py delete mode 100644 tests/akvo/acceptance/helpers/testexecution.py delete mode 100644 tests/akvo/acceptance/helpers/unittests/__init__.py delete mode 100644 tests/akvo/acceptance/helpers/unittests/akvopaths_test.py delete mode 100644 tests/akvo/acceptance/helpers/unittests/akvourls_test.py delete mode 100644 tests/akvo/acceptance/helpers/unittests/externalurls_test.py delete mode 100644 tests/akvo/acceptance/helpers/unittests/helpers_test_suite.py delete mode 100644 tests/akvo/acceptance/helpers/unittests/rsrpath_test.py delete mode 100644 tests/akvo/acceptance/images/kagiso_map.jpg delete mode 100644 tests/akvo/acceptance/images/project_photo_spring.jpg delete mode 100644 tests/akvo/acceptance/internal/__init__.py delete mode 100644 tests/akvo/acceptance/internal/internal_unittests_suite.py delete mode 100644 tests/akvo/acceptance/rsr_project_admin_test.py delete mode 100644 tests/akvo/acceptance/rsr_user_admin_test.py delete mode 100644 tests/akvo/acceptance/rsr_user_registration_test.py delete mode 100644 tests/akvo/acceptance/test_settings.py.template delete mode 100644 tests/akvo/acceptance/test_settings_ci.py delete mode 100644 tests/akvo/acceptance/testcases/__init__.py delete mode 100644 tests/akvo/acceptance/testcases/elementparsingtestcase.py delete mode 100644 tests/akvo/acceptance/testcases/seleniumtestcase.py delete mode 100644 tests/akvo/acceptance/testcases/webtestcase.py delete mode 100644 tests/akvo/acceptance/testcases/xmltestcase.py delete mode 100644 tests/akvo/acceptance/verifiers/__init__.py delete mode 100644 tests/akvo/acceptance/verifiers/baseelementparsingverifier.py delete mode 100644 tests/akvo/acceptance/verifiers/viewcountrecorder.py delete mode 100644 tests/akvo/acceptance/verifiers/viewcountverifier.py delete mode 100644 tests/akvo/acceptance/web/__init__.py delete mode 100644 tests/akvo/acceptance/web/general/__init__.py delete mode 100644 tests/akvo/acceptance/web/general/general_test_suite.py delete mode 100644 tests/akvo/acceptance/web/general/site_components_smoke_test.py delete mode 100644 tests/akvo/acceptance/web/home/__init__.py delete mode 100644 tests/akvo/acceptance/web/home/footer_links_test.py delete mode 100644 tests/akvo/acceptance/web/home/home_page_test.py delete mode 100644 tests/akvo/acceptance/web/home/home_page_test_suite.py delete mode 100644 tests/akvo/acceptance/web/navigation/__init__.py delete mode 100644 tests/akvo/acceptance/web/navigation/menu_navigation_test.py delete mode 100644 tests/akvo/acceptance/web/navigation/menunavigationverifier.py delete mode 100644 tests/akvo/acceptance/web/navigation/navigation_test_suite.py delete mode 100644 tests/akvo/acceptance/web/projects/__init__.py delete mode 100644 tests/akvo/acceptance/web/projects/project_view_counters_test.py delete mode 100644 tests/akvo/acceptance/web/projects/projects_test_suite.py delete mode 100644 tests/akvo/acceptance/web/web_test_suite.py delete mode 100644 tests/akvo/acceptance/web/widgets/__init__.py delete mode 100644 tests/akvo/acceptance/web/widgets/widget_view_counters_test.py delete mode 100644 tests/akvo/acceptance/web/widgets/widgets_test_suite.py delete mode 100644 tests/pvw/acceptance/all_test_suites.py delete mode 100644 tests/pvw/acceptance/extensions/__init__.py delete mode 100644 tests/pvw/acceptance/helpers/__init__.py delete mode 100644 tests/pvw/acceptance/helpers/dwspaths.py delete mode 100644 tests/pvw/acceptance/helpers/dwsurls.py delete mode 100644 tests/pvw/acceptance/helpers/elementparsing.py delete mode 100644 tests/pvw/acceptance/helpers/gmailreader.py delete mode 100644 tests/pvw/acceptance/helpers/navigation.py delete mode 100644 tests/pvw/acceptance/helpers/seleniumclient.py delete mode 100644 tests/pvw/acceptance/helpers/testexecution.py delete mode 100644 tests/pvw/acceptance/helpers/unittests/__init__.py delete mode 100644 tests/pvw/acceptance/helpers/unittests/dwspaths_test.py delete mode 100644 tests/pvw/acceptance/helpers/unittests/dwsurls_test.py delete mode 100644 tests/pvw/acceptance/helpers/unittests/helpers_test_suite.py delete mode 100644 tests/pvw/acceptance/internal/__init__.py delete mode 100644 tests/pvw/acceptance/internal/internal_unittests_suite.py delete mode 100644 tests/pvw/acceptance/test_settings.py.template delete mode 100644 tests/pvw/acceptance/test_settings_ci.py delete mode 100644 tests/pvw/acceptance/testcases/__init__.py delete mode 100644 tests/pvw/acceptance/testcases/seleniumtestcase.py delete mode 100644 tests/pvw/acceptance/testcases/webtestcase.py delete mode 100644 tests/pvw/acceptance/users/__init__.py delete mode 100644 tests/pvw/acceptance/users/organisation_selection_test.py delete mode 100644 tests/pvw/acceptance/users/rsruser.py delete mode 100644 tests/pvw/acceptance/users/sign_in_or_register_test.py delete mode 100644 tests/pvw/acceptance/users/user_admin_test_suite.py delete mode 100644 tests/pvw/acceptance/users/user_details_entry_test.py delete mode 100644 tests/pvw/acceptance/users/user_registration_test.py delete mode 100644 tests/pvw/acceptance/users/useradmintestcase.py delete mode 100644 tests/pvw/acceptance/verifiers/__init__.py delete mode 100644 tests/pvw/acceptance/verifiers/baseelementparsingverifier.py delete mode 100644 tests/pvw/acceptance/verifiers/sharedpagecontentverifier.py delete mode 100644 tests/pvw/acceptance/web/__init__.py delete mode 100644 tests/pvw/acceptance/web/content/__init__.py delete mode 100644 tests/pvw/acceptance/web/content/about_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/directory_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/education_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/focus_areas_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/home_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/netherlands_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/news_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/content/page_content_test_suite.py delete mode 100644 tests/pvw/acceptance/web/content/projects_page_content_test.py delete mode 100644 tests/pvw/acceptance/web/general/__init__.py delete mode 100644 tests/pvw/acceptance/web/general/general_test_suite.py delete mode 100644 tests/pvw/acceptance/web/general/site_components_smoke_test.py delete mode 100644 tests/pvw/acceptance/web/navigation/__init__.py delete mode 100644 tests/pvw/acceptance/web/navigation/footer_navigation_test.py delete mode 100644 tests/pvw/acceptance/web/navigation/footernavigationverifier.py delete mode 100644 tests/pvw/acceptance/web/navigation/menu_navigation_test.py delete mode 100644 tests/pvw/acceptance/web/navigation/menunavigationverifier.py delete mode 100644 tests/pvw/acceptance/web/navigation/navigation_test_suite.py delete mode 100644 tests/pvw/acceptance/web/web_test_suite.py delete mode 100644 tests/shared/testing/__init__.py delete mode 100644 tests/shared/testing/helpers/__init__.py delete mode 100644 tests/shared/testing/helpers/execution.py delete mode 100644 tests/unit/__init__.py delete mode 100755 tests/unit/rsr/middleware/partner_sites_lookup_test.py delete mode 100644 tests/unit/test_settings.py rename vagrant/provisioning/{load_test_db.sh => prepare_test_db.sh} (85%) diff --git a/akvo/rsr/tests.py b/akvo/rsr/tests.py new file mode 100644 index 0000000000..2316e53e05 --- /dev/null +++ b/akvo/rsr/tests.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the +Akvo RSR module. For additional details on the GNU license please +see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.contrib.sites.models import Site +from django.test import Client, TestCase +from akvo.rsr.models import Benchmarkname + + +class BenchmarknameTestCase(TestCase): + def setUp(self): + # Create test objects + Benchmarkname.objects.create(name="Benchmarkname1") + Benchmarkname.objects.create(name="Benchmarkname2", order=2) + # Store for later use + self.bn1 = Benchmarkname.objects.get(name="Benchmarkname1") + self.bn2 = Benchmarkname.objects.get(name="Benchmarkname2") + + def test_name(self): + self.assertEqual(self.bn1.name, "Benchmarkname1") + self.assertEqual("{}".format(self.bn2), "Benchmarkname2") + + def test_order(self): + self.assertEqual(self.bn1.order, 0) + self.assertEqual(self.bn2.order, 2) + + +# class notFoundPageTestCase(TestCase): +# def setUp(self): +# site, created = Site.objects.get_or_create(domain="localdev.akvo.org", +# name="localdev") +# with self.settings(SITE_ID=site.id): +# c = Client() +# self.resp = c.get('/does-not-exist') +# +# def test_access(self): +# self.assertEqual(self.resp.status_code, 404) + + +class homePageTestCase(TestCase): + def setUp(self): + site, created = Site.objects.get_or_create(domain="localdev.akvo.org", + name="localdev") + with self.settings(SITE_ID=site.id): + c = Client() + self.resp = c.get('/') + + def test_redirect(self): + self.assertEqual(self.resp.status_code, 302) + + +# class projectsPageTestCase(TestCase): +# def setUp(self): +# site, created = Site.object.get_or_create(domain="localdev.akvo.org", +# name="localdev") +# with self.settings(SITE_ID=site.id): +# c = Client() +# self.resp = c.get('/projects/') +# +# def test_response(self): +# self.assertEqual(self.resp.status_code, 200) diff --git a/akvo/rsr/tests/__init__.py b/akvo/rsr/tests/__init__.py deleted file mode 100644 index bb682033f9..0000000000 --- a/akvo/rsr/tests/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding: utf-8 -*- -""" - Akvo RSR is covered by the GNU Affero General Public License. - See more details in the license.txt file located at the root folder of the - Akvo RSR module. For additional details on the GNU license please - see < http://www.gnu.org/licenses/agpl.html >. -""" -from __future__ import absolute_import -from .partner_sites import * - -#starts the test suite -__test__ = { - 'partner_sites_tests': partner_sites, -} diff --git a/akvo/rsr/tests/partner_sites.py b/akvo/rsr/tests/partner_sites.py deleted file mode 100644 index 8d3f31155c..0000000000 --- a/akvo/rsr/tests/partner_sites.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -""" - Akvo RSR is covered by the GNU Affero General Public License. - See more details in the license.txt file located at the root folder of the - Akvo RSR module. For additional details on the GNU license please - see < http://www.gnu.org/licenses/agpl.html >. -""" -from __future__ import absolute_import -from django.contrib.sites.models import Site -from django.contrib.sites import models -from django.db import IntegrityError -from django.http import HttpRequest, Http404 -from django.utils import unittest -from django.test.client import Client -from ..middleware import PartnerSitesRouterMiddleware - -''' -__all__ = [ - #'PartnerSitesRouterMiddlewareTestCase', -] - - -class PartnerSitesRouterMiddlewareTestCase(unittest.TestCase): - - def setUp(self): - """Reusing middleware, Organisation and Partnersite objects where - appropriate. Otherwise there is one request per use case.""" - self.client = Client() - self.mw = PartnerSitesRouterMiddleware() - - # Configure default Site object - site_1 = Site.objects.get(pk=1) - site_1.domain = 'rsr.akvo.org' - site_1.name = 'rsr.akvo.org' - site_1.development_domain = 'akvo.dev' - site_1.save() - - self.akvo_request = HttpRequest() - self.akvo_request.META['SERVER_NAME'] = 'rsr.akvo.org' - self.akvo_request.META['SERVER_PORT'] = '8000' - - self.nonvalid_request = HttpRequest() - self.nonvalid_request.META['SERVER_NAME'] = 'www.nonvalid.org' - self.nonvalid_request.META['SERVER_PORT'] = '8000' - - self.valid_request = HttpRequest() - self.valid_request.META['SERVER_NAME'] = 'partner.akvo.org' - self.valid_request.META['SERVER_PORT'] = '8000' - - try: - s = models.Site.objects.create( - name='partner.akvo.org', - domain='partner.akvo.org', - organisation_id=272, - partner_domain='projects.a4a.org', - enabled=True) - s.save() - - except IntegrityError, e: - pass - - #print models.Site.objects.all() - - - def test_akvo_host(self): - """Tests bare rsr.akvo.org.""" - self.assertEqual(self.mw.process_request(self.akvo_request), None) - - def test_nonvalid_host(self): - """Tests nonvalid host.""" - valid_host = True - - try: - mw_response = self.mw.process_request(self.nonvalid_request) - except Http404, e: - valid_host = False - - self.assertEqual(valid_host, False) - - def test_valid_host(self): - self.assertEqual(self.mw.process_request(self.akvo_request), None) -''' diff --git a/akvo/settings/20-default.conf b/akvo/settings/20-default.conf index 7841166786..92d45e84b0 100644 --- a/akvo/settings/20-default.conf +++ b/akvo/settings/20-default.conf @@ -70,3 +70,5 @@ PIWIK_SITE_ID = 1 FB_APP_ID = 188270094690212 FILE_UPLOAD_MAX_MEMORY_SIZE = 8388608 # 8 Mb + +TEST_RUNNER = 'django.test.runner.DiscoverRunner' diff --git a/pg_tests.py b/pg_tests.py index 518b070abd..2aec15f2c0 100755 --- a/pg_tests.py +++ b/pg_tests.py @@ -2,12 +2,13 @@ # -*- coding: utf-8 -*- """ Akvo RSR is covered by the GNU Affero General Public License. + See more details in the license.txt file located at the root folder of the Akvo RSR module. For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. -This script is a tool to validate the transfer of data between mysql and -postgres using the Django ORM. +This script is a tool to validate the transfer of data between mysql and postgres using the Django +ORM. """ from __future__ import print_function @@ -28,6 +29,7 @@ def is_float_equal(x, y): + """Float is float.""" if abs(x - y) < 0.000000001: return True return False @@ -35,6 +37,8 @@ def is_float_equal(x, y): def pgDataType(field_type): """ + Match Django to Postgres field. + With the help of a Django field type, dig out the postgres counterpart. We also make sure to only return the column type description before ( or empty space. So we exclude the legnth of fields! diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index db000e14a2..0000000000 --- a/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'gabriel' diff --git a/tests/akvo/acceptance/all_test_suites.py b/tests/akvo/acceptance/all_test_suites.py deleted file mode 100755 index c69a7cd1f7..0000000000 --- a/tests/akvo/acceptance/all_test_suites.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import os, sys - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from test_settings import SITE_UNDER_TEST - -from internal.internal_unittests_suite import unittests_suite -from web.web_test_suite import web_suite - -def acceptance_test_suites(): - return create_test_suite_from_suites([web_suite()]) - -if __name__ == "__main__": - acceptance_test_root_path = os.path.realpath(os.path.dirname(__file__)) - print "Test suite root path: %s\n" % (acceptance_test_root_path) - - print "Running unit tests for acceptance test helpers\n" - if run_test_suite(unittests_suite()).wasSuccessful(): - print "\nRunning acceptance tests for: %s\n" % (SITE_UNDER_TEST) - run_test_suite(acceptance_test_suites()) - SeleniumClient().stop() - else: - print "\nUnable to run acceptance tests until the unit test errors above have been resolved\n" - sys.exit(1) diff --git a/tests/akvo/acceptance/api/__init__.py b/tests/akvo/acceptance/api/__init__.py deleted file mode 100644 index d1bdef2c31..0000000000 --- a/tests/akvo/acceptance/api/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the API acceptance test package. diff --git a/tests/akvo/acceptance/api/xml/__init__.py b/tests/akvo/acceptance/api/xml/__init__.py deleted file mode 100644 index b73cd0090a..0000000000 --- a/tests/akvo/acceptance/api/xml/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the api.xml acceptance test package. diff --git a/tests/akvo/acceptance/api/xml/all_le_sponsored_projects_test.py b/tests/akvo/acceptance/api/xml/all_le_sponsored_projects_test.py deleted file mode 100644 index 8500af9785..0000000000 --- a/tests/akvo/acceptance/api/xml/all_le_sponsored_projects_test.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from extensions.xmlextensions import * -from helpers.rsrapi import * -from helpers.testexecution import * -from testcases.xmltestcase import XMLTestCase - -from expectedelements import * - - -class AllLESponsoredProjectsTest(XMLTestCase): - - @classmethod - def setup_class(cls): - cls.all_LE_projects_root = element_root_from(api_path("projects.xml/live-earth")) - - def test_01_can_get_xml_data_for_all_LE_sponsored_projects(self): - """api.xml.AllLESponsoredProjectsTest 1. Can get XML data for all Live Earth sponsored projects""" - - self.assert_element(self.all_LE_projects_root).is_not_none_and_has_tag("response") - - expected_total_LE_projects = 23 # to be retrieved from RSR Admin - - self.assert_element(self.all_LE_projects_root).has_at_least(2).children() - self.assert_element(self.all_LE_projects_root).has_exactly(expected_total_LE_projects).children_with_tag("resource") - - def test_02_first_project_element_has_expected_xml_structure(self): - """api.xml.AllLESponsoredProjectsTest 2. First project element has expected XML structure""" - - first_project_element = self.all_LE_projects_root.find("resource") # each element represents a project - - self.assert_element(first_project_element).has_exactly(len(PROJECT_CHILDREN)).children() - self.assert_element(first_project_element).has_single_children_in_list(PROJECT_CHILDREN) - - project_country_element = first_project_element.find("country") - - self.assert_element(project_country_element).has_at_least(len(COUNTRY_CHILDREN)).children() - self.assert_element(project_country_element).has_single_children_in_list(COUNTRY_CHILDREN) - - -def suite(): - return load_tests_from(AllLESponsoredProjectsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/api/xml/all_project_updates_for_given_project_test.py b/tests/akvo/acceptance/api/xml/all_project_updates_for_given_project_test.py deleted file mode 100644 index 0988b62e5f..0000000000 --- a/tests/akvo/acceptance/api/xml/all_project_updates_for_given_project_test.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from extensions.xmlextensions import * -from helpers.rsrapi import * -from helpers.testexecution import * -from testcases.xmltestcase import XMLTestCase - -from expectedelements import * - - -class AllProjectUpdatesForGivenProjectTest(XMLTestCase): - - @classmethod - def setup_class(cls): - cls.all_updates_for_project_23 = element_root_from(api_path("project/23/updates.xml")) - - def test_01_can_get_xml_data_for_all_project_updates_for_given_project(self): - """api.xml.AllProjectUpdatesForGivenProjectTest 1. Can get XML data for all project updates for a given project""" - - self.assert_element(self.all_updates_for_project_23).is_not_none_and_has_tag("response") - - expected_total_project_updates = 8 # to be retrieved from RSR Admin - - self.assert_element(self.all_updates_for_project_23).has_at_least(2).children() - self.assert_element(self.all_updates_for_project_23).has_exactly(expected_total_project_updates).children_with_tag("resource") - - def test_02_first_project_update_element_has_expected_xml_structure(self): - """api.xml.AllProjectUpdatesForGivenProjectTest 2. First project update element has expected XML structure""" - - first_project_update_element = self.all_updates_for_project_23.find("resource") # each element represents a project update - - self.assert_element(first_project_update_element).has_exactly(len(PROJECT_UPDATE_CHILDREN)).children() - self.assert_element(first_project_update_element).has_single_children_in_list(PROJECT_UPDATE_CHILDREN) - - project_element = first_project_update_element.find("project") - - self.assert_element(project_element).has_exactly(len(PROJECT_UPDATE_PROJECT_CHILDREN)).children() - self.assert_element(project_element).has_single_children_in_list(PROJECT_UPDATE_PROJECT_CHILDREN) - - -def suite(): - return load_tests_from(AllProjectUpdatesForGivenProjectTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/api/xml/all_projects_test.py b/tests/akvo/acceptance/api/xml/all_projects_test.py deleted file mode 100644 index d062e08f53..0000000000 --- a/tests/akvo/acceptance/api/xml/all_projects_test.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from extensions.xmlextensions import * -from helpers.rsrapi import * -from helpers.testexecution import * -from testcases.xmltestcase import XMLTestCase - -from expectedelements import * - - -class AllProjectsTest(XMLTestCase): - - @classmethod - def setup_class(cls): - cls.all_projects_root = element_root_from(api_path("projects.xml")) - - def test_01_can_get_xml_data_for_all_projects(self): - """api.xml.AllProjectsTest 1. Can get XML data for all projects""" - - self.assert_element(self.all_projects_root).is_not_none_and_has_tag("response") - - expected_total_projects = 171 # to be retrieved from RSR Admin - - self.assert_element(self.all_projects_root).has_at_least(2).children() - self.assert_element(self.all_projects_root).has_exactly(expected_total_projects).children_with_tag("resource") - - def test_02_first_project_element_has_expected_xml_structure(self): - """api.xml.AllProjectsTest 2. First project element has expected XML structure""" - - first_project_element = self.all_projects_root.find("resource") # each element represents a project - - self.assert_element(first_project_element).has_exactly(len(PROJECT_CHILDREN)).children() - self.assert_element(first_project_element).has_single_children_in_list(PROJECT_CHILDREN) - - project_country_element = first_project_element.find("country") - - self.assert_element(project_country_element).has_at_least(len(COUNTRY_CHILDREN)).children() - self.assert_element(project_country_element).has_single_children_in_list(COUNTRY_CHILDREN) - - -def suite(): - return load_tests_from(AllProjectsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/api/xml/expectedelements.py b/tests/akvo/acceptance/api/xml/expectedelements.py deleted file mode 100644 index 60ad2ac014..0000000000 --- a/tests/akvo/acceptance/api/xml/expectedelements.py +++ /dev/null @@ -1,19 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -PROJECT_CHILDREN = ["goal_2", "subtitle", "map", "date_end_actual", "current_status_detail", "location_1", - "postcode", "id", "water_systems", "city", "project_plan_detail", "hygiene_facilities", - "project_rating", "category_sanitation", "category_product_development", "sanitation_systems", - "state", "location_2", "category_education", "latitude", "improved_water", "improved_water_years", - "status", "goal_3", "goal_1", "goal_4", "goal_5", "project_plan_summary", "trainees", - "category_water", "date_start_actual", "sustainability", "current_image_caption", - "improved_sanitation", "category_other", "current_image", "category_maintenance", - "name", "currency", "country", "notes", "category_training", "longitude", "context", - "goals_overview", "improved_sanitation_years"] - -COUNTRY_CHILDREN = ["name", "id", "continent"] - -PROJECT_UPDATE_CHILDREN = ["photo_credit", "photo_caption", "title", "text", "project", "time", "id", "photo"] - -PROJECT_UPDATE_PROJECT_CHILDREN = ["name", "id"] diff --git a/tests/akvo/acceptance/api/xml/single_project_test.py b/tests/akvo/acceptance/api/xml/single_project_test.py deleted file mode 100644 index b4593427b7..0000000000 --- a/tests/akvo/acceptance/api/xml/single_project_test.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from extensions.xmlextensions import * -from helpers.rsrapi import * -from helpers.testexecution import * -from testcases.xmltestcase import XMLTestCase - -from expectedelements import * - - -class SingleProjectTest(XMLTestCase): - - @classmethod - def setup_class(cls): - cls.project_23_root = element_root_from(api_path("project.xml/23")) - - def test_01_can_get_xml_data_for_single_project(self): - """api.xml.SingleProjectTest 1. Can get XML data for a single project""" - - self.assert_element(self.project_23_root).is_not_none_and_has_tag("response") - self.assert_element(self.project_23_root).has_exactly(1).child() - self.assert_element(self.project_23_root).has_exactly(1).child_with_tag("resource") - - def test_02_project_element_has_expected_xml_structure(self): - """api.xml.SingleProjectTest 2. Project element has expected XML structure""" - - project_element = self.project_23_root.find("resource") # the element represents a project - - self.assert_element(project_element).has_exactly(len(PROJECT_CHILDREN)).children() - self.assert_element(project_element).has_single_children_in_list(PROJECT_CHILDREN) - - project_country_element = project_element.find("country") - - self.assert_element(project_country_element).has_at_least(len(COUNTRY_CHILDREN)).children() - self.assert_element(project_country_element).has_single_children_in_list(COUNTRY_CHILDREN) - - -def suite(): - return load_tests_from(SingleProjectTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/api/xml/single_project_update_test.py b/tests/akvo/acceptance/api/xml/single_project_update_test.py deleted file mode 100644 index 6ef1cc1065..0000000000 --- a/tests/akvo/acceptance/api/xml/single_project_update_test.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import urllib2 - -from extensions.xmlextensions import * -from helpers.rsrapi import * -from helpers.testexecution import * -from testcases.xmltestcase import XMLTestCase - -from expectedelements import * -from test_settings import RSR_MEDIA_PATH - - -class SingleProjectUpdateTest(XMLTestCase): - - @classmethod - def setup_class(cls): - cls.project_update_200_root = element_root_from(api_path("update.xml/200")) - - def test_01_can_get_xml_data_for_single_project_update(self): - """api.xml.SingleProjectUpdateTest 1. Can get XML data for a single project update""" - - self.assert_element(self.project_update_200_root).is_not_none_and_has_tag("response") - self.assert_element(self.project_update_200_root).has_at_least(2).children() - - def test_02_project_update_element_has_expected_xml_structure(self): - """api.xml.SingleProjectUpdateTest 2. Project update element has expected XML structure""" - - self.assert_element(self.project_update_200_root).has_exactly(len(PROJECT_UPDATE_CHILDREN)).children() - self.assert_element(self.project_update_200_root).has_single_children_in_list(PROJECT_UPDATE_CHILDREN) - - project_element = self.project_update_200_root.find("project") - - self.assert_element(project_element).has_exactly(len(PROJECT_UPDATE_PROJECT_CHILDREN)).children() - self.assert_element(project_element).has_single_children_in_list(PROJECT_UPDATE_PROJECT_CHILDREN) - - def test_03_can_get_photo_path_for_given_project_update(self): - """api.xml.SingleProjectUpdateTest 3. Can get photo path for given project update""" - - photo_element = self.project_update_200_root.find("photo") - - self.assert_element(photo_element).has_text() - - def test_04_can_view_photo_at_media_path_for_given_project_update(self): - """api.xml.SingleProjectUpdateTest 4. Can view photo at media path for given project update""" - - photo_url = media_path(self.project_update_200_root.find("photo").text) - - self.failUnless(photo_url.startswith(RSR_MEDIA_PATH), - "Expected photo URL to start with media path: %s.\nActual URL: %s" % (RSR_MEDIA_PATH, photo_url)) - - photo_file = urllib2.urlopen(photo_url) - OK_STATUS_CODE = 200 - - self.failUnlessEqual(OK_STATUS_CODE, photo_file.code, - "Expected HTTP OK status code (200) when retrieving photo at: %s\nActual code: %i" % - (photo_url, photo_file.code)) - - photo_file_content_type = photo_file.info().getheader('Content-Type') - - self.failUnless(photo_file_content_type.startswith('image'), - "Expected photo content type to be image/*. Actual content type: %s" % (photo_file_content_type)) - - -def suite(): - return load_tests_from(SingleProjectUpdateTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/api/xml/xml_api_test_suite.py b/tests/akvo/acceptance/api/xml/xml_api_test_suite.py deleted file mode 100644 index 0e24da1002..0000000000 --- a/tests/akvo/acceptance/api/xml/xml_api_test_suite.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from api.xml.all_projects_test import AllProjectsTest -from api.xml.all_le_sponsored_projects_test import AllLESponsoredProjectsTest -from api.xml.single_project_test import SingleProjectTest -from api.xml.all_project_updates_for_given_project_test import AllProjectUpdatesForGivenProjectTest -from api.xml.single_project_update_test import SingleProjectUpdateTest - -from test_settings import RSR_API_PATH, RSR_MEDIA_PATH - -def describe_suite(): - print "Using API path: %s" % (RSR_API_PATH) - print "Using media path: %s\n" % (RSR_MEDIA_PATH) - -def xml_api_suite(): - describe_suite() - - return create_test_suite_from_classes([AllProjectsTest, - AllLESponsoredProjectsTest, - SingleProjectTest, - AllProjectUpdatesForGivenProjectTest, - SingleProjectUpdateTest]) - -if __name__ == "__main__": - run_test_suite(xml_api_suite()) diff --git a/tests/akvo/acceptance/extensions/__init__.py b/tests/akvo/acceptance/extensions/__init__.py deleted file mode 100644 index 6ea32ee6a4..0000000000 --- a/tests/akvo/acceptance/extensions/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the acceptance test extensions package. diff --git a/tests/akvo/acceptance/extensions/xmlextensions.py b/tests/akvo/acceptance/extensions/xmlextensions.py deleted file mode 100644 index 5430d45ce2..0000000000 --- a/tests/akvo/acceptance/extensions/xmlextensions.py +++ /dev/null @@ -1,9 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import urllib -import xml.etree.cElementTree as ET - -def element_root_from(url): - return ET.parse(urllib.urlopen(url)).getroot() diff --git a/tests/akvo/acceptance/helpers/__init__.py b/tests/akvo/acceptance/helpers/__init__.py deleted file mode 100644 index cb3eb82d06..0000000000 --- a/tests/akvo/acceptance/helpers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the acceptance test helpers package. diff --git a/tests/akvo/acceptance/helpers/akvopaths.py b/tests/akvo/acceptance/helpers/akvopaths.py deleted file mode 100644 index 630bced987..0000000000 --- a/tests/akvo/acceptance/helpers/akvopaths.py +++ /dev/null @@ -1,114 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -def home_page(): - return "/" - -def projects_page(): - return rsr_path("projects") - -def all_projects_page(): - return rsr_path("projects/all") - -def focus_areas_page(): - return cms_path("focus-areas") - -def partners_page(): - return cms_path("partners") - -def akvopedia_page(): - return "/wiki" - -def about_page(): - return cms_path("about") - -def blog_page(): - return "/blog" - -def register_page(): - return rsr_path("accounts/register1") - -def sign_in_page(): - return rsr_path("signin/?next=%s" % home_page()) - -def terms_of_use_page(): - return cms_path("terms_of_use") - -def donation_policy_page(): - return cms_path("donation_policy") - -def partners_policy_page(): - return cms_path("partners_and_projects_policy") - -def user_contribution_policy_page(): - return cms_path("user_contribution_policy") - -def open_license_page(): - return cms_path("open_license") - -def privacy_policy_page(): - return cms_path("privacy_policy") - -def api_code_of_conduct_page(): - return cms_path("akvo-rsr-api-code-of-conduct") - -def what_we_do_page(): - return cms_path("what_we_do") - -def how_akvo_works_page(): - return cms_path("how_akvo_works") - -def why_we_do_it_page(): - return cms_path("why_we_do_it") - -def faq_page(): - return cms_path("faq") - -def global_maps_page(): - return cms_path("map_partners_projects") - -def akvo_team_page(): - return cms_path("team") - -def akvo_jobs_page(): - return cms_path("jobs") - -def press_page(): - return cms_path("press") - -def annual_reports_page(): - return cms_path("annual_reports") - -def organisations_page(): - return rsr_path("organisations") - -def commercial_partners_page(): - return cms_path("commercial_partners") - -def knowledge_institute_partners_page(): - return cms_path("knowledge_institute_partners") - -def akvo_investors_page(): - return cms_path("akvo_investors") - -def akvo_labs_page(): - return "/labs" - -def contact_us_page(): - return cms_path("contact_us") - -def rsr_admin_page(): - return rsr_path("admin") - -def blog_admin_page(): - return "/blog/wp-login.php" - -def cms_admin_page(): - return cms_path("?q=user") - -def rsr_path(subpath): - return "/rsr/%s" % subpath - -def cms_path(cms_page_name): - return "/web/%s" % cms_page_name diff --git a/tests/akvo/acceptance/helpers/akvourls.py b/tests/akvo/acceptance/helpers/akvourls.py deleted file mode 100644 index 22cb893f6d..0000000000 --- a/tests/akvo/acceptance/helpers/akvourls.py +++ /dev/null @@ -1,29 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import sys -import helpers.akvopaths - -from test_settings import SITE_UNDER_TEST - - -def generate_akvo_url_functions(): - for path_function_name in akvo_page_path_functions(): - url_function_name = path_function_name.replace("_page", "_url") - setattr(sys.modules[__name__], url_function_name, create_url_function(path_function_name)) - -def akvo_page_path_functions(): - return filter(lambda name: name.endswith('_page'), dir(helpers.akvopaths)) - -def create_url_function(path_function_name): - return lambda: full_url_for_path(path_function_name) - -def full_url_for_path(page_path_function_name): - return "%s%s" % (SITE_UNDER_TEST, getattr(helpers.akvopaths, page_path_function_name)()) - - -# Generate URL functions for each of the Akvo page paths and attach them -# dynamically to this module, e.g. the akvopaths.about_page() function -# will have a corresponding akvourls.about_url() function -generate_akvo_url_functions() diff --git a/tests/akvo/acceptance/helpers/constraintmatchers.py b/tests/akvo/acceptance/helpers/constraintmatchers.py deleted file mode 100644 index 73d9eeab80..0000000000 --- a/tests/akvo/acceptance/helpers/constraintmatchers.py +++ /dev/null @@ -1,35 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The following match classes facilitate constraint matching in tests - -class MatcherBase: - - _description = "items" - - def __init__(self, test_case, expected_value): - self._test_case = test_case - self._expected_value = expected_value - - def set_description(self, new_description): - self._description = new_description - - def evaluate(self, object_to_evaluate): - raise Exception("Missing evaluate() method implementation for %s" % self.__class__) - - -class ExactMatcher(MatcherBase): - - def evaluate(self, actual_value): - self._test_case.failUnlessEqual(self._expected_value, actual_value, - "Expected exactly %i %s. Actual %s: %i" % - (self._expected_value, self._description, self._description, actual_value)) - - -class AtLeastMatcher(MatcherBase): - - def evaluate(self, actual_value): - self._test_case.failUnless(self._expected_value <= actual_value, - "Expected at least %i %s. Actual %s: %i" % - (self._expected_value, self._description, self._description, actual_value)) diff --git a/tests/akvo/acceptance/helpers/elementparsing.py b/tests/akvo/acceptance/helpers/elementparsing.py deleted file mode 100644 index d6b18cbeb6..0000000000 --- a/tests/akvo/acceptance/helpers/elementparsing.py +++ /dev/null @@ -1,28 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import time, urllib2 - -from lxml import etree - - -def create_xml_element_root_from(url): - return etree.XML(read_text_from(url)) - -def create_html_element_root_from(url): - return etree.HTML(read_text_from(url)) - -def read_text_from(url): - headers = {"Cache-Control": "no-cache, no-store, max-age=0", "Pragma": "no-cache", "Connection": "close"} - return urllib2.urlopen(urllib2.Request(url, None, headers)).read() - -def elements_to_string(element_root): - return etree.tostring(element_root, pretty_print=True) - -def text_values_at_xpath(element_search_root, elements_xpath): - trimmed_text_values = map(lambda text: text.strip(), values_at_xpath(element_search_root, "%s/text()" % elements_xpath)) - return filter(lambda text: len(text) > 0, trimmed_text_values) - -def values_at_xpath(element_search_root, values_xpath): - return element_search_root.xpath(values_xpath) diff --git a/tests/akvo/acceptance/helpers/externalurls.py b/tests/akvo/acceptance/helpers/externalurls.py deleted file mode 100644 index 32d6b260e3..0000000000 --- a/tests/akvo/acceptance/helpers/externalurls.py +++ /dev/null @@ -1,12 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -def akvo_source_code_url(): - return "http://github.com/akvo" - -def akvo_support_url(): - return "http://help.akvo.org" - -def report_a_problem_url(): - return "%s/discussion/new" % akvo_support_url() diff --git a/tests/akvo/acceptance/helpers/navigation.py b/tests/akvo/acceptance/helpers/navigation.py deleted file mode 100644 index aa1628b051..0000000000 --- a/tests/akvo/acceptance/helpers/navigation.py +++ /dev/null @@ -1,97 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The SeleniumNavigator and RSRNavigator facilitate common navigation operations - -from test_settings import * - -from helpers.akvopaths import * - - -class SeleniumNavigator: - - def __init__(self, selenium_client): - self.selenium = selenium_client - - def wait_for_page_to_load(self): - self.selenium.wait_for_page_to_load(PAGE_LOAD_TIMEOUT) - - def open_page(self, path): - self.selenium.open(path) - self.wait_for_page_to_load() - - def click_element_at_path(self, element_path): - self.selenium.click(element_path) - self.wait_for_page_to_load() - - def click_link(self, link_text): - self.click_element_at_path("link=%s" % (link_text)) - - def click_tab(self, tab_element_path): - self.click_element_at_path(tab_element_path) - - def click_javascript_tab(self, tab_element_path): - self.selenium.click(tab_element_path) # client side, so no page load wait needed - - def click_button(self, button_name_or_path): - self.click_element_at_path(button_name_or_path) - - def click_submit_button(self): - self.click_button("//button[@type='submit']") - - def click_submit_button_with_text(self, button_text): - self.click_element_at_path("//input[@value=\"%s\"]" % (button_text)) - - -class AkvoSiteNavigator: - - def __init__(self, selenium_client): - self.selenium = selenium_client - self.navigator = SeleniumNavigator(self.selenium) - - def open_page(self, page_path): - self.navigator.open_page(page_path) - - def open_home_page(self): - self.open_page(home_page()) - - def open_projects_page(self): - self.open_page(projects_page()) - - def open_all_projects_page(self): - self.open_page(all_projects_page()) - - def open_focus_areas_page(self): - self.open_page(focus_areas_page()) - - def open_partners_page(self): - self.open_page(partners_page()) - - def open_akvopedia_page(self): - self.open_page(akvopedia_page()) - - def open_about_page(self): - self.open_page(about_page()) - - def open_blog_page(self): - self.open_page(blog_page()) - - def open_auth_admin_page(self): - self.open_admin_page("auth/") - - def open_user_admin_page(self): - self.open_admin_page("auth/user/") - - def open_rsr_admin_page(self): - self.open_admin_page("rsr/") - - def open_project_page(self, project_number): - self.open_page("/rsr/project/%i/" % (project_number)) - - def open_admin_page(self, extended_admin_path = ""): - self.open_page("/rsr/admin/%s" % (extended_admin_path)) - if self.selenium.is_text_present("Password:"): - self.selenium.type("id_username", SUPERUSER_USERNAME) - self.selenium.type("id_password", SUPERUSER_PASSWORD) - self.navigator.click_submit_button_with_text("Log in") diff --git a/tests/akvo/acceptance/helpers/rsrapi.py b/tests/akvo/acceptance/helpers/rsrapi.py deleted file mode 100644 index f89efccea6..0000000000 --- a/tests/akvo/acceptance/helpers/rsrapi.py +++ /dev/null @@ -1,14 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from test_settings import RSR_API_PATH, RSR_MEDIA_PATH - -def api_path(request_path): - return _rsr_path(RSR_API_PATH, request_path) - -def media_path(content_path): - return _rsr_path(RSR_MEDIA_PATH, content_path) - -def _rsr_path(base_url, path): - return "%s%s" % (base_url, path) diff --git a/tests/akvo/acceptance/helpers/rsrpath.py b/tests/akvo/acceptance/helpers/rsrpath.py deleted file mode 100644 index cfd4129d10..0000000000 --- a/tests/akvo/acceptance/helpers/rsrpath.py +++ /dev/null @@ -1,33 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from test_settings import SITE_UNDER_TEST - - -def home_page_path(): - return SITE_UNDER_TEST - -def project_listing_path(): - return rsr_path("projects") - -def project_path(project_number): - return rsr_path(_project_number_path(project_number)) - -def project_updates_path(project_number): - return _url_path(project_path(project_number), "/updates") - -def project_widget_path(project_number, widget_type): - return rsr_path("widget/%s/%s" % (widget_type, _project_number_path(project_number))) - -def project_listing_widget_path_for_organisation(organisation_number): - return rsr_path("widget/project-list/organisation/%i" % organisation_number) - -def _project_number_path(project_number): - return "project/%i" % project_number - -def rsr_path(subpath): - return _url_path(SITE_UNDER_TEST, "/rsr/%s" % subpath) - -def _url_path(base_url, path): - return "%s%s" % (base_url, path) diff --git a/tests/akvo/acceptance/helpers/seleniumclient.py b/tests/akvo/acceptance/helpers/seleniumclient.py deleted file mode 100644 index 0a2cddb5ee..0000000000 --- a/tests/akvo/acceptance/helpers/seleniumclient.py +++ /dev/null @@ -1,36 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# SeleniumClient provides a singleton wrapper to manage starting and stopping a Selenium RC client -# more easily for the duration of a single test case or over a suite of tests - -from selenium import selenium - -from test_settings import * - -class SeleniumClient: - - __instance = None - - def __init__(self): - if SeleniumClient.__instance is None: - self.start() - - def instance(self): - return SeleniumClient.__instance - - def start(self): - if SeleniumClient.__instance is None: - try: - SeleniumClient.__instance = selenium(SELENIUM_RC_HOST, SELENIUM_RC_PORT, BROWSER_ENVIRONMENT, SITE_UNDER_TEST) - SeleniumClient.__instance.start() - except Exception, exception: - print ">> Unable to start Selenium RC client: %s" % (exception) - raise exception - - def stop(self): - try: - SeleniumClient.__instance.stop() - except Exception, exception: - print ">> Unable to stop Selenium RC client: %s" % (exception) diff --git a/tests/akvo/acceptance/helpers/testexecution.py b/tests/akvo/acceptance/helpers/testexecution.py deleted file mode 100644 index 86f8db463c..0000000000 --- a/tests/akvo/acceptance/helpers/testexecution.py +++ /dev/null @@ -1,26 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from test_settings import TEST_MODE - - -def create_test_suite_from_classes(test_class_list): - return create_test_suite_from_suites(map(lambda test_class: load_tests_from(test_class), test_class_list)) - -def create_test_suite_from_suites(test_suite_list): - return nose.suite.LazySuite(test_suite_list) - -def load_tests_from(test_case): - return nose.loader.TestLoader().loadTestsFromTestCase(test_case) - -def run_test_suite(suite): - test_runner = nose.core.TextTestRunner(verbosity=2) - - if TEST_MODE == 'ci': - from teamcity.unittestpy import TeamcityTestRunner - test_runner = TeamcityTestRunner() - - return test_runner.run(suite) diff --git a/tests/akvo/acceptance/helpers/unittests/__init__.py b/tests/akvo/acceptance/helpers/unittests/__init__.py deleted file mode 100644 index 382dc4794f..0000000000 --- a/tests/akvo/acceptance/helpers/unittests/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo helpers.unittests package. diff --git a/tests/akvo/acceptance/helpers/unittests/akvopaths_test.py b/tests/akvo/acceptance/helpers/unittests/akvopaths_test.py deleted file mode 100644 index b7c2653398..0000000000 --- a/tests/akvo/acceptance/helpers/unittests/akvopaths_test.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.akvopaths import * -from helpers.testexecution import * - - -class AkvoPathsTest(TestCase): - - def test_can_get_home_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Home page""" - self.verify_path("/", home_page()) - - def test_can_get_projects_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Projects page""" - self.verify_path("/rsr/projects", projects_page()) - - def test_can_get_all_projects_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for All Projects page""" - self.verify_path("/rsr/projects/all", all_projects_page()) - - def test_can_get_focus_areas_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Focus Areas page""" - self.verify_path("/web/focus-areas", focus_areas_page()) - - def test_can_get_partners_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Partners page""" - self.verify_path("/web/partners", partners_page()) - - def test_can_get_akvopedia_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Akvopedia page""" - self.verify_path("/wiki", akvopedia_page()) - - def test_can_get_about_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for About page""" - self.verify_path("/web/about", about_page()) - - def test_can_get_blog_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Blog page""" - self.verify_path("/blog", blog_page()) - - def test_can_get_register_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Register page""" - self.verify_path("/rsr/accounts/register1", register_page()) - - def test_can_get_sign_in_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Sign in page""" - self.verify_path("/rsr/signin/?next=/", sign_in_page()) - - def test_can_get_terms_of_use_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Terms of use page""" - self.verify_path("/web/terms_of_use", terms_of_use_page()) - - def test_can_get_donation_policy_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Donation policy page""" - self.verify_path("/web/donation_policy", donation_policy_page()) - - def test_can_get_partners_policy_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Partners policy page""" - self.verify_path("/web/partners_and_projects_policy", partners_policy_page()) - - def test_can_get_user_contribution_policy_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for User contribution policy page""" - self.verify_path("/web/user_contribution_policy", user_contribution_policy_page()) - - def test_can_get_open_license_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Open license page""" - self.verify_path("/web/open_license", open_license_page()) - - def test_can_get_privacy_policy_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Privacy policy page""" - self.verify_path("/web/privacy_policy", privacy_policy_page()) - - def test_can_get_api_code_of_conduct_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Akvo RSR API code of conduct page""" - self.verify_path("/web/akvo-rsr-api-code-of-conduct", api_code_of_conduct_page()) - - def test_can_get_what_we_do_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for What we do page""" - self.verify_path("/web/what_we_do", what_we_do_page()) - - def test_can_get_how_akvo_works_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for How Akvo works page""" - self.verify_path("/web/how_akvo_works", how_akvo_works_page()) - - def test_can_get_why_we_do_it_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Why we do it page""" - self.verify_path("/web/why_we_do_it", why_we_do_it_page()) - - def test_can_get_faq_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for FAQ page""" - self.verify_path("/web/faq", faq_page()) - - def test_can_get_partners_and_projects_maps_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Partners and Projects maps page""" - self.verify_path("/web/map_partners_projects", global_maps_page()) - - def test_can_get_akvo_team_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Akvo team page""" - self.verify_path("/web/team", akvo_team_page()) - - def test_can_get_working_at_akvo_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Working at Akvo page""" - self.verify_path("/web/jobs", akvo_jobs_page()) - - def test_can_get_press_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Press page""" - self.verify_path("/web/press", press_page()) - - def test_can_get_annual_reports_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Annual reports page""" - self.verify_path("/web/annual_reports", annual_reports_page()) - - def test_can_get_organisations_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Organisations page""" - self.verify_path("/rsr/organisations", organisations_page()) - - def test_can_get_commercial_partners_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Commercial partners page""" - self.verify_path("/web/commercial_partners", commercial_partners_page()) - - def test_can_get_knowledge_institute_partners_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Knowledge institute partners page""" - self.verify_path("/web/knowledge_institute_partners", knowledge_institute_partners_page()) - - def test_can_get_akvo_investors_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Akvo investors page""" - self.verify_path("/web/akvo_investors", akvo_investors_page()) - - def test_can_get_akvo_labs_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Akvo Labs page""" - self.verify_path("/labs", akvo_labs_page()) - - def test_can_get_contact_us_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Contact us page""" - self.verify_path("/web/contact_us", contact_us_page()) - - def test_can_get_rsr_admin_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for RSR admin page""" - self.verify_path("/rsr/admin", rsr_admin_page()) - - def test_can_get_blog_admin_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for Blog admin page""" - self.verify_path("/blog/wp-login.php", blog_admin_page()) - - def test_can_get_cms_admin_page_path(self): - """helpers.unittests.AkvoPathsTest Can get path for CMS admin page""" - self.verify_path("/web/?q=user", cms_admin_page()) - - def verify_path(self, expected_path, actual_path): - self.assertEqual(expected_path, actual_path, "\nExpected path: %s\n Actual path: %s" % (expected_path, actual_path)) - - -def suite(): - return load_tests_from(AkvoPathsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/helpers/unittests/akvourls_test.py b/tests/akvo/acceptance/helpers/unittests/akvourls_test.py deleted file mode 100644 index 6b9557096a..0000000000 --- a/tests/akvo/acceptance/helpers/unittests/akvourls_test.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.akvopaths import * -from helpers.akvourls import * -from helpers.testexecution import * - - -class AkvoURLsTest(TestCase): - - def test_ensure_akvourls_module_has_url_function_for_each_akvo_page_path(self): - """helpers.unittests.AkvoURLsTest Ensure helpers.akvourls module has a URL function for each Akvo page path""" - - expected_url_function_names = self.expected_akvo_url_function_names() - actual_url_function_names = self.actual_akvo_url_function_names() - - self.assertEqual(len(expected_url_function_names), len(actual_url_function_names), - "\nExpected number of URL function names: %i\n Actual number of URL function names: %i" % - (len(expected_url_function_names), len(actual_url_function_names))) - - for expected_function_name in expected_url_function_names: - self.assertTrue(expected_function_name in actual_url_function_names, - "\nExpected URL function name '%s' in:\n%s" % - (expected_function_name, actual_url_function_names)) - - def test_can_get_akvo_url_from_given_page_function_name(self): - """helpers.unittests.AkvoURLsTest Can get Akvo URL from given page function name""" - - self.verify_url(self.full_url(home_page()), home_url()) - self.verify_url(self.full_url(projects_page()), projects_url()) # verifies an RSR URL - self.verify_url(self.full_url(about_page()), about_url()) # verifies a CMS URL - self.verify_url(self.full_url(blog_page()), blog_url()) # verifies a blog URL - - def expected_akvo_url_function_names(self): - import helpers.akvopaths - expected_page_paths = filter(lambda name: name.endswith('_page'), dir(helpers.akvopaths)) - return map(lambda page_path: page_path.replace('_page', '_url'), expected_page_paths) - - def actual_akvo_url_function_names(self): - import helpers.akvourls - return filter(lambda name: name.endswith('_url'), dir(helpers.akvourls)) - - def full_url(self, path): - return "%s%s" % (SITE_UNDER_TEST, path) - - def verify_url(self, expected_url, actual_url): - self.assertEqual(expected_url, actual_url, "\nExpected URL: %s\n Actual URL: %s" % (expected_url, actual_url)) - - -def suite(): - return load_tests_from(AkvoURLsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/helpers/unittests/externalurls_test.py b/tests/akvo/acceptance/helpers/unittests/externalurls_test.py deleted file mode 100644 index d7d8c39bd2..0000000000 --- a/tests/akvo/acceptance/helpers/unittests/externalurls_test.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.externalurls import * -from helpers.testexecution import * - - -class ExternalURLsTest(TestCase): - - def test_can_get_akvo_source_code_url(self): - """helpers.unittests.ExternalURLsTest Can get URL for Akvo source code""" - self.verify_url("http://github.com/akvo", akvo_source_code_url()) - - def test_can_get_akvo_support_url(self): - """helpers.unittests.ExternalURLsTest Can get URL for Akvo help & support""" - self.verify_url("http://help.akvo.org", akvo_support_url()) - - def test_can_get_report_a_problem_url(self): - """helpers.unittests.ExternalURLsTest Can get URL for Reporting a problem""" - self.verify_url("http://help.akvo.org/discussion/new", report_a_problem_url()) - - def verify_url(self, expected_url, actual_url): - self.assertEqual(expected_url, actual_url, "\nExpected URL: %s\n Actual URL: %s" % (expected_url, actual_url)) - - -def suite(): - return load_tests_from(ExternalURLsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/helpers/unittests/helpers_test_suite.py b/tests/akvo/acceptance/helpers/unittests/helpers_test_suite.py deleted file mode 100644 index 36d0a6c136..0000000000 --- a/tests/akvo/acceptance/helpers/unittests/helpers_test_suite.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from helpers.unittests.akvopaths_test import AkvoPathsTest -from helpers.unittests.akvourls_test import AkvoURLsTest -from helpers.unittests.externalurls_test import ExternalURLsTest -from helpers.unittests.rsrpath_test import RSRPathTest - - -def helpers_suite(): - return create_test_suite_from_classes([AkvoPathsTest, AkvoURLsTest, ExternalURLsTest, RSRPathTest]) - -if __name__ == "__main__": - run_test_suite(helpers_suite()) diff --git a/tests/akvo/acceptance/helpers/unittests/rsrpath_test.py b/tests/akvo/acceptance/helpers/unittests/rsrpath_test.py deleted file mode 100644 index 7dff16001c..0000000000 --- a/tests/akvo/acceptance/helpers/unittests/rsrpath_test.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.rsrpath import * -from helpers.testexecution import * - - -class RSRPathTest(TestCase): - - def test_can_get_home_page_path(self): - """helpers.unittests.RSRPathTest Can get home page path""" - - self.verify_path(SITE_UNDER_TEST, home_page_path()) - - def test_can_get_rsr_project_listing_path(self): - """helpers.unittests.RSRPathTest Can get RSR project listing path""" - - self.verify_path(self.url_path(SITE_UNDER_TEST, "/rsr/projects"), project_listing_path()) - - def test_can_get_path_for_a_specified_rsr_project(self): - """helpers.unittests.RSRPathTest Can get path for a specified RSR project""" - - self.verify_path(self.url_path(SITE_UNDER_TEST, "/rsr/project/108"), project_path(108)) - - def test_can_get_project_updates_path_for_a_specified_rsr_project(self): - """helpers.unittests.RSRPathTest Can get project updates path for a specified RSR project""" - - self.verify_path(self.url_path(SITE_UNDER_TEST, "/rsr/project/108/updates"), project_updates_path(108)) - - def test_can_get_project_widget_path_for_a_specified_rsr_project_and_widget_type(self): - """helpers.unittests.RSRPathTest Can get project widget path for a specified RSR project and widget type""" - - self.verify_path(self.url_path(SITE_UNDER_TEST, "/rsr/widget/cobranded-short/project/108"), project_widget_path(108, "cobranded-short")) - - def test_can_get_project_listing_widget_path_for_a_specified_rsr_organisation(self): - """helpers.unittests.RSRPathTest Can get project listing widget path for a specified RSR organisation""" - - self.verify_path(self.url_path(SITE_UNDER_TEST, "/rsr/widget/project-list/organisation/15"), project_listing_widget_path_for_organisation(15)) - - def url_path(self, base_url, path): - return "%s%s" % (base_url, path) - - def verify_path(self, expected_path, actual_path): - self.failUnlessEqual(expected_path, actual_path, "\nExpected path: %s\n Actual path: %s" % (expected_path, actual_path)) - - -def suite(): - return load_tests_from(RSRPathTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/images/kagiso_map.jpg b/tests/akvo/acceptance/images/kagiso_map.jpg deleted file mode 100644 index 65c2e35102bd04c843d7cfa797f96cefc0761489..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26876 zcmbTdcT^Km*FG8qq=TaLrWENQNRh50H3HH*h}3|gNeK`@Ec7B>y7b-?dhbO*2oMRq zOHYszAiyv0cfa-CweDZ{-ZPUmXRX<1)_%^+IoW$Zd*A-KT>;$FRMk)g5D*Xm)bR)4 zb`|hR1p;ya0JO9K0ssJj6hKTs3n0Yz2=E7hfEhsiKYai|lYr&FeLVuc|CPA|0EB@6 zME@&ehQI!&;h+4U(f@nB^YhMsC5C?z{*)9w-x z5fYQ!B_ScXd-pC0DFqn`DLLugyJS>k4sa02e!Cm_5}aN7sqz#}2X&)0vZ?0*}<9YP{vyheCE@B;9A zc=ZVh@8FdsCc;kyK_LDh; zt842Un_Js|cXlzy|4vTN&aoGl|G`B7ApE~z{TJE)1J`{#t~>a5Kt%E%Tm*M~@jt@* zM8uE9?$W;0C9&~%z$qR=`tVhJZf!Ri*E2md-FweTa(ZrwRUXWLp#2ZB|98MX|Nlbv zUts??E);;0kO2Sk2=4=w09O+?6g*eTkn$C!eZ*?Jey^{8X9x^zJHQ+ivt~^PI)3fe zCQ~q8?^idlA>MTiWNU9s_vDg(+`W*`!Fw|n+~`xhsuU5-0)2KR1O;LmqoFbdIG#3) z>>?!JDER(v5ao1!+vg|QsKb@EdO}Bq&E>g`e@|!0U!dk)PPlH!?^p0F?;osN(%qe7p zhFc(Cq{+;?*0%J3tWuY=!q!N(k&zI)<0bX^?VLyswC+(bV6(AUim( zQ*Rh?is*rQfx26O^Nu22Lt_WU<6lEnT)$knJa==Iw}r^IY9-=A6^YQq?Wfsa&~7U? z5%eX|jo;0&EIJM5aKGHFuVpnct3~jJq-_}pmupFZ%T28fYcZYg$o?X%y?VJ`ZFr_{ zAVF(s%u+D}eo^FzbzHBGg9>AAZUL(_VQxXRW{_nIOz)0y@V$5FjlH79(BHQJIO;A! zadEsnp}c01?&%HobFi<;Y%p3+DN=U%6V7<;Kmf6t58|LuTYyV<@fAP2X z=$Qg$s+|S9NVR&G;3qN^QWRxMTs|7y)V-_cQ7|@^KKH+@r|-UKF=&j~kQPwd{29*f z&QT@iz5K}Ie!DyN_E#yG(Co3XMN^7y%4#SNw`ZTuI+ukLB?i5~u=&F-_=|R!<@ikNI zFkQGkDquEwyn!bCofBtE0_hiXAm`u}Jbn?t^qiMio#$ipKZA~^IQ_|B$BEB3T$s3M z;lsf&99@A%uw+&0hnT00AGuZ!j7)?!5a&$1=zXK$ExJMJ{p z&YYH8vkF(GG|V<8T2Pqhe`M=xxG|`kvsBBG_JlbKh&La9WR~3PIgtP^p$?j0YmK|- z#|YrUey?_x^wHtT)rs3C;z;3rJ@lRAUG&%rx@7#P{=MV7)M_%WvW}G>8FFCDpCn?e ztzj6oNUuP04k{2zyELH8IrVHdUB9>Vx_H0CaD8;M*{x1vnM4rQ;5;~}6U%JeB^q`Q zl4^;7Puy1yF4;k8=h**LAs(A8^aynSZZ4$wVY1IK+u$Pl)4OfSIRU*)KX2okj(_P! zpz=g0ciT)A%mt3A9Lxx&8&+nr6Q(_|xWiDSy}P^D6T|{_MUM^SRzT9+f>*6T=~nHx z0MdyFuTG{hw}M4bOZmLAFI}@kT5fzn=rPI!S873*6#Fw|zW6|RWj^@co)r6I40}v& z7E9mJDie!Ydn1B)AWs06zO6<|d2tb=g!%i+m>7W9ZSD%#i_pjf*ub=)Q0B%fAJfKlIr@A~*^BxpL_r ztEwisu?#oHJyct@-UqE+S<~R$X5fWLM?}HwcFkm)QgEdOsKw6JHt}sMkdH@dwrn+Z zEYXR_MC72du^L?+xqrh0u~nH3y6;Rc+aB9#!(QagBKOV3rPZ`6K`Pdel6s{tpE@dW z!8j%pS^X)Y@}-L~^X8W8gv!H8-*PwWZyNK;sBXQ`$DW3B&hWZ_tp|Blm0ZpmENg6& zksMMA)DI$}1Xa%y2!BDIKPFNAtFc~NNu}3)@?At;o-1hK6-L#R>@z22s^Yzc)M0p;te_9fz?z`*68~SVQyDjt)L2$ zS^k-P{cMeS)8;uKu<*%&ul=u-u|0=hJg0Gv&$XqrydupiKcIkxCxOs0Spm7$p%22@ zE*G|+83(L17zIjBxzPd&Qm54izv3RKTn!phzFf);rxcs}L=?b$36!%quC9!1InA5z zf0FAAZOw2RO(D5sXps>2C$@>V$Wss~v!g!3rtVJ4MZ|uZwK`XOmf>UqbaUiQe)uVI zK;~6I@=p9g_RDIy#oqUNK+T*>y;j#H7vJmY?7zFSaADuLjT0P)juc4u?Xq=m(R`Yl z1t(#gUf&78oBNC~(LibSamy{>r(*6cAW-EN&_4^uOuHX%WccnUrY?_URZm^*fzu?= zrvg<@mGUU-thk5Q^>)nJ@vDKNM^%k$i;6?B6`0p+s%&H{{i2&zS73&CH)iVa+~CJn zlwOq->&U_2Fy_uMsN-t;M~(VPQF&nD{2vR+-?Q)k*@PUuPmz2op?R)*@c8)6&rfPx z^EkIPu=Hxqmm_&)3@t_?khWX5N|ZNdM6E+5=D7;@=As&5yO&L==EKKKqJE3;x#7j@ zv3l7$z0xNQbN<5j{4}ULnaDp4yLPd!2#R=|E-49YcL-vi0cX9;D|O6Ge_aNa!&G?e z0iV;+7p=-DwqkNxslN96XCF!F|P>}R(gD*Yj4e6PeY&!@z z-+>)1{M%3@f3*1eVN)!`+$}$HGn552P{Hcu>4O*!YNUT6R!%x#**U)aEmnC&EtI48 zhOi-J=ZNyWYh*{_h_hs=pS=7*BcJi}Jxl3us8|uUp&ty@w{a{r=Ps4)_a+~S;$$0H zdCK+Z)5`<1gq?rgqzO)Tua)`?Lf#_n41OjgwjMf?9`~!cSLi&%DIsv?<)HL$n6}1g ziBMaYk1n2Q^~n8D^?6Y5z>S`(DiPby^+)#`E!xiqbZ9_G4XT+l9$R>l>fne>H_ads z>y06u;H%jB1gpF(b>(#*`T4V^$x|8>&8l>);=P5PFTFb$h8NQkT5_h-1+f9fY4I;a zi72Q1)O_{fopW^SE!H^N3_bPJfITW;m(|?_u+-vEa62r5rD+iHHBxy^D{iT<2-n3 zIl{B3*`Rg#@TLmdSaJ*Kmf^)(2j_~0Lfux|@1Qiifcz4z>hQ6t7PYE@9dHRn<8u*}xBa#w@9Pjt}1Gck%CdgEjZYgeT8k(nQDQO|5uKJ7r?bOsh zTz$#kn6GgQ$XPgyi{i#xKp#en7R;QEN_LpR)2OZT5;Lr|G6JVjfR!4dQUf;DWiwU_ zxzf8|Riv-IIARqKtXg{-X)&sGU97Z{)RLWx4j4=qiNY|bOhU!h0tHQ`Ol=XT?w9^n zJF<#7L=%$m?v|#|CsP)~U=N8J+3|#lZN{g!07ob<=6bM?igPPabq>5l7J28>zPsuR zqEoKU)jfkC9+zwZ9j3o6q9G}$fl<@Y^|6_a`hZ$n2^&k@e9H0&h9IUNl%;I$G+L}? z)pXB4{Cc;pC!p*9Y*T0c-woNpS{y2W-3HrvMT2uew2}F)#n3PJEEQ2O@m)Q>q)ney1TX_;rgrm zpWIlAk<7$M`7s*r7Rxc-u+5v84wt!H8pYeMX?Y)1oJt`UZ^pbEpb=6vOz$f+geVBU zEp)%+jl=mWHm`;@Vs$FaL6`6jSh_*{uUeI7AL3Q|JcI{FEM5&5tb`J%5505Q7GpGP zT7c$i7S~5Vw1-stHU4V3YT=m`*V6c#{^nBYKp=`xGsa>2;YL3F^>kLoznRv*h?XU! zYFNyv4&5KqSJ_N;v1gZ;$`3tW^*jeRaSto>eL8rF*o^p-@U%EnZAB?GeLN!IY?&3C z9_S3}_N$1=6m)#}HKvI6?YLA(bX#SPN*7@^*m_`@8fsu9{H%XT7EzE4-fC)UMhMSo z#AI2`lIDjq_8zE#vPg%!pyVz%eOOBh;LE+oIQ*Q8@~$)` zt=Q23)kh81C4Tg4Gv7#8?-*4FlwJE|I{5j>%W-;xcoTnGM#6mv(=CAPLz_m~MEM+c zeD`v%H-&-25y9K8OP}k{!1>Z$KTPG3K*#-@tp!HF(O^{dx51@o+ESjfMZuy}@hn(F z?B0@j!5o~_DAzf`mH+79U!?h&zwhsTi8xx3VzDo}U%5!;S<6#Cucl@W^m(&q4-&1U zBP%8zE|`Os*m4fQ57leq>D36jMh@72eo|H7YsAi=boD|!}v zHm1tK!peG69#zdCk=R=2-vGDLGF1@u%5G^X4f94eu;N{C zb4Dez$iri~zp(kQL|y;N*?L(#qZuBZFBk-{8vQ7nDzZIMU!(Qb!3Nbml)v zdRSUG*&YPc$(Zeh9ms5@xk8pfwZE% z?@kSu2A4VE;M3EH|1`=g`kgLEob+N&HB%5#3oYDyr13?ahN}2_$+^~lM2U?Z-TXAL+_;M z&cRqdfw)vI+;vz|vztgfCO&wX`IO!*CrPur`t;oXQTgK&d->8ci5=Sm-QOjZ!r<$_ zC(c)MP|KV|tr;_syt7e*^JBL_dep(@KSi?ZJf)SKPC7*)oEQ>D^9`l*Ol(vT8nYMW#w(OoUD0T|gA5k}IaFQqp{wc}Wyz-jT~Z54;CT|B1yLTSSAH>+J}f zZ8=mPJ@M5R2@k$+wKr=PF;hv4eB07CbyBjPqZ{74eHeN+aItiVa&qImGKg{G&T-1p zS(c>)vi}H`kLQy3nzJUkGSH*?yUwNgsm;J;f!YC3I@C9{-=HESq+Wv8kn;x52i+o zO%)P$ZUL?t`|fK*S1NPriW5J4h4v#(7CCFYiPaw+lO6%hw4s-g0^QaUxK~qEUU5vj zy1O1pzD)@#a_&_XeV;r2NS?s$A)OixGqAr%g9x4&$GFG!pDD_|s~>#H>1ngrrrcXy zK+H-9StFNh&52Kuj33RdEhnC0ALLnQNgHpVZdTZ+ ziW}9hkv+{~xkc;GE)P zY>bp{`36t$^RyggeI?;in7rX&s2;x<4nUS_c^YT&2R3@o{Y|tgLpBEcik#ajA7_ndRmV~P=)o%NPq>9dPW$Xh?Dw4=Z15zXUde>t{Hgx@8EcC z7WthgMlTE*>7JZ_R^)?<%-}S5!`k#Q=PGTT4U?PGA}|I_Wt2k97c-`UwC%5I@{uW1 z6d^(hZYJq6=5CY$GYoWgvG&}sR}0wQ-i|w%)NlCx0UM@^;Ruzy;QqWeh16@sP}Ts+ znQYUS9{tlSA%JX{4BW+P5VBTBNCXpLGy1{hPM40+utn#~?TO}Tn$M>Zt`2U=hR_{w zT*@aAsc1enK>u5;%avi!gq09lsfU9ds(_j3#T%NpfCmzz0Xa0c0MKrOk$={P95k-( zDXo}zuUr)9Ui0y`{(U)YHQqfBjmHM^_Lm0}?65yW$Cj@@nP$*wovf5selH4}75lX@ zN;txn$@tXf#S~R{ae+^=MO0SbHe50_%%ozDtDb5#9cYq#StDvfysui zT)BjcemDU;EMeyc-7(c!0t1^3B#nIJ8}uU^@77_HI3;g|e2Q!B_0ea*j_11Xm!JdV z<}5Wjxpbpx?*(NB$+VNQ5T4GXT69&YrQJgTEy02+gr$j@yRLVkL?!(2#z*5|Qtk<^ zaSWTEXMx{1IyzUYiTvIIgNt>Fqr%>Q@3NB8%1wHZ?eU#@sVyEhxZ)Nb)}NwP_-ChO zJg(AIAPVcYzaX4J>w8~Dmu|o(f$~Gwq23Fkkmj>Ov}MugewLJ2c%k8N*d!};M@Z`i z;RNr*jSy5Z%;Gmm1nd^@a8K5u)`l#0Va_rIANWZ#ZTn*@xSfR|MM;5k^@%7Qn)#-^ zJH7QR>VZoQnehnq`GU%VmN~dXv*GOK&n(OJsmp(gM^l&85?M#Se=$2o{*PQn&;5#` zKYGZyd1OCrPgRgAVLB;28GYd;=j8TQ`tUv*+sla&0wUvybm~+L!Q2z-@;Q*fX9;S0)skIZ8eTNyfiJ*@C`p`W)eZzRs1ZSz-jkIFQ|NC??bjPM(Wg|ZXk zJcs8OX>pR)y*V_(P$kLqy#$NB8j$fDjHR`BYUI|7?!x;6QH+-LjGqiy09}m3Rd1}A zO=JdWJ-m1zutbYmx3rxycyh)h4_K(mU&6Tz;~8_ESKof_qB3t)>VmXX#fk)zV80Cb zH({--BH&LN8=Kms7&@K4*oY4@SWa&Exsu1KjeeJ=Jneip)A^UjgV)55ZUJ2{@o@`dZC1X=)UZ@f9+7FBnICX|B_7mKu=EgdBvDO+n%_HDJwBG`t2he`B9a9B0S zw7mSId7kHu6>fY~qx#LZrLWt5@&KVc>Qj`+w*=vaY zx+EH>_dDoO@7gd<&V|V5aHs4~H<)FPs!<^A&&m*`BZ+I^;9Btk&5AHrAF4Q{;}Lcg zm}-DH8ptW_1{W{;wOEu==XhCdu6;IH`Kne9`c}owfA7kS-@Pv+q!RBdOGD`b(J6yH zR*bXo391)C9Kk(JNDnj3$BfOmVvOvmNXp(qcV^3Bi==8%%VT9Eez{;<%i=#2C*xbSnT4% zRNoH3l8bJ=LDu0C=6{|Td|>tvCsxvs<>%Cp>Z3m9R%z~Z`9=AoWM{JbheMInF?C?gg)E7Yd~r11Qw}1* zRMmO}tg#s_8~L4D(^{0dWYbJ}4;}2o$E>uhww9hB<)u6pGWKP7#XoX?Q(I4c6ICH` z!x`ND94Cp<=}tF{iHmO2$sfb>KRg)X$_;v>Dd5A)iO9zoikLdrSC6yj-fMM*>H+US zs$a^AIWr*hj*V^s5+4f{%?opPg3-ue3iF=J0octmSOWs5l;^y}HABBUaJaMwtesla ze;ZH^dQ98RO~py_ZPNZC^xmv*xDuG-Yr0Q-`B){SRm$J0I(T)ju06YwOQ zr}-IAZGH2zG4{W!CZp=R1rIhm?{%)E%Ubs@Q)3sOU=!EIp7mMZKe48T_zuV>nQ6t# zW-|Zsi67x?bT|5=!kz~X+6{TK=r(YkD*bPH z-b~AdBLYs5^~&jv4pB{;hC&a`)2As)^{;L$R)!yJl&!k(4W=o&%vlHRE`n#gc0r>? z3_kurY>~GBmd=$jD`u?Znz=CHYTQ?-Hzwf%Ck&I6zOHMiU(mfnBP&uqFagr4s+95qXC|!goe(3iAfFMJ-MR{1> zQ$z9?vM@;atqlF=hiqoLpvuVbZga{dcO{Rni?qYcwHxT=?_ya)3xN(-Z^2h0C|;64 zeXXTkflI*x=^JwXE8|^`n#TR%5^R1C{Wbz8=qi$bziR(OhF}&FUHODBN7!_^zxhs2otXxtDGJ=h~5(EVy zc^X+Z5qApQzZ1ykGzPEKpk^B}=V#im#4dk9YiGP|rkc2J4i+I<{#X_x>mfgj-exIq zdfjh8S& z8x{B))3T+q4I0d`ep(#|jHPRI~qU)<+Du}YEE*?jz>CCh}?ODNm@7EUlX5rY% zIG_SH0%my)AL-usB8AaAs z5Tq5ucf37#UA8K$-}^Vp=0V^25oxP5b)_qLM&K{APHB0a)fmSWynRKFBd!B31{h!# z$Ckr_*e~k)6_$#@CCV*+ye4Sd*l~@+Yz;PDA`NyjZt_dz8}eLVn=3h}w@qbMq$u<8=(Ua4-NwUtG+4=9zH|P^7>-10Az? zM|!WV8OoI}2z9>C3hI4R&rXNLuegsi{jEpgf_{)h9YK^_q@Tmi? zIw=M3XZEKHD#3FXOQM|luUwNH{ZwF6NxWs?fJ#mI;d#}>X1pI8bM*xG`uc~Wlqv4T zb|))ci23vnL$r2Z@6`wXW zA;GxUMfaoCHg+3ICPS}k<@gR_U3+iH#@4LAS_$HXiy#xLn;VME(-MIn9hz;tY81wQ zT>cYqwN54!X^O7PN#|`?pnV}`t-Fu@x`8G#4g!B;ZS{*Sjy7NLeLNT-dDG zFg|i$k7tnrMu$W1sC`IkBPDd zCyCWv4Wt-6HgonLk1Fggwp?~OM9cVM);f{QiDUF-UEWCXkM`+{{oj6E~!cMU$+%ughS~zTNZUTv&*#iU# zuMw>z*+pY30abmWPIbl;WnG!MXOZTaEp*tu%e&Yyl3pJo&jSsnMkFF@V_w?o6pJMy7jO{ShB_b%Zykpw<@Cg7#}Bh9b*8_Af`YEP*91_vEF_ykiQO^!nz1vCS|5_KghD~c>!BXzUW z^vB*#o?IMOJ!wl}`eN~^Hun{IU-SIHv&0m)KI)kXYrY`FLOI`bDP}~gj)8OqdTs4h&a^B-7p-9vb0$`8!`6A+KAn(iW3^}BdB zF0*2s0R>*?z@1iRc(G0?o+H9bKtA5@pQaAvY(K;g?0;q{=%)h43G(kB|MxNIML)3u0f`M%!`; zX=~{A^C6-ad{QNHMb!?+G>?n}S%S&MOZ7qpHOJ;oKpIeZRNSb!xBPZjXPq}3zL6?B zwm9Be(f7@N=?PH7WIJf}GC6Q{FOa^^nVmgF9i=|2UKq0kIid^I zf0UES)=Tv9pSzzVS`^1Bx<;kkWnE*CbI-OWdtMLC5a~7co{vaqltoVR3-BzOm~zru z99P`(Wy}v=I^8?GTI=gAU?!!FHV#_XDw!+J*B;ksWGR7l^(AX$vM@Y@dnGa64oCMRl~UT;d94M<3w)GjoX?K@*EQ5Q-eiLHL0H@%UDU5 zc8~{@e|U)j&zY)5`*N6Y;Ps1aD(%ZN6P}T>m654!e)#9?tC~O;#4W%f82jX=93$PG z&623r7|7C%GD-#6+%5L{#+l7$qn@=kvJxGg%2lNy&wP0cI0IsJ(G*u&@3H*rI(Kov zjNapLNf4~k2&tbk5(KRkH*Zan`$F~Akt=gD?L9AP3v1QWFo6~jcfm}1ev6OU@bPl8 z^Ky{J8gJTr$LLBC=VaD`BVXUvO|uIX>p)uh)*G^BwA+9#BBTm#i zBp{!IY1n*Ze%4RHvSj!4XGHo;-mguKFge=4)jo*0su^vHUU7l=o~2>EtAfVPJDF~n zAy>U>-QAy+E1X+0REo&Bn}7z9YZ?RzOzb`}2Fw0 zwo`0Y1ol-;UNm{*zZV6<}4Q?o76a3MMmf*P~C(B@`bd#;ABcRU}w zQ+vYzbw@Yi9lM)teRNRcN+-+0oaUwXbO%GLrJkJlmEBXZ0jy>IYp8k&i*wD;9oWf4 zC_*~oR0B%3dL>LtrMW2NP3+YBQoLy2VUZ+dia0(g=LcO+;_)YmfkBZ%<3DSB<829z zg3)DC8)vZgKOmO9k#yfVPWR(}ZN;g~buFuNE!EkRS@Zewzq(lERX2v1yCcE(A(My8 zx`?06ChLf4o>Bp_;rPYOTAz)Fj4!{jZf}cXg&Mo6!#U`J?m(U_clp~{(;dJ#=;!y$ z&O;m_Lirf`q_;ZE{qQu~rsFCHc+-_oWt}x|X7byh(rHE7J>SOn`eh4a8&owToqrFU z#Xdg`_odFflO<@}!_JPkYJs|*z*zl^ znDPTAdnAR{OXPq-pw3-a!&1OKhbvJ7HBp{?m~MHq6v}+RTA-$E-2usM?s{&Vls`5a zh%l=ZcF4d6-;fTXrPmmGazZ&C1g|qQRnk1D{%v9`iq zvURyK>o&i~eelb?7SK|*s+;;DlJ8905w_g%rL9 zK&I!uyU!NPINi5yrl`81v3AR-JiKb!mS2)5z_Qa)!R?sVk4~~A-PnMFf^T?WZT!o{ zCne@)3uL(DpTpM-vfdp9BErk}hQOw}QTL?kIu=4#>^x=T{DR@~_{@(NS#q}k!nj+& zeN$!m-l=jueobG{(!C^v7SEY}!c}HqpNXAW)aI8bv`^bhq^da;2b|3CIvf=>z3ut8H~|DXOq&P7 z8y0gs6lg9Y_9eT?G^&kIb#SJ~Th;2LE>I5mF9%x~otpH6W zC#bP|X0;f@lze--?XWfl?@HmAsd)!Rkw^8h8k5DsoLu{V*cGBj#zR`J*o^+YofZx1 zwv`Z1HTl&j_v%$H!2n%^Cxuv7*LF$qj+t;DL+X2^@$?$`dT`R;PeZC(AHeHJ)Uv)C z2`hQ0bp*9C>YmRtP<=c-(s*V#T)))~QL7c3ND4+VzRk_F8z*{Wcj#)XU5 zzKRbrR*U;}09fAF=$py{ocouxpsLJ#~;(_o@#T0wo*`Q@dvD0Ji!0r-BIp8R% zv|8mJjZlGVIHgQ-+{<4U)CKXs?U3!pQhhdS+s2d!*K;b@=bOknx|f>u%GyKUlHVxR{pHt=d9}U$7IK=nD)7?$P&U3kqwd9b~)~KHVZVCB5~!(Ij&m z5hLZ&39~Tobs>C_@RWvGEN&Smb0r3;*SjteRb<(dR$}48iWWm(&fJWUM4bM~Yo6Lf zr-XfEbt@z5?`!BpA(@MQjT>kt^ibc==g_glI=fKVw@iCeX=6*q)+DDR6GfRGKMXkz z$$YnQM>Z3w25Oj{dS0O(OZ4`>{x`w~z&c$K#k1=0%v`fLo&=w**7_5p!<@EL%L-KW zw_gry3fRRm+RSf}4%ymFeIVQsu_YZTSdQk6Cg${dBE#K!A9oEXN~1W%|vp93+A_E$6Yu2qv^GqfNM z2zg~&+x)&I_9XKtao!A-8DV_+!SkP=7dbm(fde4Aq2&1!68+hwK7kijE@{VH;ZoAJ zrMz{~$H8fjSOYCjWB3`~O2^B+CYJ|NFy=Ugk!a^#?@+}4VWXwxquRACIi3L1!IT=Iug@#5IzMM~U3Ug4T7ax!B;RiM zmZ6WQalkdO5%ML*Lbf3_->RQFXSH~W_&S$A${J2_k>8jk!fo0eEj#k%?=p=!Jp7>a8y6Lxz(CGzh`;a9`4EC!Z^S($T$L(Z)%mQ*g?(9!lZ-tZ?DLPl zVRfUaNQb5jNFdbTMafny8H^aa>)-pcEF*d8g6>`A2vKBoHoIQ#$svZwt={BT5xA9E z{6)Qyg`f&U9I=6H@>XMzqwy?S~Ihws-IPm zBfQltgycRm23u=bI#nD_gaohrTqX&Ufj+w~_gaq1sTq$Djde`y@xYoJOv(QdKBW@j zJ1lB4k8+bWcony`pTuCq$*9f9KOnk)jSoZ`W5HL%IK2*Rzhm`IkQ}D5-;EUdq6Gov z$s4P(!oKH&>gKgipIt(qzCr5s5=XSUe;;B?(1)iU1x381EBeB7-5CnrPMOz_8;RL6 zef)VkYfeWjm5`?naOkeS20v``Q20@w4puzmf8+4VAS^nUaEpiR-OuDHQ3fQE#)=G@SuCU9Q19*h1m4<9{Tj<2%O4_uys$zEHy-<-Wf*(|E& zb7&#JoC6N3qEx!o?CVpikvbPq=fNG(|Md_$T1LhIt5TViRFr>f^!>GR6$ znAW*DpZ&$^KNoJjzoBjzk{%_pC7gB5b*>$DJ#a;bP-}&M-`KcuvQm=E#u-(E)T3%J z`WM)?#L_=K1DwAA-4h~@Ju<~AV1T{pigD}JREtp8oPo=uzM}|~cICtLf!dE$_{8iS zMvZ);8b3;@*&FYiu(66^=FCyoTE)3!^F8nbV+>KfMdc>EFu$H@c2)z(^bm6c*I*jj z-c)FJ&chy$>dh83O}i!P)PLrYrc&tn=@2up(6IkuQS@!ldoje33%fwRl0AnbkIZO_ zfJT2u>Wr693rK@E;6tW-UfwozxTL%Rj_bS&>$E(uUTwdrwMVaa`&!=*T1c&NVums& zTDwWRc+R?~*)=Wy6C@!v4<2j&(OBu7(j}Ga{d?PSz26S1JS!o3=P!d5C*~+zBA5(> zri6!LacQ@6_!xn>uSGI~bE@qQ z{PNJ14b5kv5yg!)9~<~`ljE7faBzxD>W`o9Qj33#j}Q{6lz+4~uiFqhlSyy7^6BCu zAD7Vl%Rj2Bz8(`Kh#q8DgvXvqh1K#1YIM4myty6OUuPYA(yJ_WTOR+tai53<5tj((L~G4{&-3K zuC&h%m_$_GJC0Cs8+;g{5E>o z%p4Y9Ih}G5!R{t1hl3@&WeoXb;%k$!JZCm>O(cw`qKIw*n2~{Givj+T%m<#}R@G}W z?c-7%ujB;nVZnC8L-$?{lvcT^^8v#0q5aHWfU_ZN>PS>H9asPaGI5)t78))nV*R)_ z-)c|2;7#89$2{B7W=ig zSh8yE=k}?(srBID_GO>_1`Y0v_5=;fIo8p-KZ5l!>af9*Gi*($raAm(M42MbM< z_^Fv(;LfdSvK`O~qO$(b-0QS%26i3^G+K(`DNj((WHt1=x_gqka;fw$kZu?@`mJ^<@$K|X z%;ItRLyl(~$F;oLX@jmC=MorvnUjBdV?R|I%!`P~-}LT6Y+itTYs*T>&)p}fs_udYY1)L9cEzQFBzv=<^5N_c$vzKs-F zs+aj7*FT`(@S>%;sppyN;n9-jgz=G6JA<}ZA{+=TH$q&M4);5?N(ZI8_1sMM4Bt>& zIhmF9Kf-7ivPXg4I2ryqWUq6*>jsp$CMw+hbyocX(_hkp-ng>N%X$jlFy^Ew51gvNjN=`x&X70j>#P%HOm!G?O$R()scA=i?4r z_%{%KYCF*hOTqmdKQl(nO}F7bvE%ALbSR5t=-M{kYUh9x1OB#ur zdDuR~!YhSHi5%7sa5^^%gxPi>a?P2G4=O7Ur*_JhEQ3Y1M=-(N7Eq2=H+FN7I7DY4 z5h{hiy@9ex$FWb%NZ3@Qna!$)U#X$Y7A&8c2Ug67zggxF%>Sii;B>jUlvAi!U4&Y` zFb2@Y8inK@cPpCli$@Uj+BOY8*PrU3!6Na=s4`K5!LYlvYr$dC9nYuaA0o%r({Q|j zK6P0Cf5v`Re|g#jN#ozUBtMW4mQJbDBrnz7jBAlNiee{54>a4_S3&Z6whcNlELb(| zuLX!jjWSNx^l?U7@xc+T@#BGPvjK`$fl|p~YK~INx0gx9qysy0^QnuGda(5gbU7dB zZc9~1tmxAo{h5HVf~|toexFTzEnV`!mDbhrBA=7Lb<_h*lQu(0yoqJP((5W_Ki}X{ zN&R6GC9n86=f5A?Ub?MtknPe!$_|7@g;u}AXEv5wzjG!u#n&{k;@WI8V?6`t(Cvr$ zr5ERCiKGV>QFeSEt9&Jyrd!X%I6rJeaH>zQUmzhVd98Woq#iuScf44xvODF!oRJKvt<;Pm zTg_+Tb<7VqF$OOoXPk19t1c8ojs`mT(4rw=C|4l3K&!NyJ-=-C$s)Jix5`nNN7pb+ zEL(lhuqXD}kk#JmdFW|1m6?Ug+O-41n6h{1DL#wQ?s!lxYRgz$?m@yF8wt~})ILtI z3WPj=FsCBfr}9;--|MUTP_vTIm&F{GkRiZUL&XQzqssH^$YV}2BMnZ05jEYTQznvH z$z6Lrx5ZMe0nJ_h%AeVj36qr!j;`ia)$;EfY7#(mt-g(hh~xJCOCdMH6(-Cd*RyZ8I9XJ=>U+~?fCdJ-W|QPEBpm#Yly$W^}RX62ybXVtd?@}utz zjMgxHt9oHKyL`U|O?Si!TAq_GlQ`lEE{N()Run7yse~EJj_=ke^t5%VEFUjfa03Gs z90V2ajueWVp&V!Y97w%3tfJkbvd7L(wlfVOM$Q*GBfG%O_H&V7Es_OgY44CIp5dTf zKSYJxKLCyYumR4ypOKEZcD7u+JKy8){-6e}t)nISW_&J!3xo3MO&0WV(%kQqBBt!( zj+4i{r6bY2EOisD98PTdvxCS#{@_k+@s~feD+gtCir0Q`=!5WIHU%Qyh6PAT^2tRzfR6;QST7j0IR$RtQGO-Cj_=Xc$oh`z@X$VAI$VEx>PvuYVz)_<9nVj%vdUOxrq zWMH&D&tOtSJN{v33P>q5mM3*kWfOPT?ctc_N%iFf4{JyyQc-1+-F0E3Po{IsjWIy= zZogi@Sy0nC&Qz@8*7}KwgR?KFEzdo-RpTe9ty3=nJ<9}~6KvSs=@H*yXQZ8W3KboX z{}I~FGl7k+o0760N#^+U{g3l*uSnS7*34Wqi$cuCkO#%aOV_=(LH-E53*T98`Ue++~bp6i|MXQ7o)m$M;^GyNh44@)(Y?D~y( zMYMeR&e|`HCskc!Im}xAr5AcO7U;$oP1y@TC?6t}aj#D8_T+^p7TaPpz>72h!Cv0ga(65;Vrp;_kBED+}`~byr70>E^ zC~Uy6cgZ|@-E2oq>zPj-qq(((0x}JqrNw{ocu=R%v{W5EJzVqZQ(??veO!P|WB9LC z572m}meeB;Ql3L=<>7g6oY3|dfr8Yl(UU0iaZPG3wESGne;?POl<_H;YeDCB2d{MV zxLk;qa?2yhZEu34(ks_88*qbN{OQ8v-;BYC^<$BX0@0Pn^^wo#;TLx*yQ~;@6QYiy z4*6&|F!F3?LmCaEtvmc$EO__B;qa33ZkmUA{p55Cl3qgY9Rw z_6Z}X)!?ze3Hb9aGW%sYYBqu_9Xl7Y$f?jpukiD+`D)UP1yn)(pi{na__)9{*|IOG z{Z8^gT%J5>A?c!9{@jtI(8afFvJ;bg>#|C^&Tio!fCmDQH@2tk4_YK4&S$BP$ zPK)f9C^b+t81Yq(3YhB2B%JPHU2fWXb2qZXn$sWG6KI+TbDsxtTEk)MCkJ&fwZ*YA z+2j31hwHQ|2&vyyLo%%wQnoK~UZCNzbkj5QkRx3n+0bm89ia8X!x z&nigPfndR2L6vqNFDrqL(o7dNdu1TpCpn%6(pN~h7au!j*>cT-?7Y4^pM|Y6%hkQe zQyxHNSd7im2)a+SKX`~75TtC30Ma@342h^bQgzp#WQ;>KR1~!}?6D#W6QX2Kn~fZb zpVOf|)<%fUXuMC|E|rh>OY~&ejFo6Y+7TMFE8Y<*L2@o389fcJ(*c@tZAW}wrYtP| zIQwnw5*Y07Hph^jT+4#=b*DC_GavR&{n?k$FRZI0 z-RIn@vIRwlW{{v3aG*HGmxw?Q%Xo(rYAS>M+-Acz7BOn-dn=p#3lQlAv#u7eIV_?g zn4k41zPyM8wjT2tRKx1+F69h`dCw^8r4LEURZdAtb1EiJxf#yTJ+ds8*$J<{xJx-G z&XjyHbBMbOV&>pgmT8w0(YXX>|9q{+_rp>NtYuyx3v+YOfB9QlqudhZ4W>&2o(8U^H_sd`M(+-IQmo3zcc%D2qXzwlO>0RCe^BXGZ1?|wAK=<{mgD+R_7rBLGNQrxWreu`GR3@a&p5S%LfQ;E7kAx#do!Ofd#_VTW&jX9%Ld$mUpxlv1Cue+Aq5Zs9 z_7tMpTsN{14E^RKa`e<4xiU3-)(Dn9?W}T7@n+n6)1g3y5 zixZioSRGR`-$%3mhD-UD6B$0FtslWG<6`m#lj|OK}-#JTWetZmLTeaXZ9m@0517 zKO2G^P2$E-l!{wSX|Vmy#r+pLiM+e8oaLOkVa^<27ccAX3Zm{(xNFN-?f&}li9)jV zhEn`b)2WIFDRdcpvaQZxuFvUS9PtWWMutlIXPEEODN#`Q2)f*x&2=qf;I-Qp7B2;p&;f{oVwLinU1^8$3G=EN?QM+PuA7I>FgG9QJBCy? ze>GgF71+l1=R;SG6Ll|>3*~d*G${zY#}W)|9Ss&oLiItAHF-4pqb;QC{bO-B zoo>=s`)Ayz$=M%K@%3dsF1`kl{BHetanS&;mwkhWzNz35Yahf-{o>MKJhZ>@pjK<6 zu@PF{NJ`J5?5DXsOvDAp+~lr=6}MzSLHZslE^sPZ#dU=A9cuvAj>f6I$Awo<d@wqy9*F=0R5|%Sbu0A%5=#@nyfut<)RbU-@LNB{_EVl`bxJVbv;6|ysuxb}ll4#7n7{rl|jmVF5#wXx|dP1l7@uioeYz46~!OdcUL|I zL+$2wSe1y;M}+fXmbJ&u%V$J?gKt@zXv{M?<*0ZeirYwC+b?A^+UD!lIcS7WuR72@nQqNh-Ck1syqm#sdqzDl%z+SS<6aJ+33Y87| z=$_{%3`&yHJ{4`w*6MZ8v>9uYF;{w!vEX_CML8yaWAfybWh3yYwU!!BfONy$`ig=g z@4e@EPy4uCAQ7qJ6|d{@4LaBFRACCnr5`UTT1fE)==m6gTbFz=htAc*Ym?-lua4;D zCpGO}(!M~i@}!CykWmk5cs!{(xtT}TszGJfAp*~rEcqULo8wmijtOsoVhjCib9;Sq zdtyg;9b^p{$?BVF=9_-v3sYtL^TnhSqnmO$Gm|-U(nLIiVJfy;h_WrF$_T>!Mm6J~ zc^RQ<>c=XulfEE+GHfwy`tB{jN|7C9Ngs zFr~>9R-E4p8cjL*jt((2vsO!AN8>`WpxzX-vB-56LE8M^R3G%d#~dxNUd?Cy{v^xO z@2&L(|0q8AOy?4>J*~U!Kl`VY7x-5YD)kRwIWBo*A&Kwt@bO@g{^HvIpybMVwtX1m z0DunAyG>OQLq3(=Fij6me0b$YzoN=D>IUJMeRsUxd|Q+nb?6|RS?vMIT4QY6XXggV z?ZgO$o|tLv_woF}`DC^iHqRp+I`ZObZUWS=pwO;+PMDLcin1T$Dm)!b=#BYVIVNjsG(E{4rNk z#Va{*JdYxeB*@gM-SvM<=*m!>xntEyv*K>^b32GH$6K0k-q}bl5Aa#YyJdxc{*44V z0x~)4-OJP8J;tz=$ZjAM@y>RrSGI|ZmVI_nJ%(N)(H~7zX~;J%cF(c5;PXJ*wdBFS z8*m1Yi*I8g^3Ou6_VMHqL}*>KVyO|LDw&_5<#8NQ&jd6{e<~2vr1mY-D4{kke{-U) zr3hy~ZpVIzq99N1!f&h2dRX+nAP2}EZ9(#c1Ki?qXz3i|H78)5MkiD`FZ$R6vc4Pg zyWOqKP9}fy^GAXw?F&5kCb>W zlP0%PR^nf>jTXv0_9gKY?uZKtq0CT|h$+E}MsF2Mr!oCP;lUYaq{Ac*hy1pw55_{- zwe4U1_BPQ6TwHrA7d;`=lsVHeO#gFV01Np3{^=2ijObbBXk!Cd*;yz{`GMh9!hbSQ zIU)r30)sKV5#Y0*K0IxE>(xI%V9#6d->gw z5U9`EVgQ*snEkTtyU}6)LztarPjR7l_1x*e_Hs?be6`$J{&Z`kclJBQdJzAEz@?_) zq9mMuYT?8aYQX;L=0vkEz|ouO(KoAHsYep} zyyE^+=l&c<3KjdkO|fv%f9M*9kq_{>_qSMNo$4y{*klDqor~?t%{xm5p5=D^Fs??O zUMrj#YAf{QPL(Huy{{k@LX1CIgQcK0w?cagmvb1tj&OA`yh+r`PC`XK$L^PH@wLl? zULqE02I{ppG8$6`Rj%75)zMwW0$|idx|#yLO<-O5HBUIE@dfsRhURqA5_i^GFj`!X zju;YU5zeIj^Z3!bGUhLhQo3N?&IZo;+RsKsYsUHVg+bljpk4@ZdlKSjEhF-myKtDJ zTaKdp_QlUudrIC^)oV|B$!?nNlpHdo9gzHnyILjtQ04GR@r7!sY&G`U0n29AH{bJ7 zk-rfXk(?eKkazK_-i?=U-#g*Vj=|~x&4E}7RM1-=nwI5J8y0gHo(9E|w6&^O7# z>~v;3S3IBczxS(J)d`R>kE`)64Z5Bg^QnPP7J@b%HES6S&Xh-?#a&@CTH1B=K6?=!J9{XbKOql+836w8vfP7@un$G8%x)-AKB9 z)ka>5ffxw8ZJK;`pSSb|sul4xo#iRtj_B1Ty|v#5dXvBaZf1sB-S_aHx(8?XEA#!k zjp#N;*6Va+cWQK$Wq0y*2UQuR|2&yE_BthCywAblY`^xrC{TQLzPWQAvp399drvyq zp=G8>3#}vNr@1sOMM7`e)p5vZl>1~T$yVte_=kF;5ian~_yG z>OvJd-@*x{x7URs3C+(v1Q{y6;`UtlG?8|Xp=EAR2x~g-9TbrM z|8_)Y^f|Xo0+DdKkLF0WPeX4DyZ)eg9@TBs(UEFnxIRl?IarjtBi*v$mbI!RQ?j_k z+eDl^oz>I6h{sEMY!;d~YjA><6Itv9zb57qqE7W{eKvLUiaosS|2(;Uu=RNwE+baZ zDlujylwbm{P3Hn}eeQdFe$D29!i9KQx<|E2J6T=Fxz<78`r5+dg7IK3Xw8GXXpO#@ zMK+@d!Zedck&30dy9PajnT2tDy33Fz(z_r-eWKDHXMB{rgAB{DfEaneKSDrlur0sP z9OktHR_-^I=-6$2iJ#DMq$%&S^QY5%6 zKdvMRdTfQ0av-@ol#$}M{{c)}aeK-IX8fC(L8s-hZxmpW&g+G-D`KZ^j8#v+yPVC} zLi&%L%ywSBy`^w*)0E>Mpw&dL#dEIqi%CNDC(CuLra)S1di=g`{3Qxq%wzIUr7~AX zozY~unX+8r#Nfz1>EnXSGzz|c>Gy)9xB#7TndFPWoymXu;Zo}OWBs8&$hb`@A~SQS zCVgMyX7m2`m1UDt`{_;UZMBVg#woL(Ru4&OeidM3R2|HA#XPb*Y~cm2u-Y0U7l-#g zVU~ceWLM8oIR z#(7Vdu%x&nfgIuJo@XB672DZOo-GnB6F9459dwH3p=sxvG!fl2bwX^T%XAH;uMC)d zff|9@SL8I~+9~9&9-QK_V{Ecd`~RnC;&T+GDrhPIUU^TAVF&YrAhQkokNv{6NE(XT9)5F>{OjrTd`5y@L&W?o2#Y^I zOgALlfn)zmzJo-5@zvXT&p%F2=H|@JsN;K{2#$|lGZ>zNg;fhD`@OOj$Ucbo)ElG7 z=9m#Z!;DIXsiOPEgyd1*X49JZgfG3@C~fbp?VdYThpev#MYS$4t+9?ZA!V)ZcFqeH z{9=DuZNeCzi8E@CWm)KnTfE2|?fT4rbsL;+MHffA!rsHkF@yVP)b^=d&=6mS$*^a5 zjbp@+PYv&cUMcf`I|Y;FG6}!x(!1*i3JrJE3Q*O(St3Px_H%(bAw z5Ch?w@NFU4J)vBSv~>D53d>uIiDa&~<56)?(b_&@&v56u{_xRZNu%7i7SSJ80}jdhAXy9QZkF7v zhu3uSH5gBxhZTZ3%WJ)iuM6Z=|;+y^a28 zL?>IA^I;&elv3gaVV8j{YkraeMc~1QR7=s2_p3Jmqo#l z{5au}avX=+H9ue#fAw{m^2LRWch}OWQV@L>o{uxrArC^-)H6EwOCkg_@rJK;gSJ%d zfUgsdgT@$RlE;7qUrhRw^&MUkxoPYk<4HBhX5Gef^0H7+^T=6{W@VtxD!F#wWgxS< zG=?O!++=OCKfB$i5=lW+rK7BO%U%o?35UH5U;4g&hCTiyla{bWo2;4)duOMNxm&+q zm4%TG+z#g3#p^L_7_M_3*GfknN!oh9ZOvu>?tqE7%hXfKPU~BjteJQnr2d5ari#y= zf=Mk-7Qyus|Ju+B`rYQ*a?$cF^NT`L_n8mNuLu^Og@3X02QP3`xG&(gFTtL8Z5v5TxC*+=CdM@R@ru%@&p}_ zOl@6S%eHAU%!z?Lo0Q@(pZ?rzXkKJ~ z!((@+P zs3O<29bkU8k|w?Z4()WxE2>_zaug;7oe^(6H{7l&jU_UsZ*;+Ti!Z?Wq_22qff;Mn z4-IUbF;Tx$9zlQx%?>=8|1s#v?M&!u*j0jK)tz$hINK-PFm1nP;;Go)&quoE+Y=tl zqh-SVbsQ995F4MM9SpN@f16VtBJsRfx6biuZsSbdk@fNV#8#WpLFpVOOie17VJ|N{ znAzbQlz1O^Va*M!<1MEfR!KL4ZhTvRcK+%B!zikYVhDeL&1RM@piAffa#_?WeBnqs zIDY`GA#LviS#;dz+SpLpjjV_>A_1cJm&di&*;6;ohHbIIiS0>}V7hQh-xvH#!`Y(D zM$p>G-IkW|@=yD0T?)0uX~P1W>Zb`tzYmWq5%9kSKulg7+|fGDny#5~H?|w^_hD&o zFuwf9w10k&yn-3JO2ZcRAF8fabBjFU!4HWL(gef{_)>jFw3v7`=$CFHX=j7PV%FRU zx}xQBvhDU0k3~DuIkXJ3>dd6}0|m-v2sV@{ConD)MelAAx(^^EI9ACgBW9(wcI<*z zPFXqcwne|=Wzt+feCBb#osYZnP)c&fU6=M`ZQF#KF8(VEcekjENm%O;ny$cvh|O7p zJ)bmm4r92h8%`(TbydW67gqUak7=@(fYerlL+ld5@ac+~BL(wqxU36?oV${H<<;c& zs8?t4>3DSEH)6}DT8b!l-3SEHyah4u+Z=!u;(4e=#kky-3H6secJnPywg(>=P(nw^LZ*Y4UR@D>*I&largP zJG`stPEF{Zr}!29?Tm4Cr9t%CRwG+S+N5NDj`#rBg5%RBiEmbKJ5ti{s^VX(#}U~Z z4rQ&v!c2YBx01F9@RDh88GGEg+ zl!M2Uan8zzo7+Y#t;)l|O;6iGwk*?^yzd)`YRQDDuA6xpg!>X>D@sdT$T|?8Q=!t0 z72gyIyN@1GRENZ8j=M9N^^{je0L*{^MYDJp)5$a05k0raVNpMEw%1p_iUYLi5<}fQ zY1A^*+Dk3r*r9wFK(%};)P|B(?E413lVqUHV`@^Oy}l0vNll|ix7Yd%bb^SDF6rHR zjMr!@DVpK4qcP(YsJrf9II;42M)~k@FTnX;lm@$EfbQB8lXV?!Dx7MJnP8FnU_+kN}cP8T{VH+iZ@f9tOqUu(ZfMg7C|+|{|UATZn2 zb~;(zxA%6Oiq2~1*`eyw2etj{%{tn)w_}!5K0#0uO*8TZV=WnaF~c)1dk>BC&s!kL zDO*L8HK?=JCcl?K2&zfP6!qpz?0{gd>tO_ptd z={}YN;g{5q8rJ0|UiUHgLp}FOU@dIZZlZiAyyvywUHUNOH7y$%Mq9c7n(FdL{?|BD ziM;D(%S+1{;+nwPP?J(nVL`cM;ED#*w0+4I)T;07bo-E^L3MIAFg`5p6*zb^POBi_ zMWd?H4fNR~JOMsq_bn;CLw+zYVr2=kz%WZFQ@?JTl`u|ZbhV4)KKL*r;rT8WNh7Lt z=9Gz!KXDdU@N=OYY8v1w$Os$0la&P%_9=-a_D`%em=}wB zTFih^X!pTH7lkz>m_v|mG4V%?%;=-PA}7Ga^><{Az^aycdot+uo^MocIKK?c4V{Y^i)@ zde$HCoyya^y61Ob_RUjA@=e^iY%qwFP#*k{ly}Z)zD5?DX*IN z8n0Py_0~Lm!20dYZ!=W!0l0U8~=I-ePr!6)zpT@$N2I3S~k^$U)a;qi=soeI5fxgpmLTVNe zf7`#Kshr8nnx*9?V>)t+lgQQbQ-f*I+ib#a&%|G9TLv&^DzK-jnfDh5BIDu1Vit{ z>c1K+)ssc`&(?pF!d^X5Ij%_AGNg!8G=V$$+Eh{2X5mdznEeA@yXahp=;GKcvmeuS zTH-|9tAb?EW^y%;!Fb!EG!l-}pvXvJFIk5Z$Sjn=GvHx;EaP6ACVWkz#aI%!XxI7= zP(d;KD~fzi7bn#LDUR5~=y2&UB$7PCLQ%$0;1l=Dz-joZf!X5l1+T$BfDrR8fsCcx zF-C7Siu|BxMTs8PM|<$KMh8lT3)i>+o(CsX1OJ8t_hV*1Qp~PYXvzRYt&RO7$(Hbq zZQ#aB)?TyAzDm-{KLFCAk*osjrA6DKqC17;pr{Fc=a(8Am^@!7B}-qT1;$A>YiBhTh<^ZHim?r{O!?As zV+vxQw61ry&v(Xi$1KB|#17nhPI-zWL^>W*(DvA>#3^r&^2wt;1u`N~q|y++LkS?E zYkQJiN-{jMPI;_C>1X*kBQL`i$#2nH@C7{ZL}UMZ%)vvxo%)1~<)LQ1UCR9p!fa;# z4`5BHrPllub6sH5OV-ujWI1<}e}IDgbmZ>b!9`yn zVl`iPUg;{G0k8B(uGQ diff --git a/tests/akvo/acceptance/images/project_photo_spring.jpg b/tests/akvo/acceptance/images/project_photo_spring.jpg deleted file mode 100644 index 7277ceecb56aa229be92a42c669dca97c62a1c61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42127 zcmbTdWmH>V^fnj>5Uf~nf(Hp!+}+*1w8bG5hoZ$Df(0q=Zbgf?xI2_mthh_@;xE7V zKkJ>f=F`mFtbEA1C+F_x$d+gC`@HbH2EbF6SCR)HAt3=$Up|26C4dY74+|Ry8xs%b z6%GMD-fL23a#CVqQZ9N1N@igmF;O8NK>h133XfO$RN559T(uHsWe7-p-a@ zCRR2U{|$nKPe4FQMEZuD{EdaQptQyR=j*u(fRB#Ufousxq5~k~BLVS|p8EjQ000u| zi?sg<{C{0Y$UqcSG!QxlCe}-bCOiN#5)g=t0z^ecL3!!z_i`VAf{#i-%O!>OTFVSX z=R(LGl$eiBFJ0G7q&@u?!ej0ljDbl^LP|!?z{tc5W#Q%H7Z4N@mXVc{S5Q<^*3s3| zH!w6Zwy?Cawy}lTxw(Jx@bvQb2?-4gkBE$lMkFPtq<%?D&nPG?DlRE4E3c?;Xl(k{ z+|t_C)7#fSFgP?kGBZ2(bN<)D@5S|v&8_X7-M#&Tv-69~tLvM8w|D>HLIME)2iE^V z_W!_z|AGq{1qFx#`VSWpvggYeh>wCw%Y{ZDr3Er`c}>S1gia`(m|xe8LC>T8m&n|8 z8j~2pyUuX-AGH6C?Ef9G;QwF9{tvMK8`mNL8;JC>ctCuB1mJ|ZFjtvn3_02uimhxc zc=gavh|OFOElH@QqH3lj?;r`zHpiI=6+9W4LeH7&4`f;%1dN|be8k2;pvY%Geo;u&E7jndi}_M?gVe9m7!7t)TEBQ~n5=Mn&W z28g95zhCl5R|D4{iF@5JjT7N6u0K5kwq8+xjJO{>FGRcx$q^fF8E2Qe9@03oIDo#| z0{&~b{Gawwu$Erf)`w$%-GXy!ed;hU;)uiRhRvT)ml_uFwkkY z3T2X?~nZ_-dlzRq0Qxn93OI%pDw-_ly9GIc_|hY)CTuTzChYR zqQ0qUA~WPwzlH*Wo&k6g1DV%XrxgCVn;O4IYdecnK7FA@QL)PF?SI^e%0*c zk{hr;@WJ-l^$2{%o?ZA2>Irsc$z58%3>b+&M)xxe==$%T1dL$EFb>w?Nrb%8^Wa@5 z9ub|anzsJyqTJdWr;Tpgm6*)7&&P4`l9Gw7V-?J{xFftdc*`#~tCz@h{u6EfYMH^mNc zn_xa3qD}!)U8d82XQrHLq3V4Cs?jz~`RjHFh{3QtHZMw4YCo_1g;q_7%xryP18vHK zZoXWUFl`~VbPMqYX*lgF_xr(O*<^%1QR@?S`QzTy9WjII?B}dEu-)i37iRsZogTQ~ zY^#qMzqb0(7Qg}xwi1od7B7j`x0s6a-78oR@LG-bsu->i_xGBMzgFkEy{Zaw=DKkf zixpIjSge+(E$`r?FtHpmSSTMi$khRD2jV|1VUFPxQ7P;yq>0&TMZZ!>SRKa~H1E37 z-+c!B)R$-yd%Tc2~1QG-JGm0LIQ5CO;XzqEM)xK|AXiyzwcA?##*_V~B%n8bTZ_y}H2r0r zzmLnm&ESSza0HErHVCX*OK7VxaxLh%ouE?0mldW7DOd-?+8dTNHA-HAduvbpVBRI+ zypH4GAvP4?13fP)RdDR;oFlIrh`GaeCPWeHGd)I(9gWMIsZmX>rNC*(36g|%XZs)G z|C`Zd-o??D;>}*-Jr#Wh+*PnJ?~*{7G6vf*-;F+>uAuCl{}Q6W>590`*-2;-ZyXc2+&!YUL;ivD8Q_zTgL{T4-4o|>p2S<^K75yD3kTxIQ3=>)iFDc&N!C&|~750u7y!S#ZH7$yA6*sdsU zvHpc$x#;ZP%T!4J$vqcXEAHS~5l;P(TxM*$c?zh@Ws47ip<8v5T| z_fz5xm=0i~6T&|=I6a@-3pA94dJ~#=!kfByMU+&lB z@>Kpq*y}qyV3ht}1_v?w@%s{Z*9^ z`wtbe6XAb_-DbXU-YRwU_#oX*cii;L?BE(pN}ay!yQC8_H$^Z4%_Rdqt71`CJVwmO z<~FBIO#d%Trd^Ea2a7YPr61gFwv<_JCck;8Mu+&qY3RTCc%V7{cwi01@eh6xh$i6~ z;H7=~46yar!&Sd*Elgum{_t3#wt7YE2a`gJ35yc&%}|@`z9KE&Je2F{IU!t|Ta{>6 zR2R{5rf!R!8=q?>Em-5&l)u1Be0@Jx&vSR z0(4W3(+@B8`x9Bj08&lTTU-Z~-|5H=Np#Jbu#HLu?!l5)Sa46dZuYg%R(}6r5tnc>Q7wF?B_}dK5Oa;x7Ghr$EJB*?2O z6Ff~h1?gu}Mi$VzU$mYeK*v&3XB&b)IiLPrESCpgvL>pTs>9#iyRe)Fx7tR?J`0Qq z?|a&*7;Uk$BijUiAG?2 z;Vsg6OdBwEy#3&)l zJINat{S1iS2xNGjd%Ghi=7@Aisdr&=Y2s&lK@G1h=r;e8Ov_TMp^|9A8a&pZkwU zunhPwj6(P3k+}un&`B8ZNB6s#n7jlzzeNf2q91e1C5iLX-{R%(jmsAQ)JU%j)-5^K zA4DHv0@QZWlE+Fd7R4k;zwi9rTd{@su*Ain#SJg2#4vfF=75{{X4P5md(e19~dgn-WP2Z)V{-Qe$0GNNnW1+JPgj#`itBn;1v3 z{|t!z-bz@4tE6-XpTQG@amjT_Bi_&km3Y^eFEyW+Ds_P!E!H1ZFr79}?j9d>I3k zKt(6!+|YvS(WqS%rnJ4iPH(k-5Ee+q$+5;_)%gbdH?9!|07|^m_-G*T6Vigs+dz!p z=*3;44#2ZKWZyG&BtJEpDch09c|x$jszkAb-5vD=9O)*&7+}VRh9CWeoOJW&V)nAU zRm?^Hj}HeityS_>@+=AsLN$V^ynM;EM)H;3dfW0*O-uKSzQLr0WR0 z`Io`gpU*$=bVcDZ_mjWV>_OQtOxg*YLs2cRPa>bDwZxmRW|jFxXn1#Frg&KIAb?y* zdZ$Eea93T=p?0UMcd|MiOrG-C{K z?*@?~_w}yKEBBwcw3J~x^mjPr3WQn-7q{V-@P-<|X*!agn9uQAQqSK-nDdzmu3J;@P#8A{*in91W?mZ=T*wfP1?^mNqZ;yrxVt&CZK|f+i|;e zg3tPx&a^bV3*U#n*2~#yMzTfL37SMmfOP|GQNKmrmZkq`H5T0gA|+54bF!VfOafn= zgt(yinF`2cJMIN=7P**R1TLTNwmc<5ED#dk!K03YtMF(Csn4ubX}Qm!P-kf7%}p$J z-ezFa(9g??OVL-t<|wOof?NUxE1BU25Q{@8ev({``6Q}8)goqu4p+P;D1bZv#yrj= zR3>$vJ8id9xi0$9!Sv6RXmIwt^rRoD`&h0k-u#9z$M|K-mSBgPC5hkm zW4u<$WfA&7y&@fuLP9y@5!5wK5wOT7vZO?cCTj_5hZ0duA4=A6GGCQeS;dj;hzDvl zUJn-uQTl2*Q<|c)MQ+;e7{+ zA}IYlI!So)Tfm6PJR;z7l@Hu;>u3RIT?Q(Kb-oO-2VV6Psr$BDr*!ON)^2W-p?L6W zYH*nu)m_*Ves^5u#+}k3Rvg*_-yp~H@x;Q#&Z13vz*cTE887G2%G_fY7$+x)`vqW~ zeFAXn9v2AqCOq2wbzVs0gIf(CEvDH-a+5@fV_xpfF9Og(eEeXtLQk~nt812t@x=m@ zR}0Lf>v*87j6~_L)iT#96Wl*EnR(nt198=%3s_{v&f?(}qDva95@Gb}`CiKdF-UIg z2d_9z^@!5WTeorN@W&~bTv9x!|B`!9m85P_dOg6f6XQ4fwN<Ib;;hTJ3X~Nk?zJH~$vnvt(@q{Z5eh5-bm@C3>yEv0RY!FS?Ey z)9p~(xDu~FEsHAogkH4Yz042+df$ZY>Q~}M#^B78byYovJ@3#*$CJSSO`QUaul+}t z9qlocXfk6kUO8IOG|@2lNavKp&Tt6Mk2HJ&b9g9Pw$i3NN8-&|KsN4KE_+xi-B*9> zrPpwtbYNVuBtN8N7L)_3Q8S7ft8dFQVIEY!oNI@>gmbT0JiMX}(vSx(VtPJ#+PKv#9WNxSLi^x~OuxL?uL^Kh4w>4eDjJ1ard2@B%QG+xoWCnQ}W zCz)!h!}LkqhK7#idR@9LnRYU%Qxso6WeV&oe;YqS6*b0rm}xN#3pIV15usL{4e)$m z`4dB4f2Kfi-b6l}+e(gGO@fRI6~Xp*-;VN0o?O>Qa&>9J9Z5UsS|jk=Lw*Bwdnykg zmoD;KnA3?75@JjUdE8XxP>6U2SYk>SJp=G1!qkG|P-#KUgh-%dmz%fed1yLe`VZDw$v*yH3NxqM!{mdqDB!Y*lF<~PgtwJsc>@*tag1R3L3`8U$ zp2ZxPCj*j)FGwThJ2i7Fbw`;$v_(shXHXD(iSA^Ongd0OoO%9X7X8Aj%9J_1q`}V} z)3O#x{oLcrT++(MsX;Y2$>#?Z-Od9+vrpc&knV?m&xQQr9DZDh}lku zh6|m`f;KaNXp`^7%J9zpphby4BPXks9T@SWNUQ9;Z?okCuy+dk{B_=p8Q$#6cjwbD zY2eAQqP`lU4Vt_t8y&_Uv*tOlQhmyXCMu9qcCE*+dO(u?Wz-VW2{*6VB8!b9CPv1e zMo_5}idM8Ewf>;@3EaP9>FjfQwV+-6lb&MaY{@fOK=LqFC_mqR(eCjn;>wAzcSI%f?or|x9&^^O4UYdeYoNUw`H zctUbVf?};e6onJhff~F{mxTL79R6(uz z!argA8u#zo1}xGO0b5B~@dGJ+Qr^P+U0PhJCUBg}C&7wlS-zTQ0PPTKFFkN+vE*mr zH$PD|`{|MBuIy4FvYQJ0Oew4Z1RF6RM1C2hRmlt; zGq{tR(?7hZ!zO-<9b&fv@7Hs!w{Hn5Bta6{mo=OEsszlj&(yx*!KW zDKVf}q8AIe>xs5BiJ54I<)AO0syhoxsLl|zF83!|!7na85k)w`T-=~uq;(*XIG;x~ zhu-Vppqc_M9=r<86C7u^tlgRL=sE~?&4@l11^(1`9>v*8o6!vVIN_VhZ%dj4Xhu@K z%>8H-A0s}9Gmi#%NAQWZp+@7yM7`d1Cw0Wk+R{BQXL0Ub#@C*-p{&8i^hjEQlh^3= zeCxjeU%pw4)x<23HK`Dd4+(pJMVb6dy`6(dN(Z5Qp>L7OgJeF^8L1T)P|c~l%!w@a zqp$ZAGmj_qrr_*n0Ram_-eN7jr!<@>kwD>m!-kArOak+pQI6<{TW+Q+0V~c1`pi~e zgGewEa)#%t*nBX{IwXtnbb~eVVgI}OZzCy(+@3M@hOlsoKe2G0O_Io~3N;kc2?n*1sauP9~V5mur zrAA*?ADY77oYH+o$YG)?3eLJl2`p){nc6*RiH}1G#9y5K*st6S3fzo0u8c6expin3 z>>{Iop*r<4F1@=YL}y!;0Jjq@Hm${94#-jJkg8Dup(xXe{Of|7_2F@gmGMQA%OI?kVk?yOS zo=o^{xCuOW zAi)r6_)uX}OTK!?G~~ujn+k&NvnerqJB9o>o1q}?tlgFW{=g-7B%u~SHIPq0ph&4; z2l$+Bn-y1Bx~`_cy)-t>aa3+9UXW~w*Gk)oet3ITVU;?Rw(YdsI-r}Nb0BdY%X zi3JoHC@K-67aV%wO*QM?ExMN4OC5ivh+U?ZT^EN|7#SvbTT%WnZgTK&RNtn^Ivt`w>cjch>UWOPkxSr{rIKU7a;0>81lQ(lfxiwN=gnyFTx}sGLQjSZ@2% zsKo+KviECmIm-kBja60XoeqKy^d^3gcO{6`k#|6nnrm>Dw`a+VA%JDHp~d~@F10NS z2&3gJYqRtHmtegjDw{$aiU;P}rMX7JP$_N}8QLyutKGYKzrA3J@f`E)M60?72zj(Y z^1zf5eTSdqfb=7e9>E{q2Bn?j14STHd^J_*N+yOtMuEKG>ENwq=SN8eJ(3kZNVp0 z*_BM1W)L1O$g4+P>^0o4^FakN44rdGMpU2y0q`-?pC+5fR5SVt)WirY(ZmChCq47k zF_Sz!+o|JC_S)Ps#&q_ur_`s93g?NjeU2u+Q~XLWpCZ1_p4)`FUg-Vk2}{Zhn*m#0 z%O{;)i)z`vx>YZ_jB^rGiln$kJms+}*A?3`0iS6}!~L}eF3F0z$84nGRiFEe#8dl1 zZ3rye3*>H@FW#Z=U(sy0p!BZgzJv|4*P9W9qnvoa68?Kmfma7x##w*^heBwlhJ88j z$X)0}LB_u$6Nr?(Fm#vUAyuCD3m=t1xlW>|3+&HFFi;}T z)edD6T-2a8*@&VI*Hp1^CL0{%`G=D{So_IIm`ssA&rxBPE+t`^OH!3sf%64p1m;j##5 zpL*3=aLaz&Rbk~HB^$cFP+F^%A1zerRfbJikr?Ky=AT%$5^&2d`IN;JzZbffpxKP3 zFt}yiJbcWTlh<1bmYN(<5cT~<38|VT{rahv(&tjfZKkgU~G_FuvP0+cBoB(-zPsq z#XI2=l#u|jQ#eVx5zRf6wV!E;<8F@}I_y`WN#3?eCIUNmJOhN;qFIMOL6^-|`)~*e zaMz7yOhy>T`xpRQR^HVPbq*r(f(Pj1^ir>n9ma#^1cdH%@Us#hOSI46l{obJqI%7U z160k#+Cf1+Iw|(b+tk06rlv%ngRY45ueXcf1J@^2xSBp0nbnzu za$##-2n2|(F6)_6O=z!teSsg$YW>^d8^kO~%+)8?crt2!(=b_xy*9hOZcubKa)dwK zW})a4h&uL@$27M*k_6Y*PaSNjhf}B&fWzQWe_pS9KhTr$aqH=9J5D7pU465aUy1c}bY2w@ZUm5Mjw z?4kLAHr2aSA)#K@Dfq><=TZWG)D2@#_F#BL>{EI`U@Nq2o%NQ zuf$9t0i5!}eznCODwLPmP#UcT9j4ET#+AF`t?iMr=^C^f3qJuDxqQPAMRfWXWh{rO z(6A;w?RDi@8O`s)xYD9;P^b_4Emub!bszK09fJzh{j*)(x=O!w6CP{^Bhn>|`#RyP ziUh1qNrEc~q#L?KeeMj!Xy?;GQcPk0PvtNd$TS<2Fqly6g-t*BC|W4Rg9K|SG~IQX z+%_h@=m<=!F0cgKyWd7kNA8q`w`VeI(NVYi9SB{318A5@?4)2M0H0=FV+E8hr$+po zBJMaASc11k-HppE>5C=S_9U%qQ_U{~Q+1H1m?y-cDYTT4AIQV|o3tXNzo%F-pWkGG zJwZanE^t=5JDY`#^rQ!wX8={1>TlbJZ)PnCUIWmb&4m0o$=z?vSO{Q?CH2tk=l)@e zIEDL{Sgw>|ONCY{q3@B`Qc7!YNk=vRz=- zMt>pkV#vXNb}!1@7m8ZHx1P_k2l|}N*Nm`lu!HNp>uWF!?{LctwQI(Pt4-rcl_=Yh zm!zIPNtPRR)Dv+#yG{9hbQ-&`Mh6WYjyij6mhg;g(ixg_CwA~S`@*SQ#rBs|W9EHi z?F2@K-_*MoT(6R{e?V`AI1D=41$Xu()hT6g8kWgAjm9fC`2YTfpDrUra}hLqmY-+v zWc7;F zt3fDW4N&X=K{=~)RU)+PkW{`f`Kuu^tCw6MtftU~%H@+dsAx=K3r5!vKNM^3q0?xy zGqiuI>qz@4$$b0nakiWHU4gfnL2Fv?cOx^}Hc%9XMBL)QT&Wk@LNqrIn3Y*@mr_po zx*133a}3q&&AXsSR`E0IRC6L=gMi5EpmC8E!bEfLuLN&6bC7`(7j_p4!@UJ^3)`=wbvR za_9~kJk)5l4cQ>rR`6K+>8f<#qgS9nMj;yXPfL-6KA206Q#isK>+@)^hg>u;2M>T1TNf zKQ&h+o=T{!Nyy;n+Zzl~p0ZZG-o&8zFQj*K!?kneRb$QaLi|+n%UNp{8AFM|14QV% zNzr>XRT(=|mCAV*+ZYSKSfs#IO|U)2kj^)^yG{JxE?HS&g@}zUr-gOoq(G&8rC554 zUM@8U)1{uH#AZ~pENqLb@-2_ZdWWG2v?<947R^7La*-+Tx3+W*R5+%$!mx2(7$rZb zJB4hZK&rOha-WX{GJ-X#+6LFYF18Scli5u@lSP&;eXEgEUHBviSR+Z$&0zjm){DHC$QI(X`&(Yw^5r)>F38bven#QKt z*lrC0X*8!H^{2XW!&`!ak1Xw`jN6VFYqQ1<#p?6+!RUY|_ly>tjK$j;2zogIPH3yp zou2O~My|at7kvPpxtoD$=lP$bql2~hFIjj#SLIZ?$-o4PIV!1w$vj)jx3HV*H&DNA zQVYmE$^f%91!T!6r4og4UhR)yJ4} z`h`h^`c&TTel*@4r9Z|YSBh>7bcw^#VcDk>g+h_beFO%VW!W)`UBqY+U&n=TPP0IYV z7lc*k0_l{}i9u7jJz;SHTxkNs?WZ>JW4hhlnPZT0|sCx54CU}C|V8rExu?dlmdH-Q|yWZ-C?IZuuJChG7=EJ-nTX0JSA3qj+L(qf0 zZ487ss;At#K>J4d$^Q^e?D4F@ADX4+D>bJPZ{HV>XO@pF=k?NjcZ>9KDy?|qh*X? zPm#+f`Sg&W<70zqulb4ITcO$?mEXhT272AR$(*0WU-@zDqWp(%>*An<=s4u7t4 zXlGr%EEG3xRHG4zR}G4;EJ-$e3%gyZ_4FXExWJp;+)da;9i;FJ)3JhB9t38Vo78rT zA&nc#I3Z!iQ*gx^4uNEr$wPFw21QUl1OzCDZ!k4k#wivqOFBx4lH2t)7|-~X6)4p; zTAC?No|mH@q97@u=H`RVYf;BuBGU4NfcAdlhTP9bU}mPoK_AlCy|3sLD&OX*`CZ1D zmdF*j;*+nDZp-Lc3B7NlL>*YFd+EZ5TlGbisb%~>^b(2_v%XX8uiO0{ic%;D{#@m_1Eg!F^kn*QAnbl{kJWfrRZ(x% z(!*od^*dKiAyH<9eBE1CQw!0M!;txsZ9~Mk#&2_iJ{;uw_HPO`%K>+lDq36=LMJ3c zY-0i_LRiPgMhRF^?D?-=6Y2rQn|zK&d65{vTtHK>=dt=$3G#ma;&d1r37L>YiawVL zeM7s|Qc@S;nf;!MgJ{l9fo+X+gTm{P-uiM!2~4%fRKYZsGJ1x31xQd%YgL{#&p>+` z2I&?WO=8Bh971+1m*(kocHe0Jtm?+4KNYp%!Ux+rS5h`fgHR(lZ0Lz#_e!V&cSrSB zk5*}bTk+x0UyPBymxcvbQ-hCT42{(_5n`q==GIm0QZvZTCP(e)X;EIfgymQ7ecy~t zxb$aEKkXY#!cTy0nI$NGpaC=4saV_mV;x1y$`r00lr*?6hq(l#eB%Pef|7}GWxP~9 zfKoS6JSSKR>G1OG*KQ~e40F)q`nAh*e4q44EVeB^pe_aa>2nbO}Yfjo0PUL1hP}_clbPGlb9U&UuU>~ z@uJ}}n>2CJ!ur@=E*aXu38dp?YOaBeM7}0?%{ZaR1bPO1ReFb;lFwn$l)?R8uopkO z3;T(W@@o0QA$%qLb=d)_M`_Qs1P^I%{ndwRp(`xFy=Yk>ea$-DU*_(oU0?q>MXa2W-h|+B%o|UJeF$Ycpvz>G(zyn|DM}EVEiSjIcq0 z#oH0rCBADby3UoY;C#g)OSU)U2TE>x|KRl#3!D7J>py zzNy!&NMr%dvPfEO8)(6oCyXO~{7HJJIglC}kG#T#T^HC3xTGGb8&9VG{a0nDR**LE z3MKmcmkrK-$)O4F!#EtjkN77y##OXR3&%lO*p_!XwKXR4DY~K9wB7p?e|+kk#Qzee za**tyUsc_+&SG0Lf-LZyF*b_4gOb%=vjmOPW|&G-N+GFO0#D;mAxX)}l{`XZ!>{i2 zklZ0`42v>2Tmv(9SPliwdvH?dN>bvJk9G@r{VG8q!BAvCMCyR8?*jRPS+*+%Rxp;E zQC)$3VjA!`X;M77nPFPe77h6?cfh2N0N(xYj)hGuS~hqKC0EYRpGHbJ=?>sY$FFWo zs7t9baUe0)6x$g^8ry;0483O%vuX@+6x6Tmg&8&}Y+!gn?Yk6Fy!Y{!nO+61lG+~p!ZrvV zH6{9QJ>IN2VbMYHpMSAkS`~ei);YT0u#uUApNmz%d0761MLA*{4&CAYt=PFX%-~i& zF-O1sH&_jE8@OB6mRMnSyXvkw(rQnG2+{}$?jYVu(dxm|Ms7550x((R?CXX;oLMTGRa~fV?mG8%_fhh3mK2-gsW$&09r+-nL<+1E^XC z>0;^%RfRWcoi((5=G_k&LU+zrd0xmv^0QyRh+su%dp+F~(+Cavzc-bVm58)uuH{dJ z{1C`%zY^38p+Ie6G*ZHIwDq?QAlRj`aGfgGJgTzt7=w3qvI6mUF-#jO>3ouO&s%enz_H*4N`^7HrM-e`w>jD-}2~} z8`ZE;8nxM=kOz@C4a$S9I#XoYMXAj|zyk|iO_jQAntg(==0cSk;q9#f=>*b#^WTb7 z(U+XwCQ=-RkRa>eEa4RdA8h4|0DUmdScZD=a9jZ^al%su;FMA}uSsmL;Wk0J&j3B? zC>PhFhY1S+_MLSbYvD(>a8#4s9cG@%A4GUF>~-G_xSY075AS|Ld2tx^Iyf^wS-Uo{ z;4WOI3G^2boP5@B?nbEeNr zHK#H(<#JHqi(^?uU7S&z7iFcleWqru7bMX%%oCWvHh;G1K z2L8%}@<0IG;*TTlnO=e3M!zFQwqL?GGn4mqUf5%GLM$34SA^G;Cu}6+qVTvsba147 z11)n|Yi9uqR=C@w&*+S~k!9i*yjIl|dTPv5l(00)!{SJPQaeb*E>Js_y4dGoAg{Kn z!c4W6%optLc!TmAQ6SeBL{a3nU5Kwsc$<5dqNXOXMX)yH#7JK15t5NPHb3g1#%p;ewQmaAijBOrYbSNTW}Dp6BSy|3ty6&91V8+ml1>Q3P&2=T+Po} zr&}wZ)OHJs&gyveRB-}WUQ=n6$fvG0c$)a(6{Yt&{BSFw_mVL?jWJqv+<8Vh|0j`# zCYsl&k>=CEU*?w=3S1Ht1;_1&QEH{w++@2PmV!Mjn3mm)^rw~BH%%>>UtSLo8*kU= z9v~I28@y@rZ{lBW0l;xIIt>5=c{n_KP^B)4BB@+`vLc8EZxD_7SY6qDA5KV4%Fxhn zi-C`xnwi9L72Q#kJQ=$S{64cXdn%|!vxDC`m)zp!^h+`Usl$}yvP>d@WGK&oEG<=I zMEf&Pf%*51prV^mURf*GE{`4u%u|!%*b9C8)jL3D~c3ZWab&!50iY|#`61q52 zhKVYom*V@^`^BELmlehmi00XIk?y_ZW{;}q?ti=~qkIOiR6354+YU1a%L{c~QI0FF zZZCX&PqTr6nQFpG`jQ;es+6@D91`sS;JDrXbQ7iRv62$qb^7p9*H*2!ojv+cL8Ku~ z5^^|>^6i~c{;M4Qxy@;uU+@QBc=UUx|-|FGigeRG#Y^S;pO zP$7>|dI-n`<7x7-M{X!hnzRb%O0@_v;MiJ>Gcqzc8|s%T?7BEWVN?klIvzKkHu-YO z9Xpbo9GfW!*8dvOT$*!M$&-b8>s4{L#rB1zk8`<2=*Z1DhdS!1hl&rv1Adf)ieai~ zugv)65q&OqY@Y*D+t1Z4^vqN$(AwkZaW!>5{=h^L*)gz6c=H+TvY*lRi{5dr&sNy& z*I7}G7@AlzDbC+M6IV`2x`GTWn{OgF1G_YwW`paRChu>(xy1osunk{~OPLAR67d6+ z-kV7xOk4IF!*YE;8K&MB7tQ}1AX&xxrJ$QQMdQTz^|=<9N}PrxO0hkxx+!W?><<0tgom*eAvWr&F;n=Kl`w(VU=|806rN4pK=ZV0<=70G zeBmC+W0orkcixKizf^WwG`quEfWJC9e~*>vi)irJ{rv~_&6tngiZo`1!`QOIQEaGw z7!S9EO}}R@=8#4ljbTWr+hXA_7}~|D{_W}3++@PUc<`BvWz47Nb(Nzq-HO6P7W27~ z&#YMKX73R95oMSo`htz7E__AQ>E#GXmdM12{r({_+~r@ifyK5wTZ3>~hT*pX1e&|f zQ1j3zembB?&(7c^j(qV+BwUdC;rONKCr>tCe@M0Bq_Bd%GT|>AsbEhZ?q#c zv#x$_LM=aXT5GZ{!QK4*cP5;_)#DlpR1aL`aX_1fzosF^<82E)dXej7Z8?5+LNQvr z4(DZrS@_*6QyE4KaRBlSx!soi%OVw#@K5p@Oq8Brx8v2)))@{Conebac(Cx3yKUIW zpzOg&6(=D)7}aVK?P=i-TQ8y_il4>Vt*kCn0;#erXt$}NNQ zsL*L+Jj$5MRo@2ZbTqf7{6YSUf6uT!q3Gta?2SF~$*W*VG90Z21nxg=%0U(EBsiP{ zGajOCkN=RS@9x7sqWoR~f)gs(UF>_J^5(4xhM*29&02Ox z(y?}CVMl55SO_)edlu#@-Qm_|M|u=SG}uuO1J|vYBp65od9=01hfK>kiqFZKOLFIB z5d^RlLXO>w)Ai6d$;AAd7ERUQ2T~FU-P5&=m#~77BP&y=3lP9N3zb-a0`(&(>LOD(z@ixy; zzFQiH+xAR&AS22D9BM^F%!SP?xUUhS4U4JbA8mGi+_d>>4m&gKc4{qVWqmUV33UeL zQP2G{u`Tb0m>&oZFPE0=%kS{;^`^~Ia|q`?HHja9KBj$B+F`S_yaDf24SJEq@S~l! z@l1IU&lWB)7RqaMIj%G;sH)%!+59br!N%taa`e(gZFu#g^ ziLv;0Sa-h(k|g--_&sk*cKT{j2G7!{zi5g0J!t@!^jl;pd3wrT?D&aB*9s*}9G}z@ zGEVJ4)C z32og#1Oki*h&)rK3ngYpCZhk!boJtLvk!@UZz7)Ar3nMV0|Sip@zX1m2-*e-eZ7Rb zA>^ahsA(ay^CfL5yV+gK3lm(w2uDfvcedmo(Z>xJ5|*3V?B6CJ2@Ue<1n0`w}PAW(J}P{ympBW zR&;8ud+GtjS{i~%G^sS*!}dX4qI&bIcxBz@3Lrt=N(yW=)6TQSn8*TIZhj83sL7EI zcI9ui_O2t!iRWdG;Z+?U7wVX5Sl-l?GdXTCwb*O9(4kW32H`IYQ4DWp)DbPd?K`AP zC~XrE6Hl=t)gmcq9l#Ks3oyH|1dX0f)o9Fz6_QP?uG~(%g?!aRxh&mB6#2dDZI6@O zyr?8kNe@r`U zx$V!XV0V}^txahoR)&TImI zB73x>AY^kY9Feyim{Fwma(VJ9E1884m0+Y_!@aes0&srXy`r;5Hwl%_!&4}I2Go?S z9cgDue*9dO6u8+y`yf=A>ch~8!uN9{9rGDbDfQ^4f9$}}9NWvS2=_vHT$Cwk=S3(n zGPre9mbJ7ZcxnhlG$-v=EoD->mJL9+dYP}pmDsmi*h4t{t$WVYhbR5y7f?}?uFV^kKm2qG{ zj#b!7UPnNiDpFS4D>#hYwA~!uAHxD+Q=cj;4!TRQOUbTW5`n~|0Ffe!?Zn13d(N7^ zU(%yS_-tnyOwF@>^$ZZ^O_Z~CTmC9ze9ZK(IbbM1^z6&g^ zD>fnx>ad@5^~spn+_5%ZIgsC{#wNmDxo>@Opnk9=H3n;l*oD$Y4(*C3?{gpoK6EI! zq6&;Ow}EOX;z*<4IJe?F-b=q5@yJSD8AmS*RVAbQJktBf z%N?P=nW=`N<|#IpRsR5__2QF<(VHW6L@BkDt)irJT1m(ST-VOkjrjfut%}<~2kx0c$ zOTh?3a2eExm-0 z2{9ap?(@&({c8??G2Ij?^A9_5&QC#)rYoX%O{iX2khejPx+&Upa{x$` zM3O1P9Axz$g)PRMuY+t!T$lKDB4eYvaAOLW3G1^11VgF{4vMpS*wj)jbTu%s;Jw$oMd3< zkHVTQ)DBn?=zCMzWly}h9>%7ISc2}3A_?S{IVb7botVmtXjVey&ePFJ{*_`YMU{Y2 zAF26)Kal71rb#QY{ol$-=y|Mv?c1Aaq>Z9dp^wY=e_Evwxz;2xK%>oKc=Y_Z6*FoU z*36-t$0;}nh)E;Z4xd`)Zf|9~wG!ITG%R}m0Cyh7vaM#4>PEM?x|1#Psb($w>F64s zf&HgrDk{6G5_mF=$N5w*9i)c|iF441umy7|rpsv>vz3>O9j2>WiB>6^?q`8yQnB)L zpTd*W4!%n(IpEs%sV+LJ0E77x`qfK4D^Ig`Fh?rx`^lWB{A-u~(!R5dLky0C7z1u{ zeX86#z4fFk=h`t|ySW_toMx4Vnb*S(pC&PGK^<7J1NEm3KGJS?NCKU}E98E7#dFZ= z_e}t~YkB978@L2u{W@Zro+FUL@@#1$3&2%x(6Cn+=t_p?7{OP7RT3itse0|aY>rMQT0$gMQ^wr&Il;-PQY3LQG-Z*H?o}T!0QDZ@t~-HMLpDBBoE|-@OHVRe zkPfdy7oqLz%!C}jz=f2 zJ$gJoV37a>_UM4cm80j#(vE*kc0+fs7x{qipUh z@$XeUfG}73AJVxk)Yp`_v&RW#JTd+tFh5F#w`956PB`gN`QVTBCulk3b5D*&DoYK4 zhgu1<6+mSLlyv$EbVXEd3V+}P0s7N;EKs)ZsHXXAzb_#JrrK8)qnxWaA;2B!SO*zW zc=V>?Gt)ktQ=$se2$LI$#!2f%!o^ZqoU0(msOwJ0lu00!HLo_BQ9v@GbN${x`kJF_ zX*|~rmR+mB9kW_Rq_rO_WpN;LjzIPlrN|f@Vzn9zsF2@eLh7Ira(ESGt@bD^a7p{5VB(`#@=524)g(yp0S5r} z&N!(fSV;MoC5KYPQxWbE5dvVI{9>$Sq$AA6@HyaAPF;amhsgwzxgh$Ulx$$6g(UiV z)7_UO;N)~U;-ij91fFB(Cy)W-*i@;ou;ULI36u2cPlhID$#g(E{JGENO4Ek`9oxHs z#S8!-anG$wcNoCV&75rmjNk$KW~O4reni2?Us?mkqaI%4>ylUg`2Zi*gCt-L&60Wm zKb0V3)^9WJc9DgbjDI{5wW-@XJ z>BU6bWh#U*2N~EvVm`H9Z~*y>9{kcs<%b{2sA(4_x8LT;Z4%o>7{qi>i-QBTZs^vx?2Xld5d`KcYtDK6RCqXz(F zgLS8*-JG+f;(N|1&* zQMrYBSY+cHvyQX8tcCj^xRg&b5TN8n2RQ9Yve>Mp;Q40<{#xfb_ND^+t>X7u2bvNT~Erc)vFL2Qt$Is9tXy~xN`EgUV*-22rQ-k1nkr9AFDfIgJW z&75t=Im-c`t#EZZtaJwA1x7|>P3m?H#N<{OhSit`wF|uApLZw!0If>J04%aJrvnUE zX!rWlgoWcfn5b?5BP5S%VQUo^M2;J_k%}~2Y*5?`{{V$)?v+qQ4%~Ii41rPkOA`Vv z726pL&OO1!GHG5(5bsdG#4s{X=hB_Y7^el&$K;e=PG+J&Zw%MFP9yf=?ffU6FXi zYBGC@ja8KV$ByH*F*H<*ONm$agtHz_2NYG(2k@{1(uxTqcT*r!l0A<~uQY85O{aEx zk~&gcGdyEtiy7`qXB^XG({Cq%E@a$dnEb5$KE9Pj5J_}Y4U4(AbnFF4)0Ie=#L@l^NC zhER5SWPYRh)E1IJR#POb@@>EhyaQFt?Ji*~<8a3E08}3B$^1B|E!eR&ge@bicW$zb zVM}fU+t#n!+Sysyu+$_bWgCN@bL_o;TEl`PWqB-VbfzD;(xx)QsoUvSbtQ=1JaFGh zb8oprZ#m=YIQF8=^%d7))|QPFt#)FTSe~wA0W~c5HxU9XqmhXO;nBZJh+N!T zTr_s7-bieSoDsBRu@u|8`@5UCZJ~cJjnA;)bJ!nhNN(B^eXCKohB??YhzCVXVE$Bw zOUqkPD_O?LCRw(QROi1GnvSl~p|^q=18_3l{+_4aoiLI_jbOXmb0NTtFl_!fM$>OY!OjUEL;nERplPLv zmK%kUhe+fH6o*UQFUt~0=aQmK6ZztcptCL~iJ?(|?!WCAhx8_{!{RGu7?S$~ull?n z%=E5S>rR;`2^GA*K5(ZDe@dq`F9|+mPZ`M>Dn~TYF6i%@Sx}16mSFz?be{gaaZFA+H=U~2kFIe(Hn^EAfmuNN{#j5@!v~rH-mDR)n_r_DoCm39joQ(AP)8U?2XICI9`l!wad}gaUn?+$C`qBX+KA1kV zmU@(X6i9^R<15MhXtuW%lPl{N%X57!wzA17g#p|~(obS=1tyInTv;@-H_pTvN8c4(pvzPZ=nN&S1CCw6BwwP)7>-*;3|^b zl6!xJW}Q}hmi@?QUWAi?4PJ)fH3;5F$RrP#90I>kI@NTwf+cJ+rsI>rAoLZU#)Kbl zm9EkiiHoto9Q@U%1Q%t>GDd|D-I1_)V*?~}>6*Ex!QuO8*X=iK*93m>GJLzcrrGZgJc%sKzv{%e+w}nC)#lSJep9f;x1m+%^Es|g zMo3xnCqu|yLHs+^Lh;^16evr!0;nVsPoU{l%7W(g&*`3!|mJpW}wr&Gbjl)#NlN7*bY8Z?rTl7J9j_n6Ypc_0jOxCP}T3Ex3*}) zq_Yw~h@5_1D!!MhT)}i!XfqKUgdG0>_3KpV(5r2YSSjn39R9S8rfkZI8=gQ|OLO>A zu$|25KYJ-{n?cC~np9J??Lyh?I{yIrt4cjGXTfLKoxVaF^~E;oNUcbSMyd}E<+8`q z=I95tT6fWtX3A*{(jaw(*dF+$cqLJ|#U=pfDu2SHG0d)aE)enx^Pk3qCvXZ+OpUx8 z`c->1+=7|gz*TH#?t#q`5}j8B`t=oa?Gge9pC(5vJkFln(wPavtUhTR=f9SGG-E({AIim8EFeo1g=z_2#2Xa6i@!#CG(iv@vo>9@r+B z%kf>ue=phDWZK+~=Wtf{$8UbsQ&NR(RgBTS$wm8&fwm8KRt!hfQrWOp+Zv7dZ=8}z z9+=K5TfeoNLeRRoMZ-rT2IJL92Omo6q`lLcr^I7v_z)5Ts4Pzctt(?BoE&zeNmN@2 zCn7dwasYCFkfa-n7YXu~BRJzVgx|hxAB4x7Qh1p|f=aed-i*KFRBn96m(I=vgLPQd zmL2|NQmG{1sO)>ucOKIWXN<xJ&STF^QO+}0F0H($?}Nzqr~+hTwL@iC zVuDB>yjM>W$8Bz?&AS)@mn3KDSvpj4t@Lt8yVg9h2d7ReYCkQ*NX3E900V%1t16P{ zi-OkVY&WM(r@0`CPb~-`u*%(lG~%R^S&2X0=O2wBa(KZl=mlVGERr&^>{HW*Zr|3V zM`ww4?-*>CQS*Kj!5c4a5bbjj%rP+HyZC!{372 zha0*B)~4OL{{VJ{RYph5cMtKPMDKADwgC=15k*I}oR(rq^&*NaEeM?x1xkVk9Vh^B zgBTq%NJieLlh&GYPpx(+*yn6`BONF&j)Iyqnp_WFYRMvriD?v(!+%OiB3B^DatEl* zAOu`K1~Rk)cV{^?MJI4>z}BlG5TvVi!huxU36L1rNI^X9BDA*`8DY|tZYLw<9@U(v zr?G0IC@+x^*s9FOsol*zNJ3P`KqCN>4O#Nz$-s3TkOD0`*f!_p^M1nQRQ8TbUoC+Po zMp!pjR`xG&5)#cO7!#IXOyu$@V%2B1+Ox(c-ZB{vKTK6}i-Gd6qXFN%c5N{y4#C)xs^xHD;y0gsRT;zlAv}Tzoltv7dG-Dn4VF$=G^JDXWUa)VX*T&gCMHl{{XX4 z$|IMCjyz)@bOTUFdo!e)zRi%NhB-Mn=rR6zr%84e5s1{f;wwpI+a8~8!O7UG z!!QHraY@(=n~AlTj77A%54*Gsf$3MQ?Zh^1E$K2$cmSs0p4c7z=?(R=C^s>(%2#qi zyx^12QVYVQz2r9##o6|gMuBE$>K|!|zz9kX`*JI4!aI9gc@Eh8#=s4<1D|S-?KToF zW4lQ?z+Oqm(v}H)`C2BDHHmpyF`dU9I?&__B-)m(b7veeTf`7QP2V^5tp5P*%g9^; z+rjI&V15Aq07{!tyKOiut8g2z41nX`{{Yog7hf_f24a2Nk@--p!KRHlJVSR0Qwj~3 z0fsx(Is8q2(kmemDwDv^KGj`kiH>aI4o(SI$ph5Wt}mll8|^m9=BoU!8NtuLYBUly zbiWZi=Mq2fI$^QLxIg1db7^Tc$&yK~k2{(z=WBc9jz2o&V7ho1%8>%ZbCJNS3#-Z- zYblZ}=VKm6(wnfA&f?ng%GxB3BO0LRJBi2RRz|IC94a@M$DjxNNUu4#yDdKJStZ+y zob?CNrGg3HYt1{TW7BcXBD6c!)h$j>lmip}(8i@^GVD9Vd%4Cjkz8{E(FRFOU=FNC zYBs-N<)GANlmYW1mK^?OnI~MAP_5C8Rd;kQ5xC>6Gtr&T}3pb$N!b&?JBXAddY#DcAEy5tULYxKhMOFbS!xHZ9T@ z2X1-eCm&Dns@kpX&FoS`W{})OG8@b0QSMi${Hv~u_fC4B5tF1geC^6fFP=J%D)qz2 z5C~9^e}_H&YLq4T|+2`X2*=buiP zsVeA!jI0lp`?ABYUMP}6@g!=^l|RBTDU!4A+q19n9^TZ@lEPJ^K*gKp813s!Vmn49 z0!I1C;O_k?{#$NVEWvv!fIrXHrF%fHzhWpO00J^s#&CfE+`&5V8npXExkY+aGz7m`&51ATEo z0wSU+g(=5Criy0CTP8I)J$`Qg0G$*7!oX3SiUJ4VF>}bCpf5HJR#cn&$epC_UtA>IXvy{Rhf(8 zG>@U{*10OLdqZeF1q~u7*rayJ6>{1|7+D*6^#-bKVsKQj9Awc|1MzU=rCIFoxg5;{MeQIyr zk&W3tf|Mf>$qGJ{S#}-UBY2b#naKYDcNH63TS>QW_HoxdRNGr|3$>5GYEVx+jQZm= za!0UpNQrIH3mg{DLPrDerb!W$4ahyPaZ@kdCvnfc36YXiwtJp2QS6|~=aE(IWEdgx zy)ZgdiD{p_TO;_g0I7=eo!I{XWOStfzISE7_oV2=e$j~>Vk`wk3+h`rr%SQERvktO z?@b{$ah&>NG~y%1Njtp_T8c`<-LgRkoX&b!KRVjqcxxBEX@CJFTW|Vd`i@xTFK!^g2W|-e3h|1nsts<_8Z&C~4B(kf=CcvR^xzEfxpU;{^4OfmPyEP~{T?BY{yWc2^u~3V|O`k|-B@hT&ZUjQRq4Rj93OrpY8#m(y14W25u{_u0Qan~p`&i)`^)Ra2}m~H|_xj+uht;an{ zrhjP73=zhO8_ZiJ$@z&b&PRW(Fr^eyYqbfm5}*FsC{5#_T< zcL&S&RYz0lQCR40Ad#;;$cW)kbw2sUOJiefWAi7CCSlI(amUuK9XcjJvR%&X6Ql7wR&#ET&#gc;A`O&q}CW1Z7uFLVJ=%0UNl>G;=09kgka5-OZ$1mgmt z`%HGJkVH`~S(Fe%fBNcYzp^p;X|S;w0ygJ0T*RncpwQfz+G}}0_EXQ`Yfj5ixw46x zXP#2WkohEi4l0}`<~BZJFa-4~aw*q(go!F8vY+;|{uCxlM*X$yS1}hrLl5A_SRbY; z%u^$)0^EQ>1OP|jSPLYNE@hu+QI!kwpU$P5P<(+Zw2`lTkN&swq|nnhZQJbuRTwgb zCs2pY|BlH!|uB&ZwOg7~_-f##xsha0&?3D7q!U;GZp`=Cz$7P|Y-PNj6k`=n28^k&41}kx@*D%5i`g z5nbGH&g}Bq%#()djQfZm@GhT)MI?4@h%W8eH@-MNzyVtGk;;xPLQIE`){%K&JLbDt zG)T&ohSCXD&NlbNBJ;_LF&6Vp!xo7mi1^I?_cQ`yeYjE>|iyb>_2b#ca%Krcqi`U<&;-p~_UO;E)2*%&nrB6J2@QhWJc4hZ-3sFTc=Qf9a!GBS4o$K{^2Ja+M``O-+zvvK7G#~+Rb5vs6eZkgaV zGCwK`5=Lp@i!*tl4g#Oy{CoZ;l@tSv7Uq-))Zj*2*R?1F6NXsEGnZjN6D*TOl}Avy zILPLTu5u0uKb;f+(Jp_6o#rk%s>Qv=X}(}zyn3Fs+hdyLz3N8-oBOc^i-P>2U3^R2WaP#7{2fPHDlc0g{P)XZRETWF+I=awY< zQxas2gW8o`k-!QCLdziFVE#0i3+`!I4(yPE`8)tS(jUA4CC|S~Zt~wLTna{zoCM;Y zqPZgk?!=#J7$6)1qq)r@00&W?^o@fc7$jq$q%ojJobEr3Dz5gzkCb<(?HDD1_7vn+ zVU;^YJB5P|jCt+A>q;amleBMd?wo&0iJb%CTOO=vAzWvcBfU7Pq*YDXR>2*~rZPz*@W%u2pklBJ z2x0>Jiel|n0x(JM#XaNLH*PF_4Jv|z<;W+!G{n&39)E(PPnDl2Jv!2#H~xAP>;)>K zkQKQ-%`Z{j`wX8lB9v`}9B?WlB#PTglk^p4Nh3uHhbO%#EwFMcCr&KUO`?m4+!d8h zPa#foPcf>X0FXT@!AThIVy)?()Yh{}moJ6&+A19{F{zazUo-BbIX;9B>r3*X>QR&U zTb_QkY8dU~O{6w+!Ob}l4-u~&%}=srbE1}3O|nUrDszSDQk$t~y<3>$jhPfEBw%sd z6*Jo>c}Zj1n6Q;|{lVBAl=G!WkZVLRP^7N^7JBemQI&ct^_uGD3 zKHPMwOs-pK8&D3$qw+H9izBmtbhm0=@&#h{jF#}hGu;(37X9R|#Cb zU~o5XJYZ(5+}=%ZYPObE-bcDVcVoH#0PEE|$)s77#T-hALo4mtTksVsULm+AfWxQLHELU>ypUQ)E!1wrfT8yfsV63_G!W@Jd1om* zG2qLClid9UJHDc_=tZYYxMOp%=6;GlhyMVt`qbsTrrc6I4xHy7ttG4{?B-vyMF5cJ z7;FRUl22-ycwkFMl1pfv$jE5d=08fMEeUaEbiO2#IY?+0L?R#J6@J5%^-2lhkS3L$x$5On5No9fUsS~5q!Ykm>;EadONIoTQ?bIVoz^R=}=zY%L6OLB7>ae3Bf+#)iq)- zeU7L}c`ukCo;6T%BRpr@rCFNhYk1@HBUA+8mnR?R@UDMK)aPuO5qCFIK*e3Wxw!K2 zBiX29zz#Bh3=IBsnhTb$A+or1GTo|{?l5usbo{Ed){AlFGud24ARS8_55pO&kX*+N zn+eA_2m*1D>qU*3Tt z&MRE_Ye;dCX5+sSF#fe&G#guVkuB$t=jQU?Zht=i0F^BT%2Ruh7DANTImic}&X{C3 zQ3JU1(-kp_CE)G^br{e1RB}ay;j#xKZxn}OA1KC7a!+1c{NkR=BR1wN%zK_`RItHk zIQr9EF$C~HImtag#(~_75;)`W9q3|Rz}m>IfWcVc`zZ1 zHqm7ri6ry!J5I-t|4o4#tE{m?>Qa41t49=kPRHKPCbF32cPcapQSQIMF0cy zdI~~*Y;76$=8W_5;C>XE08}Bj5I&VA7_LDS!UCRJg4sWN1L;X5wjIagXvl79RDwEW z`_w>@(+%!v2Tibgrw4K$Jd>7^iJ1+ny`Q@5bcxuF1noaDFZKvE9kaw){| z$se5`DeIapAO)O!zpWlw$K4!yQM@kz5jw7zNSf$d5Qci>RC&)o;! zoxo7c23busuy*^Ujyu!-eBd`8qJW)Bl5^iRBN)!0V`--;RA0OYu%*GrDnAoZgj1iF z@-**o)N&RrmIV4#kBoK3d(#ifIAVROIUKjjI+|9v?mR9Z<(88xxR+`~K^e<+rP{1_ zJ}HQek}`0)C)%VS6wcPb_n`nUgaA{R5z**u5*y}j03x5pm4R=VzH$6CfO@bXb`XDccJWPeItznbZxUFi)_di4`Ta zCSC16Zh%#GOOqxeC6l;cO1@cFf`ENRITtx?+cVPx6`Q9W%I13%nIk|1kh0^ZIH`=K z7d~2TBL{C>Q{{`!VH?Uy)5WYX#z4+Gl1*nSZFMwK)J-<%*t;w-vWau|mm-#X*Ag*U z#PUB9GjIt%$WsF(kpA*Rv%WAtN{I-LMp#R>{{Z46wP$u!tVm3;#x3pS8AG_nib#C( zfY{HsHKC`O^$1xeW{TMk(uACo=qjzf#P)GMA&x-ZLFy@O}%;-R2GuSGLr8h`AdP0;Ta@~xV7hBpG-GUOJi2|uUoRAG&w$&l9 zgz9_Nj3ty}W4>CKWbxbN+kPv8+R9#OfAepq5}6$FTOK(Q$SN zWKCLm7RoOn6adnk^Z0-D>MQ*|t31cW+laYY;^Il+7&B24r29V$7r8;?KBMs@!1o44XPHAhp_ zu2SH{u>G8;1P;0S)vYgFxkoY2BY8+N;PZi1uH?41E?eny#S1jf(SX}d2pFhC!vw5h zh)U`I06lt>jtI{cZ~IEt=rdY_B*YKhxW?i!z#g?4X!mgD>Q{nGnLhQo$-w&b28*#c zq*A)nBx^-t{#?CwoN_V#HFH9XPk4-%Hxd~M#=>wjk7LbMmq>fbrExmMc=;K(5%~I4 z2HNHZ5Kil}IYJl&C+a$yYCz(4%Pc}M_HCye0rq#r>-07Kw#IKy{al)=YokWQ2RcBD(AD1BK z>zVFLfcQRwigzl-RZydoibEm~b5+^%*EE5$MhDPWZz+c{ zIhDH%(gt(e6gF|m!Str6X5&11=8XV)XLdr9nsY057^MXx85t+qk(`y}5lZ(N9^=1h zVn@=SgOD~Hdzwwfmk7D1h5&Qch9o1B2i>HM1{o?dPTU-00~DJS3=E1_9frxc9sr{_ zTmnh@QtSh<`sR?xtA!cQU@4|62bik7j%j}KkI^ZS^0qS1l;|P$38*a=@`P0mew;og42M$j7xS?E{iPrE%D1Q1VA3(v$^b z!kqdVV#vRBIjL~iJ5CJ`KofD#10K|@6plz!Oj6C<6W@w)2&X3*q{f9CO5h*LnA=BJ zI320mm3;@bBCu@yxfB4^D}82mwhallo9l2FV|#E1WP;{{WREV;r-7bb*RO zk=Jk1qbQ1bat$Jl#NhGknv)0z02A*|VBBC;$RL(9O6~{U+s9f}E(jP3Dd9Vp%@^(i z6rhX@7AL92FPO2e5lJ-SMs}}SL%X=5_YFjjQ_k)w9D;HQEuNm#+zzfO%F(IF>qU@V zh)WZN87H+!vTYl97^rt;vz&TSu(|n8eQ34!1nfy6^8r=my=W2aL74{vlte&3KR-&0 zLR*Gxk6J_DQL4qCX5+N?QBoEW@D!0ij6#Kh{BcNu=H!s8{OPb6Do1dD`FO{3#RM?` z2iiJwQc9?*Pnb!^Ow>RI7z_vFQ_7@O+7onylq--wj2dcNL==~8&DV82d1wwuW9})- zZxn;fU;9kM_klL&+`BzDq|4Fm+lWm;kiII5e#t5ds+HIaDy@KV*-Q|}bDIUb)poo2&J!RjFame~p zE)1@Oi12yF`Yy(iYCF4Y%kT6kolr%z#Le=PpYW?zm+@O-*usT?$v`vCeJdKtC5kx$ zGUfRvzvoxh^=U{VHu%!qN*@XzkTV zQ^+{WdT?s2_wBr1!cfYi?-R+-V~UO^n*2QXih>(_J4Q$h=h$QuLc7>)r1d7S(~%Mh zq>++P!N(sdK8CF78k?+&sUea=IE_EXqq^2?+9r!1E-|$@CZW-7;kUajG^yq?28`~= z866IL^r|ECBc2CKX=Z8H%yYkKlaM_&pXpWf>wzW0#KR$nA35az0F7?nZJO1DOv?B; z^2UGq)rY6(m(twESv-W!eAx~H`})w8#@&&ume!NX#(5iTL*@)l<@d!$bcLB?w3bJQ zp)JPmaaQ#WGD)Fk6TGp42<$9`Faum0M?<%T9P-0HC@?x ztr@?%u6X|d$3<3`N4v9DlHxGH9A!uy}Jkj5L#VV=QyQB|`j;Yxw;MIjVCzf(XY zaFnVU&m)R)3%D-QJ?pyXHHR!rd63c_k(?+bp0usA7zZC#G%3OT*azH-o3ev=Oq>us zO(&cig~>lkcb3JsI|E3>?ij{9($EJea5(^bQV?0bU{nfLmmC3_Zg&y83J+sOpbq;o z6be|$E0RuWeq3V$kYP^^_)%~}n72$5>?xZtGr%;Xm%+&Pr(k2H2saZrA2w)J-O0*< z?@70xyhR~ZBMMDrV*06h&ntewcJ5W(gSz|)g0oE&1BSyzFU z&*4%=FfechA=piUdE99PstE@t-jwoi4rx_Fa&ekKGvs!{HVr6@1Cr#@l;6l4dr}aC zj&dltSaY)u5q}y)-WQyMNUTv#dHiV@$o&WcfE}K2NXhr5<2VdI3Sq>2oHKjT8S@X^ zz@Pt=Tt=j>dT=l)C1jC)V0h`;lXgL2jFE=XIqOIA&}Neibv#p51$Qq=!#y**7~C zMe9J2$QISVhB<-zxeHzZ#CgmHz;h5E!e7Ir}Dg{;OD0VEkO_7t)h|Oth z5qp*rNTMNBf_T8jDH`C0e09!x)g*!lt7nw#a%-T8e@7Pt`H%t6U;H+B_I zca}Fu#nhaVLE^4Rs2^}reT^h=CB|~)SKpEPQfPaS$1XQWs0(x%$o%SGGHZuFYK}5L zg%pqn3*WtcCu2(AGOgYQ5J?8IP@x%H$_r#l#eJJPZ$ z;K|SQrn4Q`j0_&;kP-$8xXC9Jk@^%l^)(X$r*`gYa8A+dL(ph=7#%3&dr%3$%_!vi zR5nn;-1`b?!00$M_8k2xHw?HWQ$k{c>(-Y!I8bUFlahZbuo-ranflXu0#_KQ6^jrF zG)PC?1ClyW&OyNG^ri(Ri}UG|OVkC6WPL`{>S!m;ZYB7Yxakv^6_i7iZG-EI~e$24->ca6M?ST@EZV4s%KyjrWXU#eqyLH{m(;r(lee)6$pqdjS6=nbq3H&Lj$j--ZNEsA_K5)chrHv6Yfu8Z^f9Xth*Y-p9$7s_D`aqfRrLm>Xyhl6f$L2O0m~fyMI@Hs+aZylAgLz!7n{JGCGg+b)A6YJMBu{HnWd*W9=O2X>0bF@-oBg;8z?Xk&lR@`@O zObV^YBp{<=mIX=ThhWs1cA(=Fh4OGZ&?6Y+lS$8aDxc@4Y;d4l)V#rkMZ$WPJrAx#+3^q3XeGAh-aL*ie#! zOE}JYQx!K$^JAq<$&a~>)bv5C5EhV}f~r4SUE2l+6czPspHONd6U+o;)aX4&Gf3nF zT+%6Rr_4KQZ?qs@ep-Y|vdnSM6z}8~^Bo$E+ly`;s>g0B1yZlb#XXqg3yPPh_9WfK zBOW=ZKx2|lJuym2#!d|@4&c(@aB-Spke;;6?mal9ae>WRNQT9X0(opzkYZDS0Y6OD zbcL95IHeLr56jL)DQZ+n{MAvGtFprRK_os42U9hHKlh-tiOrt26Us{Z`l8kw02Bcpw zVOU^O0Eq(i>+erzRL0?f>rk;x{{SnoV^1ifnGWJ9JwS54_W3|7+|eTKAdT41Zj>e) zl;C#)mO{Y^QVu<7U$9t4xIi(3nnc~4mKZ&#j21z;N99M9ci~$ChhWrGwT=xtCm;%F zK^{&?G}dM7-|I)95|T$zOlMqm0QyvGxw#GBrAk+5&H?(<*moNnB%CqNwMqW0;RjxV zo3$~V0aGHZ-7aZ-#RC}`q`?WgMdtwL(u5`3dkg{7G}d5F0l_rwr1R!~Dgb{5hIIpi zDlNu03Kt~z%`3#Gp7es^DLaV?o;aio%-c%fd(?rKZZnE%s=4QoJ7%50cpoXlf+`@v zbCcJtF2yf_z^NBu=mi%7E$GMY^Yy1Ij(~Lar7XnMsm5P`NbcEAYzvU^f;!7-#KQ;qfViy@pz+ykxnwBFE|3Bkf|UM z^x~1CC2_k0(u+hc!+U2tfnREhVpwMs><}@IDl)A31HC&FaxA(wS3bVgC)x;gDYTL6 z+Lj zbtjI4-ko)DF7_*RT;+hKfYkodfHKDusEl$z1l51FHO1;Rs-%Y)!;U_`TF8y#$Jo#P1pN2tl32ir_Xn42p9wcST-X8@OKnm0{(Gh2G3u zl5v5IanRLOb&*39*y=dP1kx{3Qstw_P2XO%8kBJ9BkkiLpXE{p5+05_@Idb__cdIG9&|LH1kwOjGNaz6TN#i8l_S}Oc5_(gO5`3^Ffur#A1K3P>skqB4=(2(pnr`9 z8z}zxGB=|?_*8S1%4dfMh1|#3W|Xr5l8gtYD?uev50<`I9fE;X-g|^#*({{`f1J|h zA1O#m#f}#uqz=cTesrmDCY755Zg5EB6p~1H6kPpkxsxW%0A)_2noeYXxcXDju0One z=|%y_IHzzB3^qqvkbCn`w8~o?=AK_~7^!2>YNNS7byxML1>3?d@5Y(8CoPkn*`dHh zJ4O%Im=2OAamWUQj6#_s=Jl$nJb>_N{$%cX=zXc$LcB{KF#zI`-)K2F;+hPLjNsGo zrl5CNrD^3;|>PpvewrzLYonIzq? zwLq*Z-DP;FVga)53uCoQ<#X$bm|bj4c}t&qE|$V~dy)O1s__vE^rkh=?iEf?UMc?o zYH2bX1%KHT-!WGh7@;ocF3BP)s&D%l+eulWsc!^{8E+%-9Y+ z#WW^N6=PfjiU=|cl?6wksD>Bs9G`PeGL`@WIpc~N1kmw3XN=<>w1Lw(3^Pq2D`kMj zI@20u$k?EtVM@Vr#!fPNR7H3vU?Q4YLNTy_dengK91fIh8ZbzK0R7*kB#1{liT0*E zu7_yBK7x@JS8dF8k9u}u(0&}R&4r{9F6`$fnqz*xW(7$QaxzFX0IZ;nf|F?3g~of+ z@K=+AOfHL`Q$@noBl4X|A+t<(aBxW#VPsOdZYiE*ayHRTOUNzeBxp}A{{WRqvN6cW zKUxYRo(DAVEFP!wq}U`^cWwI+5_E*u*MmgoGOfd6(I^a$3I$Ky~BPKE-}wq7$P?Z83vo? z9A^fd=Ay9_?>z-HG8Atxo!MMd%kTMeezhF325M0vD8O7*Sc}+JTyUhHtwqW=J@~1V zha4PKawq`g^V*BpO%TrgK_?_*HB=S=1so2wphC$8)?b(&w7~-B83LwUqgN^{TbPnM zdepI6l_j_}Ysy9He_EC{jErPdUt1Sqk%+G#3>s`P2<|-1k+R_AGKT6g(yrz=;1T&! z7?DnCJD{;yS>lbnw%R%cUbP_9W{NfQ8*?0z4l|C}rD+srXvwPNE4Fcu=}_Ns*%zL0 z?q(ra0HiK|O0bf&ujjT%AmoMNdJdJ0@W@DEkje%#-yBtxl*0?3yh#1$T;%k{Jpj^4 z#Gtuzv;)G79AcuHWppMu+W_Zr^~Xc}>Il5Ogq9(X19x#wc}y(J7tOeh#PT!rrUOxn z0$U}APMrJInvHE%aCvg9YLzDNn^Gnxc%%72l!Qpq+5HIkOp{HJHhM7rC?0j zn&Kse<5iA4gN$)i?4NC^p5a2iF_muL<55REck%-f-5QPkJNi>^E(}owWGY*bnEpW0 zF6L$2{&eM;-SNOI266aNS0U0aCX7hRRG!9)E{AqaB+U6LIQ2YYkF`e(StZ^~^OJ@C zRVs+~6O=33tIClwADcNj#}%Oja$dV*%L8)`Jp~a)&G+VJe!z76sUe9DcD@IuD#ReO zHr9y(43?3CjD1h?pbFEZkS6sk?AgiB0k~;B zA1THufg_Ls=cO}$BdPidrk4fe0l_|)t1BxZ$l#uWv`o#Cu35MT@u>u78D^x7$>6a1 z()oYwlS<)X`;@Q%^Ft!B!R=8>!B>tkNV9{}wJSb@xg&%F9X^!6tjC7q-hr25PH|3; zcJq)x?My>nHf#WMifpiuG8p2l9G*a`?dCh}0~98~kN|VR$*G{+WaNWV2ox_pX*Y3$T<4mETPF^nbg0~`lT3;yZ@k=7%mdV#G*5AA z`VoXV+N=PnL=oerO)+Eg+jj55rQMP8<3Cy(>=y1f%L;fH`cU#de6fR(-?cV5cQbC| z6tX%J0Hx|4f)w1K9uIs{ZIUsV&PSoCR!G%;@TK0Tq3cfJVyoP~2n)?5UTJ;66OqZO z<+saZj2e&)syhMNpE6q^S+}VPXX-)Yu%!qel5lCyFkU*7*i&{n9FU~?QcPlbV|E$N zF;77pOP(`PG%Ps`Skk;}v>tLh)A@*)vna+v&uULORA8JD+M6EUu75gn2*~~(eJUD7 ztBjGEoE4AprkD4>W z79+T(N+vIi0y@+tAkuut1Jl-|E*(jJ52Z0q%%gsXiBOFe<(gBse^JVukY* zo%kY{^MjlW{uI)84J=L_diJ5F3Nm_hs-j-R9(}52Qby7-njCGolk7QU-^!jnX~sgM zhEwfP2-9u{A4+eKGq^GQXtE2kX58_e;Z~tkE&P2dVv@S!kIteABuD04sqQGz1JrSi z$41R6g?0f?}m7DJI>p}t$3=S$q=j&9+LI~9T+D1%p!lVNf9sxBs9f%+07!=ky=Rf^w zdyUjYgLkcG&309Wl?6Uyx}2#RrZI|_$^hr4decID#CEF?##}BH@%U7GHu6}LQzymkBm6 zC2%?Ww6+me!JAAwRe*{9^D5+@>-ko`ryOpU*K@3rG(Rv^^rp*el~92|C*}hj{{UJ@ z-QOl$9i1`99-fq#Ud0QG>&fKvBXJrq;Yc~6t&4<-m;@{d&S<1Qa}lj(XC^s}W3C+M zG^sR^xJ{~inE)phS*`?FkIl<^5s)f)wJ;9Eh%xR!=~{@pB%xPxGN|pxT5@^5TF9)R z_26+;1hKQJ3Q5nW6?9yzhiOf~3=jnXMRoSs6KJ_OU~;1beicUmVkkp=r{^S)e+s&{ z5UZ5KAshpWoRn2pR|UOCQAjr_44D2*Z5hd@vKN4;$oI`?8+^bTISVo6lm7s(RTy)I zIQ(ja$|ex9U=A_MVuwY*3Nw#-l5}m^B;&6Y7T~A9HAsd&AkEh!6(LZ15-KDu%MZFb z)At^S8K&5U@`+*dWK^L7X9A)UU@7cQDr^#?s0WPFZGuQnbI%`*NE_*jY|)MQ+Hvnu z#b+z2ZNv^KXi+IN$q80d(yT3%n}%N?jMR&#JAt_2Lv{QrZi3}Tl~r=b6$xZ+2PD91Fh45s?^+3GvvapO>PMicULx(c z91b%@&=i{Fj@YBmXX6I1rJnJ-ZdFGl56Dx#z{x4-R~ZM^o#HJ@CO0G~TxZnN#kd0p zCB17^Z3Yy!J#pTVZH7)h?s&~lFwDh>qUC*XX@U_eWo3Z>raaP_nk)9~fg~zWa>rq7;2zLF<9N^J@ z;bNzkEAx`SQ%`75mO*k(DpIV>RP-G2-j$;Sb;d_pIfBGc45;~W?@23cZ0_mWoLgey zjw-uuk5zTtL`a0Nr4EGlrKdu*>NN|a?r?b=3VX^z@DJrk z^2+QAA;71JGt?i(k5FDkScz#vHgQ(>;Bk{pX9JEZKeQ^0Q1uOl&n6cg%}Wr>V+(^! z1V1b@>6%w9AI!XuN;+6K9MP8QIHq8OlEl!H$tT@jDSWAU2Wcn1XjkeQbQ_MP4?c#R zgL>o~Q%2O{P7NWD9%BUKxTYe{LBZyj()ChvNV6bMnEcfVD=eE-G>4w_{fFu)2*+vwPP|~8Q-Uscew23N zh3lNs7?~91T($tu8L4gU#IAOgz{7mUsO~jGw1$*PM zqz@QXa!X_QN#p+j*Gx=sf>HrQ%Jwu>sBaeHJ<)U=5KluzBKc9oy_M3jA~!3ZxW;Qr zIHQe1#-3lVJepOIleJG;Z1P4rvB~aw)}T1SD00!RviIdNlSsZ;Lis0X z>UxTauR?%h0C&m7Fd1>EqWqB|&q4^Qvfs+t?R2{<`PHF3@KJ|YoNnQZy_|+KJPc$m$B;%UaTQ!r*+Ms22{{XWlUdwL(OCovTg5xr9Yr~s4iR}$NMa!FEnP&?D&w^a^U z;NuvpF(%avS8z<{`O@ZKQ(I0{$lov|kbN?0(!>|!BsMz^Fe!r!+t_E`rYyo#Vsg38 zGt~NjI-X`Rk|OGHN$BF>7?zxO@Qgiy#8r=XS zD*%|}W0HGQ2-<+KJ6EaBPt^W2=Vw@iOCT9z#(3#Y;}{>yjHx5$Zc6%!omhn%)C>x$ zH#~r-&(HUJf0I^Z1VUt0B{F*B(<6-gQVRo1nMuzX!hk!|UC)#VUKNc+A=soBQe!6= z`t_&A#K5ZGFH^LG&%S5`D{pcXV|#Jz2VBy;d61MNdFh|J2l>r8jzCfeuglH{dKiXs zPang9+KaFw5h4x_dF$MtT82pRxEy5U@zSR|Re*k>v)8YsGGGfR7#j%$4_bF(xdDw_ zCI&P7vDDRZ17$J@tsp*C1Oi5L*qTL*GKP@#>5ocjh0M>h2_s_s0LK*J67Jz}p!KWX zSSmQ-c{KAH06PXbwS%G?P509SwpI{TVinEbd#Ne&1j zkGy-;Uf^YgGGr6-`*o=jG)$1cjZYK-8MknxWcuU$@l#w|mT|WVqXTH|#!VOO4HUf1 zry1s-zdeDdr$lxw%7A#KRaF_uKaD1lNs7#w$sE&J)PwQ@M{HuFlXxH}IrZ&GE#`23 zYNa0HY*68c%fZh>PGsYgfld&zrZ^4srQ;tr6s{YDXUkk;ihr0fQ8VL;0|LC`G@2TA z9KbS=+|dryU8;N3Zyx}bIP|5AA;=jRr)>q)S)o!31B2d~46&+U4ttt=BDVpE_Mt72 zv)Y9%H3qfNauUtEjD0B#KsNmG=}u^#HTgba=}^e>k^xcxp=+>ulY$7~=9`?i%4kPS ze7FbFm5S#h1L;U%$?HzQBNV}r$v=fDekibqifgbuQ$ro5kaQ-H3OJ{O=tVJd-jtW+DRB`XSv<%_#dSdT-%W51ZLOF zisf+G`^4iIs{UKtPx6@wINAbq2dDo4uAe2v!|mN85S=$Md;1MYUBO!1J&t88zVk3>p z+u(pybJvmDrFSvMB7#W90VA){qD1pmi~OT$BZ2seYdM>AYQ*h1$5IE^>q_BbbpVBK z6m%yX`hFbJed0?g;fOqbzvt4c!enF_RTwxR^(TsvKn)+tamIPhNBCx$RvjctBvM8( z$;bITQmwF-=*rAKd;#f!=xJBwEhthHk%cE9W|kew7@k7|@)MCv5+{Zs9EurmBy8ul z-+#`T1VFY~lyAUMj!Dn*r@L-|015Kf2e(2h7|y_tl3ODzPaSCpMN+8bwinxz*A)2~ zi*UGbNMCPScFoMh94Kt`;+XA~XKlcd!2M}lS1Tj{{Gc+faB?{$`c;sHS8|2kM%)A2 zIi-q0oH#1`G0D$g@uiWM$S?O85)XdeKT3BU#)W3cAdpT=dQ$wZs(Id{=02yl=YvZF zk_sR=2LPUjAB9IS5W+(_4&)a09MBUMAaysXw08JaAb?2{4bpsq`qAJWcG0yB~AKvRkcIyuLGIw_*;Ge>z zRNa?D^5kUy0H38W8UWrI_{bRtnn{(V-=1G3fcoZ~uB4O%_UYH__*9XC!K5Pu^d85( z9KdHhOpvoE%N(fB)`?-0ZpFxKmSRs|O1J_j;BGveAAXe5NR$w{Il<#O`c)|bk}U?{ z2`mZ5Y2Ho>E&<#Ia5`1^P;rtD)0}nx06i%@m3YKzF(AOmJ*v5Y&M+S?R|H`gaqZ0* zVHcc66t*+(T2F7b*}=fxa!;l@{&iiU8I1;Zhb@!z{{Z#Vx?qgOb|AiYQ5bj5;l)n& z+Zl?CFJNl8X=CJbk;px%uOX5%A}JhZp;T6rC(?x?SqnHB>?sSOlrA`?v=av0WIGN= zrAZp>1oM;Dq-99*K@%5*M12{j0MAJFX%f(9aDeb8uMx8J!RgF_Prbb54Pg<9P zGATCh2_dH)>NW~H(o7`JY*Zn!o!zKF>`Q=q)thl1Rl;v7tj?}JQ;$p>)j~)2g;<5w zICo?c&4K~vZ2}t_yS5MpJe&%#Dk{c+Z7v7h2iBdZ#=Ez}yt47PkHFNg36fbuVOwz8 z**QIWV~ZPP019NdQm7;g zz5CJ?g4W$&k==>IXL9gOIkLII48093fT$s34cC$?C6YwLZ8$xR1z4SxjCtLH#;LN% zE;p$FDLqA7SKrVQ3CB*9G((Rtui?%qg3ycY2d3aL*ql*N{g{GwvB5d}Y&IMVqP{U#AxrgamXvlXcy}6%u(~ay; zPM_yA;c5i&tEmB$uN{G{ff6c*QGyrqrII8i7>;p|&#f!iMs>EHy9si3qhU(@I{tNT z+7ylaz}z6hsNe!Vr<$=L+aORdHlO88LQH`wp1LnoC7 z`O;b_CqG}ung&TASoTJDaHA~4zoj+c3<3kSI;lOqsqVYtK+I0UK=&Cm*_0$P<0mRf z$NN{Bco5mWD|Q`MzVHr!@P2-WA=*+8-G> z$r(R|77#KLGq`|BDm^=jagEGJXdS^Luj@f}@{4Dje@bwXytQtJ2l-GJC5k3kOKc2` z0ORiQ{HhzH3d|J%$YFv8LG}G<=r*Bc7$lMTRcYIDz}Nw>IRokbG_C~CHs&ppw;lfg z&$U-Za{{Wb%0LWH@~6lGmLOwjGyjR_$xq)4l{9PZ%r-}9;VgMa|ro>UAD)d0AaFO?Or z20vc4B0Dn2lhihUFaEU`0lQfa@(PW^ZYg}Q-~tO{E(bx$`cPzMk|igGOrO+LrAF0m zax%So;GBOd0>YxQD-K9*yk`|2RSN>dD-gLJ!ja`=+s`qBZ;sTVtr zOLRV!EPDz_0+7lH&UihASiXfm#}LLoaDKliKh~mHl%s>5Pvyl>5xT6;lv1P;yyFy% z+hIG22dCjuU`H9pao(YFb`W{wbKKGp$hR4nXDkLsIQOT?Du6cNWalTPRAIQI6U%q0 zt>ad;C~`pHbI9h43|*?SGm?4vc8}7dS5p4~dysMmtvcf=C<=QDWO1snVfTo}e-lUq z$!0w8cpmgg_k6S*?*w(@o|PQu0f6m}e>!n?S^DRYIr>u>3oAJ}msG?#)&uV1j%@+HKcZ1Ud`HC6@ z?jglRCNa=djmP9Fp>kw#^`wyA#OVx@sFFCz7&-hZOJsSXD7!|}o(CttG zJt`Y`*X+2*S+Gy9%bIMI%aKJG5yf^H)F~=Z1B30Jl;vZ!mHt@3`}odJ91eN@l;;_7 z$>Sh%>?v7_$H!FU8jvZ-Pn_6~4bidASFsd2s8=n4(1YtvQdVL?#Ze3D1417s2?M#0W~sH-S< LE>1rxC?NmYwasDV diff --git a/tests/akvo/acceptance/internal/__init__.py b/tests/akvo/acceptance/internal/__init__.py deleted file mode 100644 index 35b47b7f76..0000000000 --- a/tests/akvo/acceptance/internal/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo acceptance testing internal package. diff --git a/tests/akvo/acceptance/internal/internal_unittests_suite.py b/tests/akvo/acceptance/internal/internal_unittests_suite.py deleted file mode 100644 index add75502ef..0000000000 --- a/tests/akvo/acceptance/internal/internal_unittests_suite.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from helpers.unittests.helpers_test_suite import helpers_suite - - -def unittests_suite(): - return create_test_suite_from_suites([helpers_suite()]) - -if __name__ == "__main__": - run_test_suite(unittests_suite()) diff --git a/tests/akvo/acceptance/rsr_project_admin_test.py b/tests/akvo/acceptance/rsr_project_admin_test.py deleted file mode 100644 index af3c323d56..0000000000 --- a/tests/akvo/acceptance/rsr_project_admin_test.py +++ /dev/null @@ -1,249 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose, os, sys - -from seleniumextensions import SeleniumTestCase -from test_settings import * - -from helpers.navigation import * - -class RSRProjectAdminTest(SeleniumTestCase): - - KAGISO_PROJECT_NAME = "Kagiso Water Aid [UAT]" - - @classmethod - def setup_class(cls): - SeleniumTestCase.setup_class() - - # unfortunately we need to use class variables (rather than instance variables) since - # the nose framework requires class-level setup methods to be class methods... :-/ - cls.expected_project_number = 0 - - def setUp(self): - SeleniumTestCase.setUp(self) - self.navigator = SeleniumNavigator(self.selenium) - self.rsr = RSRNavigator(self.selenium) - - def test_01_admin_page_has_expected_project_sections(self): - """>> 1. Admin page has expected project sections""" - self.rsr.open_admin_page() - self.assert_title_starts_with("Site administration") - self.assert_page_contains_text_items(["Project comments", "Project payment gateway configurations", - "Project updates", "Projects"]) - - def test_02_can_add_project(self): - """>> 2. Can add project""" - self.open_project_admin_page() - self.navigator.click_link("Add project") - self.assert_title_starts_with("Add project") - - project_map_path = os.path.join(TEST_IMAGES_DIR, 'kagiso_map.jpg') - project_photo_path = os.path.join(TEST_IMAGES_DIR, 'project_photo_spring.jpg') - - sel = self.selenium - sel.type("id_name", self.KAGISO_PROJECT_NAME) - sel.type("id_subtitle", "Kagiso Water Aid - project used for user acceptance testing purposes only") - sel.select("id_status", "label=Active") - sel.click("id_category_water") - sel.click("id_category_sanitation") - sel.click("id_category_education") - sel.type("id_city", "Johannesburg") - sel.type("id_state", "Gauteng") - sel.select("id_country", "label=South Africa") - sel.type("id_location_1", "14 Tugela Street") - sel.type("id_location_2", "Kagiso") - sel.type("id_postcode", "1754") - sel.type("id_map", project_map_path) - sel.type("id_project_plan_summary", "Provide water and sanitation aid and education for Kagiso residents.") - sel.type("id_current_image", project_photo_path) - sel.type("id_current_image_caption", "Spring being constructed near Kagiso") - sel.type("id_goals_overview", "To improve sanitation and water availability in Kagiso.") - sel.type("id_goal_1", "Provide local Kagiso community with improved water sources") - sel.type("id_goal_2", "Provide sanitation education for Kagiso residents") - sel.type("id_goal_3", "Help Kagiso residents build a larger water reservoir") - sel.type("id_goal_4", "Provide eco-friendly water sanitation options") - sel.type("id_goal_5", "Provide water preservation education") - sel.type("id_water_systems", "4") - sel.type("id_sanitation_systems", "2") - sel.type("id_hygiene_facilities", "3") - sel.type("id_improved_water", "1600") - sel.type("id_improved_water_years", "10") - sel.type("id_improved_sanitation", "2000") - sel.type("id_improved_sanitation_years", "15") - sel.type("id_trainees", "4") - sel.type("id_context", "Help complement ongoing improvements of Kagiso water and sanitation infrastructure.") - sel.type("id_project_plan_detail", "Use funding from foreign and local donors to implement goals.") - sel.type("id_current_status_detail", "Project has received initial funding.") - sel.type("id_sustainability", "Trained workers will maintain implemented projects.") - sel.select("id_currency", "label=$") - sel.select("id_budgetitem_set-0-item", "label=training") - sel.type("id_budgetitem_set-0-amount", "800") - sel.select("id_budgetitem_set-1-item", "label=building") - sel.type("id_budgetitem_set-1-amount", "2600") - sel.select("id_budgetitem_set-2-item", "label=maintenance") - sel.type("id_budgetitem_set-2-amount", "1700") - sel.select("id_budgetitem_set-3-item", "label=management") - sel.type("id_budgetitem_set-3-amount", "300") - sel.select("id_fundingpartner_set-0-funding_organisation", "label=Akvo") - sel.type("id_fundingpartner_set-0-funding_amount", "400") - sel.select("id_fieldpartner_set-0-field_organisation", "label=Water for People") - sel.select("id_supportpartner_set-0-support_organisation", "label=Aqua for All") - sel.click("_save") - self.navigator.wait_for_page_to_load() - self.verify_project_admin_page_has_loaded() - self.assert_page_contains_text("The project \"%s\" was added successfully" % self.KAGISO_PROJECT_NAME) - - try: - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - except AssertionError, error: - self.fail("Expected '%s' project to appear in project listing after being added:\n%s" % - (self.KAGISO_PROJECT_NAME, error)) - - def test_03_can_navigate_to_project_page_from_project_admin(self): - """>> 3. Can navigate to project page from project admin""" - self.open_project_admin_page() - - try: - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - except AssertionError, error: - self.fail("Expected '%s' project to exist (added earlier) for verifying project content:\n%s" % - (self.KAGISO_PROJECT_NAME, error)) - - RSRProjectAdminTest.expected_project_number = self.kagiso_project_number() - - self.navigator.click_link(RSRProjectAdminTest.expected_project_number) - self.assert_title_starts_with("Change project") - self.navigator.click_link("View on site") - self.assert_title_is("Akvo RSR - Project no. %i, %s" % - (RSRProjectAdminTest.expected_project_number, self.KAGISO_PROJECT_NAME)) - - def test_04_project_page_has_expected_project_name_and_subtitle(self): - """>> 4. Project page has expected project name and subtitle""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_title_is("Akvo RSR - Project no. %i, %s" % - (RSRProjectAdminTest.expected_project_number, self.KAGISO_PROJECT_NAME)) - self.verify_text_at_path(self.KAGISO_PROJECT_NAME, "//div[@id='outer_leftwing']/div[1]/h1") - self.verify_text_at_path("Kagiso Water Aid - project used for user acceptance testing purposes only", - "//div[@id='outer_leftwing']/div[1]/p") - - def test_05_project_page_has_expected_status_focus_area_icons_and_location(self): - """>> 5. Project page has expected status, focus area icons and location""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - self.verify_text_at_path("Active", "//div[@id='project_details_leftwing']/p[1]/span") - self.verify_attribute_value_at_path("Water", "//div[@id='project_details_leftwing']/p[2]/img[1]/@title") - self.verify_attribute_value_at_path("Sanitation", "//div[@id='project_details_leftwing']/p[2]/img[2]/@title") - self.verify_attribute_value_at_path("Education", "//div[@id='project_details_leftwing']/p[2]/img[3]/@title") - self.verify_text_at_path("Johannesburg\nGauteng, South Africa", "//div[@id='project_details_leftwing']/p[3]") - - def test_06_project_page_has_appropriately_resized_location_map(self): - """>> 6. Project page has appropriately resized location map""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - self.verify_element_size_at_path(140, 140, "//div[@id='project_details']/div[1]/div[1]") - - def test_07_project_description_tab_has_expected_project_plan_summary_and_target_benchmarks(self): - """>> 7. Project description tab has expected project plan summary and target benchmarks""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - self.assert_page_contains_text_items(["Provide water and sanitation aid and education for Kagiso residents.", - "4 functioning water systems", - "2 functioning sanitation systems", - "3 functioning hygiene facilities", - "1600 persons with access to improved water for 10 years", - "2000 persons with access to improved sanitation for 15 years", - "4 persons who receive training / education per year"]) - - def test_08_project_description_tab_has_appropriately_resized_project_image_with_caption(self): - """>> 8. Project description tab has appropriately resized project image with caption""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - self.verify_text_at_path("Spring being constructed near Kagiso", "//div[@id='tab_description']/div[1]/div[1]") - self.verify_element_size_at_path(220, 165, "//div[@id='tab_description']/div[1]/div[2]") - - def test_09_project_goals_tab_has_expected_goals_overview_target_benchmarks_and_goals(self): - """>> 9. Project goals tab has expected goals overview, target benchmarks and goals""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - self.navigator.click_javascript_tab("//div[@id='container-1']/ul/li[2]/a/span") - self.assert_page_contains_text_items(["To improve sanitation and water availability in Kagiso.", - "4 functioning water systems", - "2 functioning sanitation systems", - "3 functioning hygiene facilities", - "1600 persons with access to improved water for 10 years", - "2000 persons with access to improved sanitation for 15 years", - "4 persons who receive training / education per year", - "Provide local Kagiso community with improved water sources", - "Provide sanitation education for Kagiso residents", - "Help Kagiso residents build a larger water reservoir", - "Provide eco-friendly water sanitation options", - "Provide water preservation education"]) - - def test_10_project_sustainability_tab_has_expected_sustainability_text(self): - """>> 10. Project sustainability tab has expected sustainability text""" - self.rsr.open_project_page(RSRProjectAdminTest.expected_project_number) - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - self.navigator.click_javascript_tab("//div[@id='container-1']/ul/li[3]/a/span") - self.assert_page_contains_text("Trained workers will maintain implemented projects.") - - def test_11_can_delete_project(self): - """>> 11. Can delete project""" - self.open_project_admin_page() - - try: - self.assert_page_contains_text(self.KAGISO_PROJECT_NAME) - except AssertionError, error: - self.fail("Expected '%s' project to exist (added earlier) for testing deletion:\n%s" % - (self.KAGISO_PROJECT_NAME, error)) - - self.selenium.click("//input[@name='_selected_action' and @value='%i']" % (self.kagiso_project_number())) - self.selenium.select("action", "label=Delete selected projects") - self.navigator.click_button("index") # element name for the 'Go' button - self.assert_title_starts_with("Are you sure") - self.navigator.click_submit_button_with_text("Yes, I'm sure") - self.verify_project_admin_page_has_loaded() - self.assert_page_contains_text("Successfully deleted 1 project") - - try: - self.assert_page_does_not_contain_text(self.KAGISO_PROJECT_NAME) - except AssertionError, error: - self.fail("The '%s' project should not appear in project listing after deletion:\n%s" % - (self.KAGISO_PROJECT_NAME, error)) - - def kagiso_project_number(self): - project_number = 0 - project_name = "" - row_number = 1 - - while project_name != self.KAGISO_PROJECT_NAME and row_number <= 5: - # table query is of form table.row.column - project_number = int(self.selenium.get_table("//div[@id='changelist']/form/table.%i.1" % (row_number))) - project_name = self.selenium.get_table("//div[@id='changelist']/form/table.%i.2" % (row_number)) - row_number += 1 - - if project_name == self.KAGISO_PROJECT_NAME: - return project_number - else: - fail("Unable to find added project in first 5 rows: %s" % (self.KAGISO_PROJECT_NAME)) - - def open_project_admin_page(self): - try: - self.rsr.open_admin_page() - self.navigator.click_link("Projects") - self.verify_project_admin_page_has_loaded() - except Exception, exception: - self.fail("Unable to open project admin page: %s" % (exception)) - - def verify_project_admin_page_has_loaded(self): - self.assert_title_starts_with("Select project to change") - self.assert_page_contains_text_items(["Project listing", "Select project to change"]) - -if __name__ == "__main__": - print "Running tests on: %s" % (SITE_UNDER_TEST) - print "RSR project admin test:" - suite = nose.loader.TestLoader().loadTestsFromTestCase(RSRProjectAdminTest) - nose.core.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/akvo/acceptance/rsr_user_admin_test.py b/tests/akvo/acceptance/rsr_user_admin_test.py deleted file mode 100644 index f93df15a58..0000000000 --- a/tests/akvo/acceptance/rsr_user_admin_test.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from seleniumextensions import SeleniumTestCase -from test_settings import * - -from helpers.navigation import * - -class RSRUserAdminTest(SeleniumTestCase): - - UAT_USER_NAME = "UserRegistrationTest" - - def setUp(self): - SeleniumTestCase.setUp(self) - self.navigator = SeleniumNavigator(self.selenium) - self.rsr = RSRNavigator(self.selenium) - - def test_1_auth_admin_has_expected_sections(self): - """>> 1. Auth admin has expected sections""" - self.rsr.open_auth_admin_page() - self.assert_title_starts_with("Auth administration") - self.assert_page_contains_text_items(["Groups", "Permissions", "Users"]) - - def test_2_can_register_new_user(self): - """>> 2. Can register a new user""" - self.rsr.open_home_page() - self.assert_title_is("Akvo.org - See it happen") - if self.selenium.is_text_present("Signed in as"): - self.navigator.click_button("//div[@id='header_button']/a/span") # Sign out button - self.assert_title_is("Akvo.org - See it happen") - - sel = self.selenium - self.navigator.click_link("Register") - self.assert_title_is("Register with Akvo RSR - Step 1") - sel.select("id_organisation", "label=Akvo") - self.navigator.click_submit_button() - self.assert_title_is("Register with Akvo RSR - Step 2") - sel.type("id_username", self.UAT_USER_NAME) - sel.type("id_first_name", "UserRegistration") - sel.type("id_last_name", "Test") - sel.type("id_password1", "deleteAfterTest") - sel.type("id_password2", "deleteAfterTest") - sel.type("id_email", "akvo.uat@gmail.com") - sel.type("id_email2", "akvo.uat@gmail.com") - self.navigator.click_submit_button() - - if sel.is_text_present("Traceback"): - self.fail("Unable to register a new user:\nTraceback details:\n%s" % sel.get_value("traceback_area")) - - self.assert_title_is("Registration complete") - self.assert_page_contains_text_items(["Thank you!", "Please check your email account."]) - - def test_3_can_delete_user_account(self): - """>> 3. Can delete user account""" - self.open_user_admin_page() - self.search_for_uat_user_account() - - try: - self.assert_page_contains_text(self.UAT_USER_NAME) - except AssertionError, error: - self.fail("Expected '%s' user name to exist (added earlier) for testing deletion:\n%s" % - (self.UAT_USER_NAME, error)) - - self.navigator.click_link(self.UAT_USER_NAME) - self.assert_title_starts_with("Change user") - self.navigator.click_link("Delete") - self.assert_title_starts_with("Are you sure") - self.navigator.click_submit_button_with_text("Yes, I'm sure") - self.verify_user_admin_page_has_loaded() - self.assert_page_contains_text("The user \"%s\" was deleted successfully" % (self.UAT_USER_NAME)) - self.search_for_uat_user_account() - - try: - self.assert_page_does_not_contain_text(self.UAT_USER_NAME) - except AssertionError, error: - self.fail("The '%s' user name should not appear in user listing after deletion:\n%s" % - (self.UAT_USER_NAME, error)) - - def search_for_uat_user_account(self): - self.selenium.type("searchbar", self.UAT_USER_NAME) - self.navigator.click_submit_button_with_text("Search") - - def open_user_admin_page(self): - try: - self.rsr.open_auth_admin_page() - self.navigator.click_link("Users") - self.verify_user_admin_page_has_loaded() - except Exception, exception: - self.fail("Unable to open user admin page: %s" % (exception)) - - def verify_user_admin_page_has_loaded(self): - self.assert_title_starts_with("Select user to change") - self.assert_page_contains_text("Select user to change") - -if __name__ == "__main__": - print "Running tests on: %s" % (SITE_UNDER_TEST) - print "RSR user admin test:" - suite = nose.loader.TestLoader().loadTestsFromTestCase(RSRUserAdminTest) - nose.core.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/akvo/acceptance/rsr_user_registration_test.py b/tests/akvo/acceptance/rsr_user_registration_test.py deleted file mode 100644 index 435167dca4..0000000000 --- a/tests/akvo/acceptance/rsr_user_registration_test.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from seleniumextensions import SeleniumTestCase -from test_settings import * - -from helpers.navigation import * - -class RSRUserRegistrationTest(SeleniumTestCase): - - def setUp(self): - SeleniumTestCase.setUp(self) - self.navigator = SeleniumNavigator(self.selenium) - self.rsr = RSRNavigator(self.selenium) - - def test_01_home_page_has_register_link(self): - """>> 1. Home page has Register link""" - self.rsr.open_home_page() - self.assert_title_is("Akvo.org - See it happen") - self.assert_link_exists("Register") - - def test_02_register_link_loads_organisation_selection_page(self): - """>> 2. Register link loads organisation selection page""" - self.open_home_page_and_start_user_registration() - self.assert_page_contains_text_items(["Set up your account", - "Step 1 of 2", - "Select the organisation that you belong to"]) - - def test_03_organisation_selection_page_warns_if_organisation_is_not_selected(self): - """>> 3. Organisation selection page warns if organisation is not selected""" - self.open_home_page_and_start_user_registration() - self.navigator.click_submit_button() # Continue button - - try: - self.assert_title_is("Register with Akvo RSR - Step 1") - self.assert_page_contains_text_items(["Set up your account", - "Step 1 of 2", - "Select the organisation that you belong to", - "A problem occurred", - "This field is required"]) - except AssertionError, error: - self.fail("Expected warning if organisation was not selected: %s" % (error)) - - def test_04_can_select_organisation_and_load_user_details_entry_page(self): - """>> 4. Can select organisation and load user details entry page""" - self.select_organisation_and_open_user_details_entry_page() - self.assert_page_contains_text_items(["Set up your account", - "Step 2 of 2", - "Enter a username", - "Enter your first and last name", - "Enter a password", - "Enter your email address"]) - - def open_home_page_and_start_user_registration(self): - self.rsr.open_home_page() - self.assert_title_is("Akvo.org - See it happen") - self.assert_link_exists("Register") - self.navigator.click_link("Register") - self.assert_title_is("Register with Akvo RSR - Step 1") - self.assert_location_contains("rsr/accounts/register1") - - def select_organisation_and_open_user_details_entry_page(self): - self.open_home_page_and_start_user_registration() - self.selenium.select("id_organisation", "label=Akvo") - self.navigator.click_submit_button() # Continue button - self.assert_title_is("Register with Akvo RSR - Step 2") - self.assert_location_contains("rsr/accounts/register2") - -if __name__ == "__main__": - print "Running tests on: %s" % (SITE_UNDER_TEST) - print "RSR user registration test:" - suite = nose.loader.TestLoader().loadTestsFromTestCase(RSRUserRegistrationTest) - nose.core.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/akvo/acceptance/test_settings.py.template b/tests/akvo/acceptance/test_settings.py.template deleted file mode 100644 index 697a88f662..0000000000 --- a/tests/akvo/acceptance/test_settings.py.template +++ /dev/null @@ -1,27 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The following values are used in the Akvo RSR and Akvo Platform acceptance tests - -import os - -# options are 'normal' or 'ci' for continuous integration -TEST_MODE = 'normal' - -BROWSER_ENVIRONMENT = "*firefox" -SELENIUM_RC_HOST = "localhost" -SELENIUM_RC_PORT = 4444 - -SUPERUSER_USERNAME = 'your_username' -SUPERUSER_PASSWORD = 'your_password' - -SITE_UNDER_TEST = "http://test.akvo.org" -RSR_API_PATH = "http://test.akvo.org/rsr/api/" -RSR_MEDIA_PATH = "http://test.akvo.org/rsr/media/" - -PAGE_LOAD_TIMEOUT_IN_SECONDS = 120 -PAGE_LOAD_TIMEOUT = PAGE_LOAD_TIMEOUT_IN_SECONDS * 1000 - -TESTS_ROOT_DIR = os.path.realpath(os.path.dirname(__file__)) -TEST_IMAGES_DIR = os.path.join(TESTS_ROOT_DIR, 'images') diff --git a/tests/akvo/acceptance/test_settings_ci.py b/tests/akvo/acceptance/test_settings_ci.py deleted file mode 100644 index 92919f1a2a..0000000000 --- a/tests/akvo/acceptance/test_settings_ci.py +++ /dev/null @@ -1,27 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The following values are used in the Akvo RSR and Akvo Platform acceptance tests - -import os - -# options are 'normal' or 'ci' for continuous integration -TEST_MODE = 'ci' - -BROWSER_ENVIRONMENT = "*firefox /usr/bin/firefox-bin" -SELENIUM_RC_HOST = "localhost" -SELENIUM_RC_PORT = 4444 - -SUPERUSER_USERNAME = 'not_yet_allocated' -SUPERUSER_PASSWORD = 'not_yet_allocated' - -SITE_UNDER_TEST = "http://test.akvo.org" -RSR_API_PATH = "http://test.akvo.org/rsr/api/" -RSR_MEDIA_PATH = "http://test.akvo.org/rsr/media/" - -PAGE_LOAD_TIMEOUT_IN_SECONDS = 180 -PAGE_LOAD_TIMEOUT = PAGE_LOAD_TIMEOUT_IN_SECONDS * 1000 - -TESTS_ROOT_DIR = os.path.realpath(os.path.dirname(__file__)) -TEST_IMAGES_DIR = os.path.join(TESTS_ROOT_DIR, 'images') diff --git a/tests/akvo/acceptance/testcases/__init__.py b/tests/akvo/acceptance/testcases/__init__.py deleted file mode 100644 index c72917be80..0000000000 --- a/tests/akvo/acceptance/testcases/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo testcases package. diff --git a/tests/akvo/acceptance/testcases/elementparsingtestcase.py b/tests/akvo/acceptance/testcases/elementparsingtestcase.py deleted file mode 100644 index 5d55fb38f7..0000000000 --- a/tests/akvo/acceptance/testcases/elementparsingtestcase.py +++ /dev/null @@ -1,69 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# ElementParsingTestCase extends unittest.TestCase with common XML and HTML parsing assertion patterns - -from unittest import TestCase - -from helpers.constraintmatchers import * - -class ElementParsingTestCase(TestCase): - - def assert_element(self, element): - self._actual_element = element - return self - - def is_not_none_and_has_tag(self, expected_tag): - self.is_not_none() - self.has_tag(expected_tag) - - def is_not_none(self): - self.failUnless(self._actual_element, "Expected an element -- received None instead") - - def is_not_empty(self): - self.failUnless(self._actual_element.text, - "Element <%s> should not be empty -- expected element text" % (self._actual_element.tag)) - - def has_text(self): - self.is_not_empty() - - def has_tag(self, expected_tag): - self.failUnlessEqual(expected_tag, self._actual_element.tag, - "Expected element tag: %s. Actual tag: %s" % (expected_tag, self._actual_element.tag)) - - def has_single_children_in_list(self, expected_child_tags): - for expected_tag in expected_child_tags: - self.has_exactly(1).child_with_tag(expected_tag) - - def has_exactly(self, exactly): - self._matcher = ExactMatcher(self, exactly) - return self - - def has_at_least(self, at_least): - self._matcher = AtLeastMatcher(self, at_least) - return self - - def children(self): - self._describe_and_evaluate_children("child elements") - - def child(self): - self._describe_and_evaluate_children("child element") - - def _describe_and_evaluate_children(self, child_or_children): - self._matcher.set_description(child_or_children) - self._matcher.evaluate(len(self._actual_element.getchildren())) - - def children_with_tag(self, expected_tag): - self._describe_and_evaluate_children_with_tag("children", expected_tag) - - def child_with_tag(self, expected_tag): - self._describe_and_evaluate_children_with_tag("child", expected_tag) - - def _describe_and_evaluate_children_with_tag(self, child_or_children, expected_tag): - self._matcher.set_description("%s with tag <%s>" % (child_or_children, expected_tag)) - self._matcher.evaluate(len(self._actual_element.findall(expected_tag))) - - def elements_matching_xpath(self, expected_xpath): - self._matcher.set_description("elements at path %s" % (expected_xpath)) - self._matcher.evaluate(len(self._actual_element.xpath(expected_xpath))) diff --git a/tests/akvo/acceptance/testcases/seleniumtestcase.py b/tests/akvo/acceptance/testcases/seleniumtestcase.py deleted file mode 100644 index e5a5b97c42..0000000000 --- a/tests/akvo/acceptance/testcases/seleniumtestcase.py +++ /dev/null @@ -1,104 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# SeleniumTestCase extends unittest.TestCase to add convenience methods for common assertion patterns - -from selenium import selenium -from unittest import TestCase - -from test_settings import * - -from helpers.seleniumclient import SeleniumClient - -class SeleniumTestCase(TestCase): - - @classmethod - def setup_class(cls): - cls.selenium = SeleniumClient().instance() - - def setUp(self): - self.verification_errors = [] - - def tearDown(self): - self.assertEqual([], self.verification_errors) - - def assert_location_contains(self, expected_text): - self.assertFalse(self.selenium.get_location().find(expected_text) == -1, - "\nPage URL should contain: %s\n Actual URL: %s" % (expected_text, self.selenium.get_location())) - - def assert_title_is(self, expected_title): - self.assertEqual(expected_title, self.selenium.get_title(), - "\nExpected page title: %s\n Actual page title: %s" % (expected_title, self.selenium.get_title())) - - def assert_title_starts_with(self, expected_title_start): - self.assertTrue(self.selenium.get_title().startswith(expected_title_start), - "\nPage title should start with: %s\n Actual page title: %s" % - (expected_title_start, self.selenium.get_title())) - - def assert_title_contains(self, expected_title_content): - self.assertFalse(self.selenium.get_title().find(expected_title_content) == -1, - "\nPage title should contain: %s\n Actual page title: %s" % - (expected_title_content, self.selenium.get_title())) - - def assert_page_contains_text(self, expected_text): - self.assertTrue(self.selenium.is_text_present(expected_text), "Page should contain: %s" % (expected_text)) - - def assert_page_does_not_contain_text(self, unexpected_text): - self.assertFalse(self.selenium.is_text_present(unexpected_text), "Page should not contain: %s" % (unexpected_text)) - - def assert_page_contains_text_items(self, list_of_expected_text_items): - for expected_text in list_of_expected_text_items: - self.assert_page_contains_text(expected_text) - - def assert_page_does_not_contain_text_items(self, list_of_unexpected_text_items): - for unexpected_text in list_of_unexpected_text_items: - self.assert_page_does_not_contain_text(unexpected_text) - - def verify_text_at_path(self, expected_text, text_xpath): - actual_text = self.selenium.get_text(text_xpath) - self.assertEqual(expected_text, actual_text, - "\nExpected text at %s: %s\nActual text: %s" % (text_xpath, expected_text, actual_text)) - - def verify_field_is_required_warning_at_path(self, expected_warning_xpath): - self.verify_text_at_path("This field is required.", expected_warning_xpath) - - def verify_attribute_value_at_path(self, expected_attribute_value, attribute_xpath): - actual_attribute_value = self.selenium.get_attribute(attribute_xpath) - self.assertEqual(expected_attribute_value, actual_attribute_value, - "\nExpected attribute value at %s: %s\nActual attribute value: %s" % - (attribute_xpath, expected_attribute_value, actual_attribute_value)) - - def verify_element_size_at_path(self, expected_element_width, expected_element_height, element_path): - actual_element_width = int(self.selenium.get_element_width(element_path)) - actual_element_height = int(self.selenium.get_element_height(element_path)) - self.assertEqual(expected_element_width, actual_element_width, - "\nExpected element width at %s: %i\nActual element width: %i" % - (element_path, expected_element_width, actual_element_width)) - self.assertEqual(expected_element_height, actual_element_height, - "\nExpected element height at %s: %i\nActual element height: %i" % - (element_path, expected_element_height, actual_element_height)) - - def assert_link_exists(self, expected_link_text): - self.assertTrue(self.selenium.is_element_present("link=%s" % (expected_link_text)), - "Expected [%s] link to exist" % (expected_link_text)) - - def assert_links_exist(self, expected_link_text_list): - for expected_link_text in expected_link_text_list: - self.assert_link_exists(expected_link_text) - - def assert_link_exists_starting_with_text(self, expected_link_text): - self.assertTrue(self.selenium.is_element_present("link=%s*" % (expected_link_text)), - "Expected link starting with [%s] to exist" % (expected_link_text)) - - def assert_links_exist_starting_with_text(self, expected_link_text_list): - for expected_link_text in expected_link_text_list: - self.assert_link_exists_starting_with_text(expected_link_text) - - def assert_submit_button_with_text_exists(self, expected_button_text): - self.assertTrue(self.selenium.is_element_present("//input[@value=\"%s\"]" % (expected_button_text)), - "Expected [%s] button to exist" % (expected_button_text)) - - def assert_field_with_id_exists(self, expected_field_id): - self.assertTrue(self.selenium.is_element_present("//input[@id=\"%s\"]" % (expected_field_id)), - "Expected field with ID: [%s]" % (expected_field_id)) diff --git a/tests/akvo/acceptance/testcases/webtestcase.py b/tests/akvo/acceptance/testcases/webtestcase.py deleted file mode 100644 index 4b3a02dcdd..0000000000 --- a/tests/akvo/acceptance/testcases/webtestcase.py +++ /dev/null @@ -1,55 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.akvopaths import * -from helpers.navigation import AkvoSiteNavigator, SeleniumNavigator - -from testcases.seleniumtestcase import SeleniumTestCase - - -class AkvoWebTestCase(SeleniumTestCase): - - def setUp(self): - SeleniumTestCase.setUp(self) - self.navigator = SeleniumNavigator(self.selenium) - self.site_navigator = AkvoSiteNavigator(self.selenium) - - def open_home_page(self): - self.site_navigator.open_home_page() - self.assert_title_is("Akvo.org - See it happen") - - def open_projects_page(self): - self.site_navigator.open_projects_page() - self.verify_location_and_page_title(all_projects_page(), "Akvo.org - All projects") - - def open_all_projects_page(self): - self.site_navigator.open_all_projects_page() - self.verify_location_and_page_title(all_projects_page(), "Akvo.org - All projects") - - def open_focus_areas_page(self): - self.site_navigator.open_focus_areas_page() - self.verify_location_and_cms_page_title(focus_areas_page(), "Focus areas") - - def open_partners_page(self): - self.site_navigator.open_partners_page() - self.verify_location_and_cms_page_title(partners_page(), "Akvo strategic partners") - - def open_akvopedia_page(self): - self.site_navigator.open_akvopedia_page() - self.verify_location_and_page_title(akvopedia_page(), "Main Page - Akvopedia") - - def open_about_page(self): - self.site_navigator.open_about_page() - self.verify_location_and_cms_page_title(about_page(), "About us") - - def open_blog_page(self): - self.site_navigator.open_blog_page() - self.verify_location_and_page_title(blog_page(), "Akvo blog") - - def verify_location_and_cms_page_title(self, expected_location, expected_title_prefix): - self.verify_location_and_page_title(expected_location, "%s | Akvo - See it happen" % expected_title_prefix) - - def verify_location_and_page_title(self, expected_location, expected_title): - self.assert_location_contains(expected_location) - self.assert_title_starts_with(expected_title) diff --git a/tests/akvo/acceptance/testcases/xmltestcase.py b/tests/akvo/acceptance/testcases/xmltestcase.py deleted file mode 100644 index 51a734c04e..0000000000 --- a/tests/akvo/acceptance/testcases/xmltestcase.py +++ /dev/null @@ -1,65 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# XMLTestCase extends unittest.TestCase to add convenience methods for common assertion patterns - -from unittest import TestCase - -from helpers.constraintmatchers import * - -class XMLTestCase(TestCase): - - def assert_element(self, element): - self._actual_element = element - return self - - def is_not_none_and_has_tag(self, expected_tag): - self.is_not_none() - self.has_tag(expected_tag) - - def is_not_none(self): - self.failUnless(self._actual_element, "Expected an element -- received None instead") - - def is_not_empty(self): - self.failUnless(self._actual_element.text, - "Element <%s> should not be empty -- expected element text" % (self._actual_element.tag)) - - def has_text(self): - self.is_not_empty() - - def has_tag(self, expected_tag): - self.failUnlessEqual(expected_tag, self._actual_element.tag, - "Expected element tag: %s. Actual tag: %s" % (expected_tag, self._actual_element.tag)) - - def has_single_children_in_list(self, expected_child_tags): - for expected_tag in expected_child_tags: - self.has_exactly(1).child_with_tag(expected_tag) - - def has_exactly(self, exactly): - self._matcher = ExactMatcher(self, exactly) - return self - - def has_at_least(self, at_least): - self._matcher = AtLeastMatcher(self, at_least) - return self - - def children(self): - self._describe_and_evaluate_children("child elements") - - def child(self): - self._describe_and_evaluate_children("child element") - - def _describe_and_evaluate_children(self, child_or_children): - self._matcher.set_description(child_or_children) - self._matcher.evaluate(len(self._actual_element.getchildren())) - - def children_with_tag(self, expected_tag): - self._describe_and_evaluate_children_with_tag("children", expected_tag) - - def child_with_tag(self, expected_tag): - self._describe_and_evaluate_children_with_tag("child", expected_tag) - - def _describe_and_evaluate_children_with_tag(self, child_or_children, expected_tag): - self._matcher.set_description("%s with tag <%s>" % (child_or_children, expected_tag)) - self._matcher.evaluate(len(self._actual_element.findall(expected_tag))) diff --git a/tests/akvo/acceptance/verifiers/__init__.py b/tests/akvo/acceptance/verifiers/__init__.py deleted file mode 100644 index 3645818de2..0000000000 --- a/tests/akvo/acceptance/verifiers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo verifiers package. diff --git a/tests/akvo/acceptance/verifiers/baseelementparsingverifier.py b/tests/akvo/acceptance/verifiers/baseelementparsingverifier.py deleted file mode 100644 index 4d7d89ef89..0000000000 --- a/tests/akvo/acceptance/verifiers/baseelementparsingverifier.py +++ /dev/null @@ -1,20 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * - - -class BaseElementParsingVerifier: - - def __init__(self, element_parsing_test_case): - self.test_case = element_parsing_test_case - - def open_page(self, page_url): - self.page_url = page_url - self.page_root = create_html_element_root_from(page_url) - self.page_text = elements_to_string(self.page_root) - - def expect_exactly(self, exact_value): - self.expected_exact_value = exact_value - return self diff --git a/tests/akvo/acceptance/verifiers/viewcountrecorder.py b/tests/akvo/acceptance/verifiers/viewcountrecorder.py deleted file mode 100644 index 762b90fd64..0000000000 --- a/tests/akvo/acceptance/verifiers/viewcountrecorder.py +++ /dev/null @@ -1,42 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -class ViewCounter: - - def __init__(self, identifier, view_count): - self.identifier = identifier - self.view_counts = [self.to_int(view_count)] - - def record_view_count(self, view_count): - self.view_counts.append(self.to_int(view_count)) - - def counts_have_incremented_in_recording_period(self): - return self.view_counts[-1] > self.view_counts[0] - - def __str__(self): - return str({self.identifier: self.view_counts}) - - def to_int(self, int_string): - return int(int_string.replace(',', '')) - -class ViewCountRecorder: - - def __init__(self): - self.view_counter_dictionary = {} - - def record_view_counts(self, latest_view_count_dictionary): - for counter_identifier, view_count in latest_view_count_dictionary.iteritems(): - if counter_identifier in self.view_counter_dictionary: - self.view_counter_dictionary[counter_identifier].record_view_count(view_count) - else: - self.view_counter_dictionary[counter_identifier] = ViewCounter(counter_identifier, view_count) - - def at_least_one_view_count_has_increased(self): - for view_counter in self.view_counter_dictionary.values(): - if view_counter.counts_have_incremented_in_recording_period(): return True - - return False - - def __str__(self): - return str(map(lambda view_counter: {view_counter.identifier: view_counter.view_counts}, self.view_counter_dictionary.values())) diff --git a/tests/akvo/acceptance/verifiers/viewcountverifier.py b/tests/akvo/acceptance/verifiers/viewcountverifier.py deleted file mode 100644 index dc5b8ff87a..0000000000 --- a/tests/akvo/acceptance/verifiers/viewcountverifier.py +++ /dev/null @@ -1,77 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * - -from verifiers.viewcountrecorder import ViewCountRecorder - - -class ViewCountVerifier: - - def __init__(self, element_parsing_test_case): - self.test_case = element_parsing_test_case - self.view_count_recorder = ViewCountRecorder() - - def open_page(self, page_url): - self.page_url = page_url - self.page_root = create_html_element_root_from(page_url) - self.page_text = elements_to_string(self.page_root) - - def expect_exactly(self, exact_value): - self.expected_exact_value = exact_value - return self - - def view_counter_on_page(self): - self.view_counters_on_page() - - def view_counters_on_page(self): - self.view_counts_on_page() - self.view_counter_images_on_page() - - def view_counts_on_page(self): - self.verify_page_has_expected_occurrences_of_text(" views", "view counts") - - def view_counter_images_on_page(self): - self.verify_page_has_expected_occurrences_of_text("rsr/counter", "view counter images") - - def verify_page_has_expected_occurrences_of_text(self, expected_text, text_description): - actual_occurrences_of_text = self.page_text.count(expected_text) - self.test_case.failUnlessEqual(self.expected_exact_value, actual_occurrences_of_text, - "\nExpected number of %s (when searching for '%s') at %s: %i\nActual number of %s: %i" % - (text_description, expected_text, self.page_url, self.expected_exact_value, - text_description, actual_occurrences_of_text)) - - def standard_view_counter_at_xpath(self, view_count_xpath): - self.standard_view_counters_at_xpath(view_count_xpath) - - def standard_view_counters_at_xpath(self, view_count_xpath): - self.view_counters_and_counter_identifiers_with_xpaths(view_count_xpath, "%s/span/img/@src" % view_count_xpath) - - def view_counters_and_counter_identifiers_with_xpaths(self, view_count_xpath, counter_identifier_xpath): - self.verify_expected_view_counters(view_count_xpath, counter_identifier_xpath) - - def verify_expected_view_counters(self, view_count_xpath, counter_identifier_xpath): - self.verify_expected_view_counts_at_xpath(view_count_xpath) - self.verify_expected_counter_identifiers_at_xpath(counter_identifier_xpath) - self.can_read_view_counter_values_at_xpaths(view_count_xpath, counter_identifier_xpath) - - def verify_expected_view_counts_at_xpath(self, view_count_xpath): - self.verify_elements_at_xpath(view_count_xpath) - - def verify_expected_counter_identifiers_at_xpath(self, counter_identifier_xpath): - self.verify_elements_at_xpath(counter_identifier_xpath) - - def verify_elements_at_xpath(self, element_xpath): - self.test_case.assert_element(self.page_root).has_exactly(self.expected_exact_value).elements_matching_xpath(element_xpath) - - def can_read_view_counter_values_at_xpaths(self, view_count_xpath, counter_identifier_xpath): - # where view count text is of the form 'n views' - view_count_text_elements = text_values_at_xpath(self.page_root, view_count_xpath) - self.current_view_counts = map(lambda view_count_element: view_count_element.split(' ')[0], view_count_text_elements) - self.current_identifiers = values_at_xpath(self.page_root, counter_identifier_xpath) - self.view_count_recorder.record_view_counts(dict(zip(self.current_identifiers, self.current_view_counts))) - - def verify_counts_have_incremented_as_expected(self): - self.test_case.failUnless(self.view_count_recorder.at_least_one_view_count_has_increased(), - "View counts should have increased after successive page loads:\n%s" % (self.view_count_recorder)) diff --git a/tests/akvo/acceptance/web/__init__.py b/tests/akvo/acceptance/web/__init__.py deleted file mode 100644 index bf38159e9b..0000000000 --- a/tests/akvo/acceptance/web/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo web acceptance test package. diff --git a/tests/akvo/acceptance/web/general/__init__.py b/tests/akvo/acceptance/web/general/__init__.py deleted file mode 100644 index 34bebb5a4e..0000000000 --- a/tests/akvo/acceptance/web/general/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the web.general acceptance test package. diff --git a/tests/akvo/acceptance/web/general/general_test_suite.py b/tests/akvo/acceptance/web/general/general_test_suite.py deleted file mode 100644 index 446444d293..0000000000 --- a/tests/akvo/acceptance/web/general/general_test_suite.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.general.site_components_smoke_test import SiteComponentsSmokeTest - - -def general_suite(): - return create_test_suite_from_classes([SiteComponentsSmokeTest]) - -if __name__ == "__main__": - run_test_suite(general_suite()) - SeleniumClient().stop() diff --git a/tests/akvo/acceptance/web/general/site_components_smoke_test.py b/tests/akvo/acceptance/web/general/site_components_smoke_test.py deleted file mode 100644 index 8b43ff1327..0000000000 --- a/tests/akvo/acceptance/web/general/site_components_smoke_test.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import AkvoWebTestCase - - -class SiteComponentsSmokeTest(AkvoWebTestCase): - - def tearDown(self): - self.assert_page_does_not_contain_text_items(["Traceback", "Error", "error"]) - - def test_01_can_load_home_page(self): - """web.general.SiteComponentsSmokeTest 1. Can load Home page""" - - self.open_home_page() - self.assert_page_contains_text_items(["Most recent project updates", "Project focus areas"]) - - def test_02_can_load_projects_page(self): - """web.general.SiteComponentsSmokeTest 2. Can load Projects page, which redirects to All Projects page (Django + RSR operates as expected)""" - - self.open_projects_page() - self.verify_basic_content_for_projects_page() - - def test_03_can_load_all_projects_page(self): - """web.general.SiteComponentsSmokeTest 3. Can load All Projects page (Django + RSR operate as expected)""" - - self.open_all_projects_page() - self.verify_basic_content_for_projects_page() - - def verify_basic_content_for_projects_page(self): - self.assert_page_contains_text_items(["All projects", "Name", "Location", "Status", "Funding"]) - - def test_04_can_load_focus_areas_page(self): - """web.general.SiteComponentsSmokeTest 4. Can load Focus Areas page (CMS content loads as expected)""" - - self.open_focus_areas_page() - self.assert_page_contains_text_items(["Focus areas", "Water and sanitation"]) - - def test_05_can_load_partners_page(self): - """web.general.SiteComponentsSmokeTest 5. Can load Partners page (CMS content loads as expected)""" - - self.open_partners_page() - self.assert_page_contains_text("Strategic partners") - - def test_06_can_load_akvopedia_page(self): - """web.general.SiteComponentsSmokeTest 6. Can load Akvopedia page (Wiki operates as expected)""" - - self.open_akvopedia_page() - self.assert_page_contains_text_items(["Welcome to Akvopedia", "Water portal", "Sanitation portal"]) - - def test_07_can_load_about_page(self): - """web.general.SiteComponentsSmokeTest 7. Can load About page (CMS content loads as expected)""" - - self.open_about_page() - self.assert_page_contains_text_items(["About us", "How it works"]) - - def test_0_can_load_blog_page(self): - """web.general.SiteComponentsSmokeTest 8. Can load Akvo blog""" - - self.open_blog_page() - self.assert_page_contains_text_items(["Blog", "Categories", "Archives"]) - - -def suite(): - return load_tests_from(SiteComponentsSmokeTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/akvo/acceptance/web/home/__init__.py b/tests/akvo/acceptance/web/home/__init__.py deleted file mode 100644 index 9e905ede20..0000000000 --- a/tests/akvo/acceptance/web/home/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo web.home acceptance test package. diff --git a/tests/akvo/acceptance/web/home/footer_links_test.py b/tests/akvo/acceptance/web/home/footer_links_test.py deleted file mode 100644 index b63fbb2f20..0000000000 --- a/tests/akvo/acceptance/web/home/footer_links_test.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.webtestcase import AkvoWebTestCase - -class FooterLinksTest(AkvoWebTestCase): - - def test_01_open_license_link_redirects_to_licensing_page(self): - """web.home.FooterLinksTest 1. Open License link redirects to licensing page""" - - self.open_home_page() - self.assert_link_exists("Open License") - self.navigator.click_link("Open License") - self.assert_location_contains("web/open_license") - self.assert_title_starts_with("Akvo licensing and copyrights") - self.assert_page_contains_text_items(["Akvo licensing and copyrights", - "Akvo Foundation software", - "Akvo Contributor Agreement"]) - - def test_02_terms_of_use_link_redirects_to_terms_of_use_page(self): - """web.home.FooterLinksTest 2. Terms of use link redirects to Terms of use page""" - - self.open_home_page() - self.assert_link_exists("Terms of use") - self.navigator.click_link("Terms of use") - self.assert_location_contains("web/terms_of_use") - self.assert_title_starts_with("Terms of use") - self.assert_page_contains_text("use of and services provided by this website") - - def test_03_privacy_link_redirects_to_privacy_policy_page(self): - """web.home.FooterLinksTest 3. Privacy policy link redirects to privacy policy page""" - - self.open_home_page() - self.assert_link_exists("Privacy policy") - self.navigator.click_link("Privacy policy") - self.assert_location_contains("web/privacy_policy") - self.assert_title_starts_with("Privacy policy") - self.assert_page_contains_text_items(["Privacy policy", - "handling of your personal information is governed by"]) - - def test_04_admin_link_redirects_to_rsr_admin_login_page(self): - """web.home.FooterLinksTest 4. Admin link redirects to RSR Admin login page""" - - self.open_home_page() - self.assert_link_exists("Admin") - self.navigator.click_link("Admin") - self.assert_location_contains("rsr/admin") - self.assert_title_is("Log in | Akvo RSR site admin") - self.assert_page_contains_text("Akvo RSR administration") - - def test_05_help_link_redirects_to_tender(self): - """web.home.FooterLinksTest 5. Help & Support link redirects to Akvo support site on Tender""" - - self.open_home_page() - self.assert_link_exists("Help & Support") - self.navigator.click_link("Help & Support") - self.assert_location_contains("help.akvo.org") - self.assert_title_is("Welcome - Akvo Support") - self.assert_page_contains_text("Akvo Support") - - def test_06_contact_us_link_redirects_to_contact_page(self): - """web.home.FooterLinksTest 6. Contact us link redirects to contact page""" - - self.open_home_page() - self.assert_link_exists("Contact us") - self.navigator.click_link("Contact us") - self.assert_location_contains("web/contact_us") - self.assert_title_starts_with("Contact us | Akvo") - self.assert_page_contains_text_items(["Contact us", - "Partnerships", - "Communications", - "Technical", - "Post address", - "Visiting address"]) - - -def suite(): - return load_tests_from(FooterLinksTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/akvo/acceptance/web/home/home_page_test.py b/tests/akvo/acceptance/web/home/home_page_test.py deleted file mode 100644 index 70b4517a3c..0000000000 --- a/tests/akvo/acceptance/web/home/home_page_test.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.webtestcase import AkvoWebTestCase - - -class HomePageTest(AkvoWebTestCase): - - def test_01_home_page_has_expected_sections(self): - """web.home.HomePageTest 1. Home page has expected sections""" - self.open_home_page() - self.assert_page_contains_text_items(["Project updates", - "Staff picks", - "Most recent Akvo Blog article", - "Subscribe via RSS", - "Learn about Akvo", - "Akvo at a glance"]) - - def test_02_home_page_menu_has_expected_sections(self): - """web.home.HomePageTest 2. Home page menu has expected sections""" - self.open_home_page() - self.assert_link_exists("Home") - self.assert_link_exists("Akvopedia") - self.assert_link_exists("Projects") - self.assert_link_exists("Partners") - self.assert_link_exists("Get involved") - self.assert_link_exists("Blog") - self.assert_link_exists("About") - self.assert_link_exists("Register") - self.assert_link_exists("Sign in") - - def test_03_home_page_footer_has_expected_links(self): - """web.home.HomePageTest 3. Home page footer has expected links""" - - self.open_home_page() - self.assert_link_exists("Open License") - self.assert_link_exists("Terms of use") - self.assert_link_exists("Privacy policy") - self.assert_link_exists("Admin") - self.assert_link_exists("Help & Support") - self.assert_link_exists("Contact us") - - -def suite(): - return load_tests_from(HomePageTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/akvo/acceptance/web/home/home_page_test_suite.py b/tests/akvo/acceptance/web/home/home_page_test_suite.py deleted file mode 100644 index f84de59378..0000000000 --- a/tests/akvo/acceptance/web/home/home_page_test_suite.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.home.home_page_test import HomePageTest -from web.home.footer_links_test import FooterLinksTest - -def home_page_suite(): - return create_test_suite_from_classes([HomePageTest, FooterLinksTest]) - -if __name__ == "__main__": - run_test_suite(home_page_suite()) - SeleniumClient().stop() diff --git a/tests/akvo/acceptance/web/navigation/__init__.py b/tests/akvo/acceptance/web/navigation/__init__.py deleted file mode 100644 index 66b8943663..0000000000 --- a/tests/akvo/acceptance/web/navigation/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the web.navigation acceptance test package. diff --git a/tests/akvo/acceptance/web/navigation/menu_navigation_test.py b/tests/akvo/acceptance/web/navigation/menu_navigation_test.py deleted file mode 100644 index 25581c0836..0000000000 --- a/tests/akvo/acceptance/web/navigation/menu_navigation_test.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.akvopaths import * -from helpers.akvourls import * -from helpers.testexecution import * - -from web.navigation.menunavigationverifier import MenuNavigationVerifier - - -class MenuNavigationTest(TestCase): - - EXPECTED_MENU_LINKS = [home_page(), projects_page(), focus_areas_page(), partners_page(), - akvopedia_page(), about_page(), blog_page()] - - EXPECTED_MENU_LINKS_WITH_SIGN_IN = EXPECTED_MENU_LINKS + [register_page(), sign_in_page()] - - def setUp(self): - self.navigation_verifier = MenuNavigationVerifier(self) - - def test_01_home_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 1. Home page has expected menu sections""" - self.verify_menu_links_with_sign_in_for(home_url()) - - def test_02_projects_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 2. Projects page has expected menu sections""" - self.verify_menu_links_with_sign_in_for(projects_url()) - - def test_03_focus_areas_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 3. Focus Areas page has expected menu sections""" - self.verify_menu_links_for(focus_areas_url()) - - def test_04_partners_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 4. Partners page has expected menu sections""" - self.verify_menu_links_for(partners_url()) - - def test_05_akvopedia_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 5. Akvopedia page has expected menu sections""" - self.verify_menu_links_for(akvopedia_url()) - - def test_06_about_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 6. About page has expected menu sections""" - self.verify_menu_links_for(about_url()) - - def test_07_blog_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 7. Blog page has expected menu sections""" - self.verify_menu_links_for(blog_url()) - - def verify_menu_links_with_sign_in_for(self, page_url): - self.verify_expected_menu_links_for(page_url, 9, self.EXPECTED_MENU_LINKS_WITH_SIGN_IN) - - def verify_menu_links_for(self, page_url): - self.verify_expected_menu_links_for(page_url, 7, self.EXPECTED_MENU_LINKS) - - def verify_expected_menu_links_for(self, page_url, expected_number_of_links, expected_menu_links): - self.navigation_verifier.open_page(page_url) - self.navigation_verifier.expect_exactly(expected_number_of_links).main_menu_sections() - self.navigation_verifier.verify_expected_main_menu_paths(expected_menu_links) - - -def suite(): - return load_tests_from(MenuNavigationTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/web/navigation/menunavigationverifier.py b/tests/akvo/acceptance/web/navigation/menunavigationverifier.py deleted file mode 100644 index 434642f7b9..0000000000 --- a/tests/akvo/acceptance/web/navigation/menunavigationverifier.py +++ /dev/null @@ -1,30 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * - -from verifiers.baseelementparsingverifier import BaseElementParsingVerifier - - -class MenuNavigationVerifier(BaseElementParsingVerifier): - - MAIN_MENU_PATHS_XPATH = "//div[@id='header_container']/a/@href | //div[@id='header_container']/ul/li/a/@href" - - def main_menu_sections(self): - actual_main_menu_sections = len(values_at_xpath(self.page_root, self.MAIN_MENU_PATHS_XPATH)) - - self.test_case.assertEqual(self.expected_exact_value, actual_main_menu_sections, - "\nExpected main menu sections: %i\n Actual main menu sections: %i" % - (self.expected_exact_value, actual_main_menu_sections)) - - def verify_expected_main_menu_paths(self, expected_main_menu_paths): - main_menu_paths = values_at_xpath(self.page_root, self.MAIN_MENU_PATHS_XPATH) - - for index in range(len(expected_main_menu_paths)): - expected_path = expected_main_menu_paths[index] - actual_path = main_menu_paths[index] - self.test_case.assertTrue(actual_path.find(expected_path) > -1, - "\nExpected main menu path at index %i: %s\n Actual main menu path at index %i: %s" - "\nList of expected paths: %s" % - (index, expected_path, index, actual_path, expected_main_menu_paths)) diff --git a/tests/akvo/acceptance/web/navigation/navigation_test_suite.py b/tests/akvo/acceptance/web/navigation/navigation_test_suite.py deleted file mode 100644 index 67bec519d0..0000000000 --- a/tests/akvo/acceptance/web/navigation/navigation_test_suite.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from web.navigation.menu_navigation_test import MenuNavigationTest - - -def navigation_suite(): - return create_test_suite_from_classes([MenuNavigationTest]) - -if __name__ == "__main__": - run_test_suite(navigation_suite()) diff --git a/tests/akvo/acceptance/web/projects/__init__.py b/tests/akvo/acceptance/web/projects/__init__.py deleted file mode 100644 index ceb4daa4f1..0000000000 --- a/tests/akvo/acceptance/web/projects/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo web.projects acceptance test package. diff --git a/tests/akvo/acceptance/web/projects/project_view_counters_test.py b/tests/akvo/acceptance/web/projects/project_view_counters_test.py deleted file mode 100644 index 531d060534..0000000000 --- a/tests/akvo/acceptance/web/projects/project_view_counters_test.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * -from helpers.rsrpath import * -from helpers.testexecution import * - -from testcases.elementparsingtestcase import ElementParsingTestCase -from verifiers.viewcountverifier import ViewCountVerifier - - -class ProjectViewCountersTest(ElementParsingTestCase): - - def setUp(self): - self.count_verifier = ViewCountVerifier(self) - - def test_01_home_page_has_view_counters_for_featured_projects(self): - """web.projects.ProjectViewCountersTest 1. Home page has view counters for featured projects""" - - self.count_verifier.open_page(home_page_path()) - self.count_verifier.expect_exactly(3).view_counters_and_counter_identifiers_with_xpaths("//div[@class='featured_update']/div/div/p[2]", - "//div[@class='featured_update']/div/div/span/img/@src") - - def test_02_project_listing_page_has_view_counters_for_featured_projects(self): - """web.projects.ProjectViewCountersTest 2. Project listing page has view counters for featured projects""" - - self.count_verifier.open_page(project_listing_path()) - self.count_verifier.expect_exactly(13).view_counts_on_page() # includes view counts for listed projects on the same page - self.count_verifier.expect_exactly(3).view_counter_images_on_page() # currently only for the featured projects - self.count_verifier.expect_exactly(3).standard_view_counters_at_xpath("//table[@id='project_showcase']/tr/td/div[3]/span") - - def test_03_project_listing_page_has_view_counters_for_each_listed_project(self): - """web.projects.ProjectViewCountersTest 3. Project listing page has view counters for each listed project""" - - self.count_verifier.open_page(project_listing_path()) - self.count_verifier.expect_exactly(13).view_counts_on_page() # includes view counts for listed projects on the same page - self.count_verifier.expect_exactly(3).view_counter_images_on_page() # currently only for the featured projects - - # listed projects don't yet have counter images so we use the project URL as the view counter identifier - self.count_verifier.expect_exactly(10).view_counters_and_counter_identifiers_with_xpaths("//table[@id='project_table']/tr/td/p", - "//table[@id='project_table']/tr/td[1]/a[1]/@href") - - def test_04_project_page_has_view_counter(self): - """web.projects.ProjectViewCountersTest 4. Project page has view counter""" - - self.count_verifier.open_page(project_path(170)) - self.count_verifier.expect_exactly(1).standard_view_counter_at_xpath("//div[@id='outer_leftwing']/div/h1/span") - - def test_05_project_updates_page_has_view_counter(self): - """web.projects.ProjectViewCountersTest 5. Project updates page has view counter""" - - self.count_verifier.open_page(project_updates_path(170)) - self.count_verifier.expect_exactly(1).standard_view_counter_at_xpath("//div[@id='outer_leftwing']/div/h1/span") - - -def suite(): - return load_tests_from(ProjectViewCountersTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/web/projects/projects_test_suite.py b/tests/akvo/acceptance/web/projects/projects_test_suite.py deleted file mode 100644 index e1b516984d..0000000000 --- a/tests/akvo/acceptance/web/projects/projects_test_suite.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from web.projects.project_view_counters_test import ProjectViewCountersTest - - -def projects_suite(): - return create_test_suite_from_classes([ProjectViewCountersTest]) - -if __name__ == "__main__": - run_test_suite(projects_suite()) diff --git a/tests/akvo/acceptance/web/web_test_suite.py b/tests/akvo/acceptance/web/web_test_suite.py deleted file mode 100644 index 6c9137c7ff..0000000000 --- a/tests/akvo/acceptance/web/web_test_suite.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.general.general_test_suite import general_suite -from web.navigation.navigation_test_suite import navigation_suite -# from web.home.home_page_test_suite import home_page_suite -# from web.projects.projects_test_suite import projects_suite -# from web.widgets.widgets_test_suite import widgets_suite - - -def web_suite(): - return create_test_suite_from_suites([general_suite(), navigation_suite()]) - -if __name__ == "__main__": - run_test_suite(web_suite()) - SeleniumClient().stop() diff --git a/tests/akvo/acceptance/web/widgets/__init__.py b/tests/akvo/acceptance/web/widgets/__init__.py deleted file mode 100644 index 2827bf4110..0000000000 --- a/tests/akvo/acceptance/web/widgets/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the Akvo web.widgets acceptance test package. diff --git a/tests/akvo/acceptance/web/widgets/widget_view_counters_test.py b/tests/akvo/acceptance/web/widgets/widget_view_counters_test.py deleted file mode 100644 index 1eca6b26be..0000000000 --- a/tests/akvo/acceptance/web/widgets/widget_view_counters_test.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.rsrpath import * -from helpers.testexecution import * - -from testcases.elementparsingtestcase import ElementParsingTestCase -from verifiers.viewcountverifier import ViewCountVerifier - - -class WidgetViewCountersTest(ElementParsingTestCase): - - def setUp(self): - self.count_verifier = ViewCountVerifier(self) - - def test_01_narrow_cobranded_widget_has_view_counter_in_footer(self): - """web.widgets.WidgetViewCountersTest 1. Narrow cobranded widget has view counter in footer""" - - self.verify_widget_has_standard_view_counter_in_footer("cobranded-narrow") - - def test_02_short_cobranded_widget_has_view_counter_in_footer(self): - """web.widgets.WidgetViewCountersTest 2. Short cobranded widget has view counter in footer""" - - self.verify_widget_has_standard_view_counter_in_footer("cobranded-short") - - def test_03_cobranded_banner_widget_has_view_counter_in_header(self): - """web.widgets.WidgetViewCountersTest 3. Cobranded banner widget has view counter in header""" - - self.verify_widget_has_standard_view_counter_in_header("cobranded-banner") - - def test_04_cobranded_leader_widget_has_view_counter_in_header(self): - """web.widgets.WidgetViewCountersTest 4. Cobranded leader widget has view counter in header""" - - self.verify_widget_has_standard_view_counter_in_header("cobranded-leader") - - def test_05_narrow_project_widget_has_view_counter_in_footer(self): - """web.widgets.WidgetViewCountersTest 5. Narrow project widget has view counter in footer""" - - self.verify_widget_has_standard_view_counter_in_footer("project-narrow") - - def test_06_project_updates_widget_has_view_counter_in_footer(self): - """web.widgets.WidgetViewCountersTest 6. Project updates widget has view counter in footer""" - - self.verify_widget_has_standard_view_counter_in_footer("project-updates") - - def test_07_project_widget_with_donation_link_has_view_counter_in_footer(self): - """web.widgets.WidgetViewCountersTest 7. Project widget with donation link has view counter in footer""" - - self.verify_widget_has_standard_view_counter_in_footer("project-contribute") - - def test_08_small_project_widget_has_view_counter_in_header(self): - """web.widgets.WidgetViewCountersTest 8. Small project widget has view counter in header""" - - self.verify_widget_has_standard_view_counter_at_xpath("project-small", "//div[@id='header']/div/span") - - def test_09_side_feature_project_widget_with_donation_link_has_view_counter_in_footer(self): - """web.widgets.WidgetViewCountersTest 9. Side feature project widget with donation link has view counter in footer""" - - self.verify_widget_has_standard_view_counter_in_footer("feature-side") - - def verify_widget_has_standard_view_counter_in_footer(self, widget_type): - self.verify_widget_has_standard_view_counter_at_xpath(widget_type, "//div[@id='footer']/div/span") - - def verify_widget_has_standard_view_counter_in_header(self, widget_type): - self.verify_widget_has_standard_view_counter_at_xpath(widget_type, "//div[@id='header']/span") - - def verify_widget_has_standard_view_counter_at_xpath(self, widget_type, view_count_xpath): - self.count_verifier.open_page(project_widget_path(108, widget_type)) - self.count_verifier.expect_exactly(1).view_counter_on_page() - self.count_verifier.expect_exactly(1).standard_view_counter_at_xpath(view_count_xpath) - - def test_10_project_listing_widget_has_view_counter_images_for_each_listed_project(self): - """web.widgets.WidgetViewCountersTest 10. Project listing widget has view counter images for each listed project""" - - self.count_verifier.open_page(project_listing_widget_path_for_organisation(15)) - self.count_verifier.expect_exactly(12).view_counts_on_page() - self.count_verifier.expect_exactly(0).view_counter_images_on_page() - self.count_verifier.expect_exactly(12).view_counters_and_counter_identifiers_with_xpaths("//table[1]/tr/td[1]/div/span", - "//table[1]/tr/td[1]/div/a/@href") - - -def suite(): - return load_tests_from(WidgetViewCountersTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/akvo/acceptance/web/widgets/widgets_test_suite.py b/tests/akvo/acceptance/web/widgets/widgets_test_suite.py deleted file mode 100644 index 7776e138a7..0000000000 --- a/tests/akvo/acceptance/web/widgets/widgets_test_suite.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from web.widgets.widget_view_counters_test import WidgetViewCountersTest - - -def widgets_suite(): - return create_test_suite_from_classes([WidgetViewCountersTest]) - -if __name__ == "__main__": - run_test_suite(widgets_suite()) diff --git a/tests/pvw/acceptance/all_test_suites.py b/tests/pvw/acceptance/all_test_suites.py deleted file mode 100644 index 65e64fcf12..0000000000 --- a/tests/pvw/acceptance/all_test_suites.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import os, sys - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from test_settings import SITE_UNDER_TEST - -from internal.internal_unittests_suite import unittests_suite -from web.web_test_suite import web_suite - - -def acceptance_test_suites(): - return create_test_suite_from_suites([web_suite()]) - -if __name__ == "__main__": - acceptance_test_root_path = os.path.realpath(os.path.dirname(__file__)) - print "Test suite root path: %s\n" % (acceptance_test_root_path) - - print "Running unit tests for acceptance test helpers\n" - if run_test_suite(unittests_suite()).wasSuccessful(): - print "\nRunning acceptance tests for: %s\n" % (SITE_UNDER_TEST) - run_test_suite(acceptance_test_suites()) - SeleniumClient().stop() - else: - print "\nUnable to run acceptance tests until the unit test errors above have been resolved\n" - sys.exit(1) diff --git a/tests/pvw/acceptance/extensions/__init__.py b/tests/pvw/acceptance/extensions/__init__.py deleted file mode 100644 index 6ea32ee6a4..0000000000 --- a/tests/pvw/acceptance/extensions/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the acceptance test extensions package. diff --git a/tests/pvw/acceptance/helpers/__init__.py b/tests/pvw/acceptance/helpers/__init__.py deleted file mode 100644 index cb3eb82d06..0000000000 --- a/tests/pvw/acceptance/helpers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the acceptance test helpers package. diff --git a/tests/pvw/acceptance/helpers/dwspaths.py b/tests/pvw/acceptance/helpers/dwspaths.py deleted file mode 100644 index 793c270b70..0000000000 --- a/tests/pvw/acceptance/helpers/dwspaths.py +++ /dev/null @@ -1,63 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -def home_page(): - return "/" - -def focus_areas_page(): - return cms_path("focus-areas") - -def projects_page(): - return rsr_path("projects") - -def all_projects_page(): - return rsr_path("projects/all") - -def netherlands_page(): - return cms_path("netherlands") - -def education_page(): - return cms_path("education") - -def directory_page(): - return cms_path("directory") - -def news_page(): - return "/news" - -def about_page(): - return cms_path("about") - -def open_license_page(): - return cms_path("open_license") - -def terms_of_use_page(): - return cms_path("terms_of_use") - -def privacy_policy_page(): - return cms_path("privacy_policy") - -def credits_page(): - return cms_path("credits") - -def admin_page(): - return cms_path("admin") - -def register_page(): - return rsr_path("accounts/register1") - -def sign_in_page(): - return rsr_path("signin/?next=%s" % all_projects_page()) - -def contact_us_page(): - return cms_path("contact_us") - -def akvo_home_page(): - return "http://www.akvo.org" - -def rsr_path(subpath): - return "/rsr/%s" % subpath - -def cms_path(cms_page_name): - return "/web/%s" % cms_page_name diff --git a/tests/pvw/acceptance/helpers/dwsurls.py b/tests/pvw/acceptance/helpers/dwsurls.py deleted file mode 100644 index 49de7caaa0..0000000000 --- a/tests/pvw/acceptance/helpers/dwsurls.py +++ /dev/null @@ -1,38 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from test_settings import SITE_UNDER_TEST - -from helpers.dwspaths import * - - -def home_page_url(): - return SITE_UNDER_TEST - -def focus_areas_url(): - return _full_url(focus_areas_page()) - -def projects_url(): - return _full_url(projects_page()) - -def all_projects_url(): - return _full_url(all_projects_page()) - -def netherlands_url(): - return _full_url(netherlands_page()) - -def education_url(): - return _full_url(education_page()) - -def directory_url(): - return _full_url(directory_page()) - -def news_url(): - return _full_url(news_page()) - -def about_url(): - return _full_url(about_page()) - -def _full_url(path): - return "%s%s" % (SITE_UNDER_TEST, path) diff --git a/tests/pvw/acceptance/helpers/elementparsing.py b/tests/pvw/acceptance/helpers/elementparsing.py deleted file mode 100644 index c17ebd86b9..0000000000 --- a/tests/pvw/acceptance/helpers/elementparsing.py +++ /dev/null @@ -1,28 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import urllib2 - -from lxml import etree - - -def create_xml_element_root_from(url): - return etree.XML(read_text_from(url)) - -def create_html_element_root_from(url): - return etree.HTML(read_text_from(url)) - -def read_text_from(url): - headers = {"Cache-Control": "no-cache, no-store, max-age=0", "Pragma": "no-cache", "Connection": "close"} - return urllib2.urlopen(urllib2.Request(url, None, headers)).read() - -def elements_to_string(element_root): - return etree.tostring(element_root, pretty_print=True) - -def text_values_at_xpath(element_search_root, elements_xpath): - trimmed_text_values = map(lambda text: text.strip(), values_at_xpath(element_search_root, "%s/text()" % elements_xpath)) - return filter(lambda text: len(text) > 0, trimmed_text_values) - -def values_at_xpath(element_search_root, values_xpath): - return element_search_root.xpath(values_xpath) diff --git a/tests/pvw/acceptance/helpers/gmailreader.py b/tests/pvw/acceptance/helpers/gmailreader.py deleted file mode 100644 index 1dbf1a6e68..0000000000 --- a/tests/pvw/acceptance/helpers/gmailreader.py +++ /dev/null @@ -1,31 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from test_settings import * - -from helpers.navigation import SeleniumNavigator - -class GMailReader: - - GMAIL_INBOX_URL = "http://mail.google.com/mail/?ui=html&hl=en-GB" # basic HTML view with UK English - - def __init__(self, selenium_client): - self.selenium = selenium_client - self.navigator = SeleniumNavigator(self.selenium) - - def open_inbox(self): - self.navigator.open_page(self.GMAIL_INBOX_URL) - - if self.field_with_id_exists("Email") and self.field_with_id_exists("Passwd"): - self.selenium.type("Email", GMAIL_USERNAME) - self.selenium.type("Passwd", GMAIL_PASSWORD) - self.navigator.click_button("signIn") - self.navigator.open_page(self.GMAIL_INBOX_URL) - - def search_inbox_for_text(self, search_text): - self.selenium.type("q", search_text) - self.navigator.click_button("nvp_site_mail") - - def field_with_id_exists(self, expected_field_id): - return self.selenium.is_element_present("//input[@id=\"%s\"]" % (expected_field_id)) diff --git a/tests/pvw/acceptance/helpers/navigation.py b/tests/pvw/acceptance/helpers/navigation.py deleted file mode 100644 index 57b42d0300..0000000000 --- a/tests/pvw/acceptance/helpers/navigation.py +++ /dev/null @@ -1,101 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The SeleniumNavigator and RSRNavigator facilitate common navigation operations - -from test_settings import * - -from helpers.dwspaths import * - - -class SeleniumNavigator: - - def __init__(self, selenium_client): - self.selenium = selenium_client - - def wait_for_page_to_load(self): - self.selenium.wait_for_page_to_load(PAGE_LOAD_TIMEOUT) - - def open_page(self, path): - self.selenium.open(path) - self.wait_for_page_to_load() - - def click_element_at_path(self, element_path): - self.selenium.click(element_path) - self.wait_for_page_to_load() - - def click_link(self, link_text): - self.click_element_at_path("link=%s" % (link_text)) - - def click_tab(self, tab_element_path): - self.click_element_at_path(tab_element_path) - - def click_javascript_tab(self, tab_element_path): - self.selenium.click(tab_element_path) # client side, so no page load wait needed - - def click_button(self, button_name_or_path): - self.click_element_at_path(button_name_or_path) - - def click_submit_button(self): - self.click_button("//button[@type='submit']") - - def click_submit_button_with_text(self, button_text): - self.click_element_at_path("//input[@value=\"%s\"]" % (button_text)) - -class RSRNavigator: - - def __init__(self, selenium_client): - self.selenium = selenium_client - self.navigator = SeleniumNavigator(self.selenium) - - def open_home_page(self): - self.navigator.open_page("/") - - def open_admin_page(self, extended_admin_path = ""): - self.navigator.open_page("/rsr/admin/%s" % (extended_admin_path)) - if self.selenium.is_text_present("Password:"): - self.selenium.type("id_username", SUPERUSER_USERNAME) - self.selenium.type("id_password", SUPERUSER_PASSWORD) - self.navigator.click_submit_button_with_text("Log in") - - def open_auth_admin_page(self): - self.open_admin_page("auth/") - - def open_user_admin_page(self): - self.open_admin_page("auth/user/") - - def open_rsr_admin_page(self): - self.open_admin_page("rsr/") - - def open_project_page(self, project_number): - self.navigator.open_page("/rsr/project/%i/" % (project_number)) - -class DWSNavigator(RSRNavigator): - - def open_focus_areas_page(self): - self.open_page(focus_areas_page()) - - def open_projects_page(self): - self.open_page(projects_page()) - - def open_all_projects_page(self): - self.open_page(all_projects_page()) - - def open_netherlands_page(self): - self.open_page(netherlands_page()) - - def open_education_page(self): - self.open_page(education_page()) - - def open_directory_page(self): - self.open_page(directory_page()) - - def open_news_page(self): - self.open_page(news_page()) - - def open_about_page(self): - self.open_page(about_page()) - - def open_page(self, page_path): - self.navigator.open_page(page_path) diff --git a/tests/pvw/acceptance/helpers/seleniumclient.py b/tests/pvw/acceptance/helpers/seleniumclient.py deleted file mode 100644 index 0a2cddb5ee..0000000000 --- a/tests/pvw/acceptance/helpers/seleniumclient.py +++ /dev/null @@ -1,36 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# SeleniumClient provides a singleton wrapper to manage starting and stopping a Selenium RC client -# more easily for the duration of a single test case or over a suite of tests - -from selenium import selenium - -from test_settings import * - -class SeleniumClient: - - __instance = None - - def __init__(self): - if SeleniumClient.__instance is None: - self.start() - - def instance(self): - return SeleniumClient.__instance - - def start(self): - if SeleniumClient.__instance is None: - try: - SeleniumClient.__instance = selenium(SELENIUM_RC_HOST, SELENIUM_RC_PORT, BROWSER_ENVIRONMENT, SITE_UNDER_TEST) - SeleniumClient.__instance.start() - except Exception, exception: - print ">> Unable to start Selenium RC client: %s" % (exception) - raise exception - - def stop(self): - try: - SeleniumClient.__instance.stop() - except Exception, exception: - print ">> Unable to stop Selenium RC client: %s" % (exception) diff --git a/tests/pvw/acceptance/helpers/testexecution.py b/tests/pvw/acceptance/helpers/testexecution.py deleted file mode 100644 index 86f8db463c..0000000000 --- a/tests/pvw/acceptance/helpers/testexecution.py +++ /dev/null @@ -1,26 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from test_settings import TEST_MODE - - -def create_test_suite_from_classes(test_class_list): - return create_test_suite_from_suites(map(lambda test_class: load_tests_from(test_class), test_class_list)) - -def create_test_suite_from_suites(test_suite_list): - return nose.suite.LazySuite(test_suite_list) - -def load_tests_from(test_case): - return nose.loader.TestLoader().loadTestsFromTestCase(test_case) - -def run_test_suite(suite): - test_runner = nose.core.TextTestRunner(verbosity=2) - - if TEST_MODE == 'ci': - from teamcity.unittestpy import TeamcityTestRunner - test_runner = TeamcityTestRunner() - - return test_runner.run(suite) diff --git a/tests/pvw/acceptance/helpers/unittests/__init__.py b/tests/pvw/acceptance/helpers/unittests/__init__.py deleted file mode 100644 index dcd8b55a6e..0000000000 --- a/tests/pvw/acceptance/helpers/unittests/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the helpers.unittests package. diff --git a/tests/pvw/acceptance/helpers/unittests/dwspaths_test.py b/tests/pvw/acceptance/helpers/unittests/dwspaths_test.py deleted file mode 100644 index 58947725ad..0000000000 --- a/tests/pvw/acceptance/helpers/unittests/dwspaths_test.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.dwspaths import * -from helpers.testexecution import * - - -class DWSPathsTest(TestCase): - - def test_can_get_home_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Home page""" - - self.verify_path("/", home_page()) - - def test_can_get_focus_areas_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Focus Areas page""" - - self.verify_path("/web/focus-areas", focus_areas_page()) - - def test_can_get_projects_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Projects page""" - - self.verify_path("/rsr/projects", projects_page()) - - def test_can_get_all_projects_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for All Projects page""" - - self.verify_path("/rsr/projects/all", all_projects_page()) - - def test_can_get_netherlands_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Netherlands page""" - - self.verify_path("/web/netherlands", netherlands_page()) - - def test_can_get_education_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Education page""" - - self.verify_path("/web/education", education_page()) - - def test_can_get_directory_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Directory page""" - - self.verify_path("/web/directory", directory_page()) - - def test_can_get_news_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for News page""" - - self.verify_path("/news", news_page()) - - def test_can_get_about_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for About page""" - - self.verify_path("/web/about", about_page()) - - def test_can_get_open_license_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Open license page""" - - self.verify_path("/web/open_license", open_license_page()) - - def test_can_get_terms_of_use_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Terms of use page""" - - self.verify_path("/web/terms_of_use", terms_of_use_page()) - - def test_can_get_privacy_policy_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Privacy policy page""" - - self.verify_path("/web/privacy_policy", privacy_policy_page()) - - def test_can_get_credits_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Credits page""" - - self.verify_path("/web/credits", credits_page()) - - def test_can_get_admin_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Admin page""" - - self.verify_path("/web/admin", admin_page()) - - def test_can_get_register_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Register page""" - - self.verify_path("/rsr/accounts/register1", register_page()) - - def test_can_get_sign_in_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Sign in page""" - - self.verify_path("/rsr/signin/?next=/rsr/projects/all", sign_in_page()) - - def test_can_get_contact_us_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Contact us page""" - - self.verify_path("/web/contact_us", contact_us_page()) - - def test_can_get_akvo_home_page_path(self): - """helpers.unittests.DWSPathsTest Can get path for Akvo home page""" - - self.verify_path("http://www.akvo.org", akvo_home_page()) - - def verify_path(self, expected_path, actual_path): - self.failUnlessEqual(expected_path, actual_path, "\nExpected path: %s\n Actual path: %s" % (expected_path, actual_path)) - - -def suite(): - return load_tests_from(DWSPathsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/pvw/acceptance/helpers/unittests/dwsurls_test.py b/tests/pvw/acceptance/helpers/unittests/dwsurls_test.py deleted file mode 100644 index 18337562db..0000000000 --- a/tests/pvw/acceptance/helpers/unittests/dwsurls_test.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.dwspaths import * -from helpers.dwsurls import * -from helpers.testexecution import * - - -class DWSURLsTest(TestCase): - - def test_can_get_home_page_url(self): - """helpers.unittests.DWSURLsTest Can get URL for Home page""" - - self.verify_url(SITE_UNDER_TEST, home_page_url()) - - def test_can_get_focus_areas_url(self): - """helpers.unittests.DWSURLsTest Can get URL for Focus Areas page""" - - self.verify_url(self.full_url(focus_areas_page()), focus_areas_url()) - - def test_can_get_projects_url(self): - """helpers.unittests.DWSURLsTest Can get URL for Projects page""" - - self.verify_url(self.full_url(projects_page()), projects_url()) - - def test_can_get_all_projects_url(self): - """helpers.unittests.DWSURLsTest Can get URL for All Projects page""" - - self.verify_url(self.full_url(all_projects_page()), all_projects_url()) - - def test_can_get_netherlands_url(self): - """helpers.unittests.DWSURLsTest Can get URL for Netherlands page""" - - self.verify_url(self.full_url(netherlands_page()), netherlands_url()) - - def test_can_get_education_url(self): - """helpers.unittests.DWSURLsTest Can get URL for Education page""" - - self.verify_url(self.full_url(education_page()), education_url()) - - def test_can_get_directory_url(self): - """helpers.unittests.DWSURLsTest Can get URL for Directory page""" - - self.verify_url(self.full_url(directory_page()), directory_url()) - - def test_can_get_news_url(self): - """helpers.unittests.DWSURLsTest Can get URL for News page""" - - self.verify_url(self.full_url(news_page()), news_url()) - - def test_can_get_about_url(self): - """helpers.unittests.DWSURLsTest Can get URL for About page""" - - self.verify_url(self.full_url(about_page()), about_url()) - - def full_url(self, path): - return "%s%s" % (SITE_UNDER_TEST, path) - - def verify_url(self, expected_url, actual_url): - self.failUnlessEqual(expected_url, actual_url, "\nExpected URL: %s\n Actual URL: %s" % (expected_url, actual_url)) - - -def suite(): - return load_tests_from(DWSURLsTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/pvw/acceptance/helpers/unittests/helpers_test_suite.py b/tests/pvw/acceptance/helpers/unittests/helpers_test_suite.py deleted file mode 100644 index 092024548f..0000000000 --- a/tests/pvw/acceptance/helpers/unittests/helpers_test_suite.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from helpers.unittests.dwspaths_test import DWSPathsTest -from helpers.unittests.dwsurls_test import DWSURLsTest - - -def helpers_suite(): - return create_test_suite_from_classes([DWSPathsTest, DWSURLsTest]) - -if __name__ == "__main__": - run_test_suite(helpers_suite()) diff --git a/tests/pvw/acceptance/internal/__init__.py b/tests/pvw/acceptance/internal/__init__.py deleted file mode 100644 index 72b97b184d..0000000000 --- a/tests/pvw/acceptance/internal/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the acceptance testing internal package. diff --git a/tests/pvw/acceptance/internal/internal_unittests_suite.py b/tests/pvw/acceptance/internal/internal_unittests_suite.py deleted file mode 100644 index add75502ef..0000000000 --- a/tests/pvw/acceptance/internal/internal_unittests_suite.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from helpers.unittests.helpers_test_suite import helpers_suite - - -def unittests_suite(): - return create_test_suite_from_suites([helpers_suite()]) - -if __name__ == "__main__": - run_test_suite(unittests_suite()) diff --git a/tests/pvw/acceptance/test_settings.py.template b/tests/pvw/acceptance/test_settings.py.template deleted file mode 100644 index 9bbf29a008..0000000000 --- a/tests/pvw/acceptance/test_settings.py.template +++ /dev/null @@ -1,30 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The following values are used in the DWS acceptance tests - -import os - -# options are 'normal' or 'ci' for continuous integration -TEST_MODE = 'normal' - -BROWSER_ENVIRONMENT = "*firefox" -SELENIUM_RC_HOST = "localhost" -SELENIUM_RC_PORT = 4444 - -SUPERUSER_USERNAME = 'your_username' -SUPERUSER_PASSWORD = 'your_password' - -UAT_EMAIL_ADDRESS = "gmail_address" -GMAIL_USERNAME = "gmail_username" -GMAIL_PASSWORD = "gmail_password" - -SITE_UNDER_TEST = "http://pvw-dev.akvo.org" -ORGANISATION_NAME = "DutchWaterSector" - -PAGE_LOAD_TIMEOUT_IN_SECONDS = 120 -PAGE_LOAD_TIMEOUT = PAGE_LOAD_TIMEOUT_IN_SECONDS * 1000 - -TESTS_ROOT_DIR = os.path.realpath(os.path.dirname(__file__)) -TEST_IMAGES_DIR = os.path.join(TESTS_ROOT_DIR, 'images') diff --git a/tests/pvw/acceptance/test_settings_ci.py b/tests/pvw/acceptance/test_settings_ci.py deleted file mode 100644 index 85bab314e9..0000000000 --- a/tests/pvw/acceptance/test_settings_ci.py +++ /dev/null @@ -1,30 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# The following values are used in the DWS acceptance tests - -import os - -# options are 'normal' or 'ci' for continuous integration -TEST_MODE = 'ci' - -BROWSER_ENVIRONMENT = "*firefox /usr/bin/firefox-bin" -SELENIUM_RC_HOST = "localhost" -SELENIUM_RC_PORT = 4444 - -SUPERUSER_USERNAME = 'not_yet_allocated' -SUPERUSER_PASSWORD = 'not_yet_allocated' - -UAT_EMAIL_ADDRESS = "akvo.uat@gmail.com" -GMAIL_USERNAME = "akvo.uat" -GMAIL_PASSWORD = "R4inDr0p" - -SITE_UNDER_TEST = "http://pvw-dev.akvo.org" -ORGANISATION_NAME = "DutchWaterSector" - -PAGE_LOAD_TIMEOUT_IN_SECONDS = 180 -PAGE_LOAD_TIMEOUT = PAGE_LOAD_TIMEOUT_IN_SECONDS * 1000 - -TESTS_ROOT_DIR = os.path.realpath(os.path.dirname(__file__)) -TEST_IMAGES_DIR = os.path.join(TESTS_ROOT_DIR, 'images') diff --git a/tests/pvw/acceptance/testcases/__init__.py b/tests/pvw/acceptance/testcases/__init__.py deleted file mode 100644 index 6252100989..0000000000 --- a/tests/pvw/acceptance/testcases/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the testcases package. diff --git a/tests/pvw/acceptance/testcases/seleniumtestcase.py b/tests/pvw/acceptance/testcases/seleniumtestcase.py deleted file mode 100644 index 6deaececc8..0000000000 --- a/tests/pvw/acceptance/testcases/seleniumtestcase.py +++ /dev/null @@ -1,104 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# SeleniumTestCase extends unittest.TestCase to add convenience methods for common assertion patterns - -from selenium import selenium -from unittest import TestCase - -from test_settings import * - -from helpers.seleniumclient import SeleniumClient - -class SeleniumTestCase(TestCase): - - @classmethod - def setup_class(cls): - cls.selenium = SeleniumClient().instance() - - def setUp(self): - self.verification_errors = [] - - def tearDown(self): - self.failUnlessEqual([], self.verification_errors) - - def assert_location_contains(self, expected_text): - self.failIf(self.selenium.get_location().find(expected_text) == -1, - "\nPage URL should contain: %s\n Actual URL: %s" % (expected_text, self.selenium.get_location())) - - def assert_title_is(self, expected_title): - self.failUnlessEqual(expected_title, self.selenium.get_title(), - "\nExpected page title: %s\n Actual page title: %s" % (expected_title, self.selenium.get_title())) - - def assert_title_starts_with(self, expected_title_start): - self.failUnless(self.selenium.get_title().startswith(expected_title_start), - "\nPage title should start with: %s\n Actual page title: %s" % - (expected_title_start, self.selenium.get_title())) - - def assert_title_contains(self, expected_title_content): - self.failIf(self.selenium.get_title().find(expected_title_content) == -1, - "\nPage title should contain: %s\n Actual page title: %s" % - (expected_title_content, self.selenium.get_title())) - - def assert_page_contains_text(self, expected_text): - self.failUnless(self.selenium.is_text_present(expected_text), "Page should contain: %s" % (expected_text)) - - def assert_page_does_not_contain_text(self, unexpected_text): - self.failIf(self.selenium.is_text_present(unexpected_text), "Page should not contain: %s" % (unexpected_text)) - - def assert_page_contains_text_items(self, list_of_expected_text_items): - for expected_text in list_of_expected_text_items: - self.assert_page_contains_text(expected_text) - - def assert_page_does_not_contain_text_items(self, list_of_unexpected_text_items): - for unexpected_text in list_of_unexpected_text_items: - self.assert_page_does_not_contain_text(unexpected_text) - - def verify_text_at_path(self, expected_text, text_xpath): - actual_text = self.selenium.get_text(text_xpath) - self.failUnlessEqual(expected_text, actual_text, - "\nExpected text at %s: %s\nActual text: %s" % (text_xpath, expected_text, actual_text)) - - def verify_field_is_required_warning_at_path(self, expected_warning_xpath): - self.verify_text_at_path("This field is required.", expected_warning_xpath) - - def verify_attribute_value_at_path(self, expected_attribute_value, attribute_xpath): - actual_attribute_value = self.selenium.get_attribute(attribute_xpath) - self.failUnlessEqual(expected_attribute_value, actual_attribute_value, - "\nExpected attribute value at %s: %s\nActual attribute value: %s" % - (attribute_xpath, expected_attribute_value, actual_attribute_value)) - - def verify_element_size_at_path(self, expected_element_width, expected_element_height, element_path): - actual_element_width = int(self.selenium.get_element_width(element_path)) - actual_element_height = int(self.selenium.get_element_height(element_path)) - self.failUnlessEqual(expected_element_width, actual_element_width, - "\nExpected element width at %s: %i\nActual element width: %i" % - (element_path, expected_element_width, actual_element_width)) - self.failUnlessEqual(expected_element_height, actual_element_height, - "\nExpected element height at %s: %i\nActual element height: %i" % - (element_path, expected_element_height, actual_element_height)) - - def assert_link_exists(self, expected_link_text): - self.failUnless(self.selenium.is_element_present("link=%s" % (expected_link_text)), - "Expected [%s] link to exist" % (expected_link_text)) - - def assert_links_exist(self, expected_link_text_list): - for expected_link_text in expected_link_text_list: - self.assert_link_exists(expected_link_text) - - def assert_link_exists_starting_with_text(self, expected_link_text): - self.failUnless(self.selenium.is_element_present("link=%s*" % (expected_link_text)), - "Expected link starting with [%s] to exist" % (expected_link_text)) - - def assert_links_exist_starting_with_text(self, expected_link_text_list): - for expected_link_text in expected_link_text_list: - self.assert_link_exists_starting_with_text(expected_link_text) - - def assert_submit_button_with_text_exists(self, expected_button_text): - self.failUnless(self.selenium.is_element_present("//input[@value=\"%s\"]" % (expected_button_text)), - "Expected [%s] button to exist" % (expected_button_text)) - - def assert_field_with_id_exists(self, expected_field_id): - self.failUnless(self.selenium.is_element_present("//input[@id=\"%s\"]" % (expected_field_id)), - "Expected field with ID: [%s]" % (expected_field_id)) diff --git a/tests/pvw/acceptance/testcases/webtestcase.py b/tests/pvw/acceptance/testcases/webtestcase.py deleted file mode 100644 index 64844022a6..0000000000 --- a/tests/pvw/acceptance/testcases/webtestcase.py +++ /dev/null @@ -1,56 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.dwspaths import * -from helpers.navigation import DWSNavigator, SeleniumNavigator - -from testcases.seleniumtestcase import SeleniumTestCase - - -class DWSWebTestCase(SeleniumTestCase): - - def setUp(self): - SeleniumTestCase.setUp(self) - self.navigator = SeleniumNavigator(self.selenium) - self.site_navigator = DWSNavigator(self.selenium) - - def open_home_page(self): - self.site_navigator.open_home_page() - self.assert_title_is("Dutch Water Sector") - - def open_focus_areas_page(self): - self.site_navigator.open_focus_areas_page() - self.verify_location_and_page_title(focus_areas_page(), "Focus Areas | Dutch Water Sector") - - def open_projects_page(self): - self.site_navigator.open_projects_page() - self.verify_location_and_page_title(all_projects_page(), "Dutch Water Sector - All projects") - - def open_all_projects_page(self): - self.site_navigator.open_all_projects_page() - self.verify_location_and_page_title(all_projects_page(), "Dutch Water Sector - All projects") - - def open_netherlands_page(self): - self.site_navigator.open_netherlands_page() - self.verify_location_and_page_title(netherlands_page(), "The Netherlands now | Dutch Water Sector") - - def open_education_page(self): - self.site_navigator.open_education_page() - self.verify_location_and_page_title(education_page(), "Education | Dutch Water Sector") - - def open_directory_page(self): - self.site_navigator.open_directory_page() - self.verify_location_and_page_title(directory_page(), "Directory of Dutch Water Expertise | Dutch Water Sector") - - def open_news_page(self): - self.site_navigator.open_news_page() - self.verify_location_and_page_title(news_page(), "News | Dutch Water Sector") - - def open_about_page(self): - self.site_navigator.open_about_page() - self.verify_location_and_page_title(about_page(), "About | Dutch Water Sector") - - def verify_location_and_page_title(self, expected_location, expected_title): - self.assert_location_contains(expected_location) - self.assert_title_is(expected_title) diff --git a/tests/pvw/acceptance/users/__init__.py b/tests/pvw/acceptance/users/__init__.py deleted file mode 100644 index 414128cd3e..0000000000 --- a/tests/pvw/acceptance/users/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the user admin acceptance test package. diff --git a/tests/pvw/acceptance/users/organisation_selection_test.py b/tests/pvw/acceptance/users/organisation_selection_test.py deleted file mode 100644 index a66cd2391e..0000000000 --- a/tests/pvw/acceptance/users/organisation_selection_test.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from test_settings import * - -from seleniumclient import SeleniumClient -from users.useradmintestcase import UserAdminTestCase - -class OrganisationSelectionTest(UserAdminTestCase): - - @classmethod - def description(cls): - return "User registration - organisation selection tests" - - def test_01_cancel_link_on_organisation_selection_page_takes_user_back_to_home_page(self): - """>> 1. Cancel link on organisation selection page takes user back to home page""" - self.open_organisation_selection_page_for_user_registration() - self.navigator.click_link("Cancel") - self.verify_home_page_has_loaded() - - def test_02_organisation_selection_page_warns_if_organisation_is_not_selected(self): - """>> 2. Organisation selection page warns if organisation is not selected""" - self.open_organisation_selection_page_for_user_registration() - self.navigator.click_submit_button_with_text("Continue") - - try: - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Set up your account - Step 1", - "Select the organisation that you belong to", - "This field is required"]) - except AssertionError, error: - self.fail("Expected warning if organisation was not selected: %s" % (error)) - - def test_03_can_select_organisation_and_load_user_details_entry_page(self): - """>> 3. Can select organisation and load user details entry page""" - self.select_organisation_and_open_user_details_entry_page() - self.assert_page_contains_text_items(["Set up your account - Step 2", - "Enter a username", - "Enter your first and last name", - "Enter a password", - "Enter your email address"]) - self.assert_link_exists("Cancel") - self.assert_submit_button_with_text_exists("Continue") - - -def suite(): - return nose.loader.TestLoader().loadTestsFromTestCase(OrganisationSelectionTest) - -if __name__ == "__main__": - nose.core.TextTestRunner(verbosity=2).run(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/users/rsruser.py b/tests/pvw/acceptance/users/rsruser.py deleted file mode 100644 index 3ef6d3b3bf..0000000000 --- a/tests/pvw/acceptance/users/rsruser.py +++ /dev/null @@ -1,18 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -class RSRUser: - - def __init__(self, selenium_client): - self.selenium = selenium_client - - def register_with(self, user_name, first_name, last_name, password, password_confirmation, email, email_confirmation): - sel = self.selenium - sel.type("id_username", user_name) - sel.type("id_first_name", first_name) - sel.type("id_last_name", last_name) - sel.type("id_password1", password) - sel.type("id_password2", password_confirmation) - sel.type("id_email", email) - sel.type("id_email2", email_confirmation) diff --git a/tests/pvw/acceptance/users/sign_in_or_register_test.py b/tests/pvw/acceptance/users/sign_in_or_register_test.py deleted file mode 100644 index 95370fea18..0000000000 --- a/tests/pvw/acceptance/users/sign_in_or_register_test.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from test_settings import * - -from seleniumclient import SeleniumClient -from users.useradmintestcase import UserAdminTestCase - -class SignInOrRegisterTest(UserAdminTestCase): - - @classmethod - def description(cls): - return "Sign in or register tests" - - def test_01_home_page_has_sign_in_link(self): - """>> 1. Home page has Sign in link""" - self.rsr.open_home_page() - self.assert_title_is(ORGANISATION_NAME) - self.assert_link_exists("Sign In") - - def test_02_sign_in_link_loads_sign_in_or_register_page(self): - """>> 2. Sign in link loads sign-in-or-register page""" - self.open_sign_in_or_register_page() - self.assert_page_contains_text_items(["I have an online account", - "Enter username", - "Enter password", - "I forgot my username and/or password", - "I don't have an online account", - "Register and you'll be able to", - "Create updates on your organisation's projects", - "Leave comments on projects", - "Get Started now"]) - self.assert_link_exists("Register") - self.assert_link_exists("I forgot my username and/or password") - - def test_03_register_link_loads_organisation_selection_page(self): - """>> 3. Register link loads organisation selection page""" - self.open_organisation_selection_page_for_user_registration() - self.assert_page_contains_text_items(["Set up your account - Step 1", - "Select the organisation that you belong to"]) - self.assert_link_exists("Cancel") - self.assert_submit_button_with_text_exists("Continue") - - -def suite(): - return nose.loader.TestLoader().loadTestsFromTestCase(SignInOrRegisterTest) - -if __name__ == "__main__": - nose.core.TextTestRunner(verbosity=2).run(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/users/user_admin_test_suite.py b/tests/pvw/acceptance/users/user_admin_test_suite.py deleted file mode 100644 index f752d51af9..0000000000 --- a/tests/pvw/acceptance/users/user_admin_test_suite.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from seleniumclient import SeleniumClient - -from users.sign_in_or_register_test import SignInOrRegisterTest -from users.organisation_selection_test import OrganisationSelectionTest -from users.user_details_entry_test import UserDetailsEntryTest -from users.user_registration_test import UserRegistrationTest - -def user_admin_suite(): - print "RSR user admin test suite:" - - return nose.suite.LazySuite([load_tests_from(SignInOrRegisterTest), - load_tests_from(OrganisationSelectionTest), - load_tests_from(UserDetailsEntryTest), - load_tests_from(UserRegistrationTest)]) - -def load_tests_from(test_case): - return nose.loader.TestLoader().loadTestsFromTestCase(test_case) - -if __name__ == "__main__": - nose.core.TextTestRunner(verbosity=2).run(user_admin_suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/users/user_details_entry_test.py b/tests/pvw/acceptance/users/user_details_entry_test.py deleted file mode 100644 index 5dc9df0c44..0000000000 --- a/tests/pvw/acceptance/users/user_details_entry_test.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from test_settings import * - -from seleniumclient import SeleniumClient -from users.useradmintestcase import UserAdminTestCase - -class UserDetailsEntryTest(UserAdminTestCase): - - TEST_ACCOUNT_NAME = "UserRegistrationTest" - - @classmethod - def description(cls): - return "User registration - user details entry tests" - - def test_01_cancel_link_on_user_details_entry_page_takes_user_back_to_home_page(self): - """>> 1. Cancel link on user details entry page takes user back to home page""" - self.select_organisation_and_open_user_details_entry_page() - self.navigator.click_link("Cancel") - self.verify_home_page_has_loaded() - - def test_02_user_details_entry_page_warns_if_no_user_details_entered(self): - """>> 2. User details entry page warns if no user details are entered""" - self.select_organisation_and_open_user_details_entry_page() - self.navigator.click_submit_button_with_text("Continue") - - try: - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Set up your account - Step 2", - "Error when registering", - "Please review messages below"]) - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[2]/div") - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[3]/div[1]") - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[3]/div[2]") - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[4]/div[1]") - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[4]/div[2]") - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[5]/div[1]") - self.verify_field_is_required_warning_at_path("//div[@id='maincontainer']/div[1]/div/form/fieldset/ul/li[5]/div[2]") - - except AssertionError, error: - self.fail("Expected warnings for missing user details: %s" % (error)) - - def test_03_user_details_entry_page_warns_if_passwords_do_not_match(self): - """>> 3. User details entry page warns if passwords do not match""" - self.select_organisation_and_open_user_details_entry_page() - self.rsr_user.register_with(self.TEST_ACCOUNT_NAME, "UserRegistration", "Test", "abc", "xyz", - UAT_EMAIL_ADDRESS, UAT_EMAIL_ADDRESS) - self.navigator.click_submit_button_with_text("Continue") - - try: - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Set up your account - Step 2", - "Error when registering", - "Passwords do not match"]) - except AssertionError, error: - self.fail("Expected warnings for mismatched passwords: %s" % (error)) - - def test_04_user_details_entry_page_warns_if_email_addresses_do_not_match(self): - """>> 4. User details entry page warns if email addresses do not match""" - self.select_organisation_and_open_user_details_entry_page() - self.rsr_user.register_with(self.TEST_ACCOUNT_NAME, "UserRegistration", "Test", "deleteAfterTest", "deleteAfterTest", - UAT_EMAIL_ADDRESS, "nonmatching@address.kom") - self.navigator.click_submit_button_with_text("Continue") - - try: - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Set up your account - Step 2", - "Error when registering", - "Email addresses do not match"]) - except AssertionError, error: - self.fail("Expected warnings for mismatched email addresses: %s" % (error)) - - -def suite(): - return nose.loader.TestLoader().loadTestsFromTestCase(UserDetailsEntryTest) - -if __name__ == "__main__": - nose.core.TextTestRunner(verbosity=2).run(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/users/user_registration_test.py b/tests/pvw/acceptance/users/user_registration_test.py deleted file mode 100644 index b81eddbac3..0000000000 --- a/tests/pvw/acceptance/users/user_registration_test.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -import nose - -from test_settings import * - -from seleniumclient import SeleniumClient -from users.useradmintestcase import UserAdminTestCase - -class UserRegistrationTest(UserAdminTestCase): - - TEST_ACCOUNT_NAME = "UserRegistrationTest" - ACTIVATION_LINK_PREFIX = "%s/rsr/accounts/activate/" % (SITE_UNDER_TEST) - ACTIVATION_MESSAGE_SUBJECT = "Activate your RSR account" - - @classmethod - def description(cls): - return "User registration tests" - - def test_01_can_register_new_user(self): - """>> 1. Can register a new user""" - self.register_new_user_account() - - if self.selenium.is_text_present("Traceback"): - self.fail("Unable to register a new user:\nTraceback details:\n%s" % self.selenium.get_value("traceback_area")) - - self.assert_page_does_not_contain_text("Error when registering") - self.assert_title_is("%s - Registration complete" % (ORGANISATION_NAME)) - self.assert_page_contains_text_items(["Thank you", "Please check your email account"]) - - def test_02_user_details_entry_page_warns_if_username_is_already_in_use(self): - """>> 2. User details entry page warns if username is already in use""" - self.register_new_user_account() - - try: - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Set up your account - Step 2", - "Error when registering", - "A user with that username already exists"]) - except AssertionError, error: - self.fail("Expected warnings when username already in use: %s" % (error)) - - def test_03_user_details_entry_page_warns_if_email_address_is_already_in_use(self): - """>> 3. User details entry page warns if email address is already in use""" - self.register_new_user_account() - - try: - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Set up your account - Step 2", - "Error when registering", - "This email address is already in use", - "Please supply a different email address"]) - except AssertionError, error: - self.fail("Expected warnings when email address already in use: %s" % (error)) - - def test_04_can_activate_new_user_account(self): - """>> 4. Can activate new user account""" - self.open_activation_email() - - self.assert_link_exists_starting_with_text(self.ACTIVATION_LINK_PREFIX) - - activation_link = self.selenium.get_attribute("//div[@class='msg']/a[2]/@href") - - self.navigator.open_page(activation_link) - self.assert_page_does_not_contain_text("account activation failed") - self.assert_page_contains_text_items(["Thank you", - "Your account will be activated as soon as we have reviewed your request"]) - - self.delete_activation_email() - - def test_05_can_delete_user_account(self): - """>> 5. Can delete user account""" - self.open_user_admin_page() - self.verify_user_admin_page_has_loaded() - self.search_for_user_account(self.TEST_ACCOUNT_NAME) - - try: - self.assert_page_contains_text(self.TEST_ACCOUNT_NAME) - except AssertionError, error: - self.fail("Expected '%s' username to exist (added earlier) for testing deletion:\n%s" % - (self.TEST_ACCOUNT_NAME, error)) - - self.navigator.click_link(self.TEST_ACCOUNT_NAME) - self.assert_title_starts_with("Change user") - self.navigator.click_link("Delete") - self.assert_title_starts_with("Are you sure") - self.navigator.click_submit_button_with_text("Yes, I'm sure") - self.verify_user_admin_page_has_loaded() - self.assert_page_contains_text("The user \"%s\" was deleted successfully" % (self.TEST_ACCOUNT_NAME)) - self.search_for_user_account(self.TEST_ACCOUNT_NAME) - - try: - self.assert_page_does_not_contain_text(self.TEST_ACCOUNT_NAME) - except AssertionError, error: - self.fail("The '%s' username should not appear in user listing after deletion:\n%s" % - (self.TEST_ACCOUNT_NAME, error)) - - def register_new_user_account(self): - self.select_organisation_and_open_user_details_entry_page() - self.rsr_user.register_with(self.TEST_ACCOUNT_NAME, "UserRegistration", "Test", "deleteAfterTest", "deleteAfterTest", - UAT_EMAIL_ADDRESS, UAT_EMAIL_ADDRESS) - self.navigator.click_submit_button_with_text("Continue") - - def open_activation_email(self): - self.open_gmail_inbox() - self.search_gmail_inbox_for_text(self.ACTIVATION_MESSAGE_SUBJECT) - self.assert_page_contains_text("Inbox %s" % (self.ACTIVATION_MESSAGE_SUBJECT)) - - first_unread_message_path = "//span/b" - first_read_message_path = "//span" - - if self.selenium.is_element_present(first_unread_message_path): - self.navigator.click_element_at_path(first_unread_message_path) - elif self.selenium.is_element_present(first_read_message_path): - self.navigator.click_element_at_path(first_read_message_path) - else: - self.fail("Cannot find message element for activation email at [//span/b] or [//span]") - - self.assert_title_is("Google Mail - %s" % (self.ACTIVATION_MESSAGE_SUBJECT)) - self.assert_page_contains_text_items(["Someone, hopefully you, signed up for a new account", - self.ACTIVATION_LINK_PREFIX]) - - def delete_activation_email(self): - self.open_activation_email() - self.navigator.click_link("Delete") - self.assert_title_starts_with("Google Mail - Search results") - self.search_gmail_inbox_for_text(self.ACTIVATION_MESSAGE_SUBJECT) - self.assert_page_does_not_contain_text("Inbox %s" % (self.ACTIVATION_MESSAGE_SUBJECT)) - - -def suite(): - return nose.loader.TestLoader().loadTestsFromTestCase(UserRegistrationTest) - -if __name__ == "__main__": - nose.core.TextTestRunner(verbosity=2).run(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/users/useradmintestcase.py b/tests/pvw/acceptance/users/useradmintestcase.py deleted file mode 100644 index 44d110bcdb..0000000000 --- a/tests/pvw/acceptance/users/useradmintestcase.py +++ /dev/null @@ -1,73 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from test_settings import * - -from seleniumextensions import SeleniumTestCase - -from helpers.gmailreader import GMailReader -from helpers.navigation import RSRNavigator, SeleniumNavigator -from users.rsruser import RSRUser - -class UserAdminTestCase(SeleniumTestCase): - - def setUp(self): - SeleniumTestCase.setUp(self) - self.navigator = SeleniumNavigator(self.selenium) - self.rsr = RSRNavigator(self.selenium) - self.rsr_user = RSRUser(self.selenium) - self.gmail_reader = GMailReader(self.selenium) - - def open_sign_in_or_register_page(self): - self.rsr.open_home_page() - self.assert_title_is(ORGANISATION_NAME) - self.assert_link_exists("Sign In") - self.navigator.click_link("Sign In") - self.assert_title_is(ORGANISATION_NAME) - self.assert_location_contains("rsr/signin/?next=/") - - def open_organisation_selection_page_for_user_registration(self): - self.open_sign_in_or_register_page() - self.assert_link_exists("Register") - self.navigator.click_link("Register") - self.assert_title_is(ORGANISATION_NAME) - self.assert_location_contains("rsr/accounts/register1") - - def select_organisation_and_open_user_details_entry_page(self): - self.open_organisation_selection_page_for_user_registration() - self.selenium.select("id_organisation", "label=Administrators") - self.assert_submit_button_with_text_exists("Continue") - self.navigator.click_submit_button_with_text("Continue") - self.assert_title_is(ORGANISATION_NAME) - self.assert_location_contains("rsr/accounts/register2/?org_id=") - - def verify_home_page_has_loaded(self): - self.assert_title_is(ORGANISATION_NAME) - self.assert_page_contains_text_items(["Focus Areas", "Get Solutions", "Education", - "Directory", "News", "About", "Recent contributions"]) - - def open_user_admin_page(self): - try: - self.rsr.open_user_admin_page() - self.verify_user_admin_page_has_loaded() - except Exception, exception: - self.fail("Unable to open user admin page: %s" % (exception)) - - def verify_user_admin_page_has_loaded(self): - self.assert_title_is("Select user to change | %s RSR admin" % (ORGANISATION_NAME)) - self.assert_page_contains_text_items(["%s RSR admin" % (ORGANISATION_NAME), - "Select user to change"]) - - - def search_for_user_account(self, username): - self.selenium.type("searchbar", username) - self.navigator.click_submit_button_with_text("Search") - - def open_gmail_inbox(self): - self.gmail_reader.open_inbox() - self.assert_title_is("Google Mail - Inbox") - - def search_gmail_inbox_for_text(self, search_text): - self.gmail_reader.search_inbox_for_text(search_text) - self.assert_title_starts_with("Google Mail - Search results") diff --git a/tests/pvw/acceptance/verifiers/__init__.py b/tests/pvw/acceptance/verifiers/__init__.py deleted file mode 100644 index 68b47df9ff..0000000000 --- a/tests/pvw/acceptance/verifiers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the verifiers package. diff --git a/tests/pvw/acceptance/verifiers/baseelementparsingverifier.py b/tests/pvw/acceptance/verifiers/baseelementparsingverifier.py deleted file mode 100644 index 4d7d89ef89..0000000000 --- a/tests/pvw/acceptance/verifiers/baseelementparsingverifier.py +++ /dev/null @@ -1,20 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * - - -class BaseElementParsingVerifier: - - def __init__(self, element_parsing_test_case): - self.test_case = element_parsing_test_case - - def open_page(self, page_url): - self.page_url = page_url - self.page_root = create_html_element_root_from(page_url) - self.page_text = elements_to_string(self.page_root) - - def expect_exactly(self, exact_value): - self.expected_exact_value = exact_value - return self diff --git a/tests/pvw/acceptance/verifiers/sharedpagecontentverifier.py b/tests/pvw/acceptance/verifiers/sharedpagecontentverifier.py deleted file mode 100644 index 6d52e70897..0000000000 --- a/tests/pvw/acceptance/verifiers/sharedpagecontentverifier.py +++ /dev/null @@ -1,25 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -class SharedPageContentVerifier: - - def __init__(self, web_test_case): - self.test_case = web_test_case - - def verify_expected_main_menu_links(self): - self.test_case.assert_links_exist(["Focus Areas", - "Projects", - "Netherlands", - "Education", - "Directory", - "News", - "About"]) - - def verify_dutch_water_history_panel(self): - self.test_case.assert_page_contains_text("Dutch Water History") - self.test_case.assert_link_exists_starting_with_text("Learn more") - - def verify_holland_water_valley_panel(self): - self.test_case.assert_page_contains_text("Holland Water Valley") - self.test_case.assert_link_exists_starting_with_text("Learn more") diff --git a/tests/pvw/acceptance/web/__init__.py b/tests/pvw/acceptance/web/__init__.py deleted file mode 100644 index 7dc7247609..0000000000 --- a/tests/pvw/acceptance/web/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the DWS web acceptance test package. diff --git a/tests/pvw/acceptance/web/content/__init__.py b/tests/pvw/acceptance/web/content/__init__.py deleted file mode 100644 index 23cf4e79a3..0000000000 --- a/tests/pvw/acceptance/web/content/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the web.content acceptance test package. diff --git a/tests/pvw/acceptance/web/content/about_page_content_test.py b/tests/pvw/acceptance/web/content/about_page_content_test.py deleted file mode 100644 index 5006ff3f62..0000000000 --- a/tests/pvw/acceptance/web/content/about_page_content_test.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class AboutPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_about_page() - - def test_01_about_page_has_expected_main_menu_links(self): - """web.content.AboutPageContentTest 1. About page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.AboutPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_about_panel_has_expected_content_and_links(self): - """web.content.AboutPageContentTest 3. About panel has expected content and links""" - - self.assert_page_contains_text_items(["About", - "Dutch Water sector", - "an overview", - "Learn more about"]) - self.assert_links_exist(["The public sector", - "Knowledge institutes - research and academia", - "Non-governmental organisations (NGOs)", - "Private companies"]) - - def test_04_about_listing_panel_has_expected_links(self): - """web.content.AboutPageContentTest 4. About listing panel has expected links""" - - self.assert_links_exist_starting_with_text(["Dutch Water sector", - "Public sector", - "Knowledge institutes", - "NGOs", - "Private companies", - "Contact us"]) - - def test_05_dutch_water_history_panel_has_expected_content_and_links(self): - """web.content.AboutPageContentTest 5. Dutch water history panel has expected content and links""" - - self.content_verifier.verify_dutch_water_history_panel() - - -def suite(): - return load_tests_from(AboutPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/directory_page_content_test.py b/tests/pvw/acceptance/web/content/directory_page_content_test.py deleted file mode 100644 index b97ef0f5ba..0000000000 --- a/tests/pvw/acceptance/web/content/directory_page_content_test.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class DirectoryPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_directory_page() - - def test_01_directory_page_has_expected_main_menu_links(self): - """web.content.DirectoryPageContentTest 1. Directory page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.DirectoryPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_directory_panel_has_expected_content_and_links(self): - """web.content.DirectoryPageContentTest 3. Directory panel has expected content and links""" - - self.assert_page_contains_text_items(["Directory of Dutch Water Expertise", - "NWP", - "Access our database"]) - self.assert_links_exist(["Dutchwatersector.org", - "Netherlands Water Partnership", - "http://www.dutchwatersector.org"]) - - def test_04_dutch_water_history_panel_has_expected_content_and_links(self): - """web.content.DirectoryPageContentTest 4. Dutch water history panel has expected content and links""" - - self.content_verifier.verify_dutch_water_history_panel() - - def test_05_focus_panel_has_expected_content_and_links(self): - """web.content.DirectoryPageContentTest 5. Focus panel has expected content and links""" - - self.assert_page_contains_text("Focus: Land & Water") - self.assert_link_exists_starting_with_text("Learn more") - - -def suite(): - return load_tests_from(DirectoryPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/education_page_content_test.py b/tests/pvw/acceptance/web/content/education_page_content_test.py deleted file mode 100644 index 5e4675ff8e..0000000000 --- a/tests/pvw/acceptance/web/content/education_page_content_test.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class EducationPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_education_page() - - def test_01_education_page_has_expected_main_menu_links(self): - """web.content.EducationPageContentTest 1. Education page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.EducationPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_education_panel_has_expected_content_and_links(self): - """web.content.EducationPageContentTest 3. Education panel has expected content and links""" - - self.assert_page_contains_text_items(["Education", - "Want to learn about", - "Want to know more?"]) - self.assert_link_exists_starting_with_text("schools, institutes and universities in the Netherlands") - - def test_04_institutions_panel_has_expected_links_for_listed_institutions(self): - """web.content.EducationPageContentTest 4. Institutions panel has expected links for listed institutions""" - - self.assert_page_contains_text("Institutions") - self.assert_links_exist_starting_with_text(["NHL", - "Saxion", - "Van Hall", - "Wetsus Academy", - "WUR", - "HZ", - "Rotterdam", - "TUD", - "UNESCO-IHE"]) - - -def suite(): - return load_tests_from(EducationPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/focus_areas_page_content_test.py b/tests/pvw/acceptance/web/content/focus_areas_page_content_test.py deleted file mode 100644 index dc165200f7..0000000000 --- a/tests/pvw/acceptance/web/content/focus_areas_page_content_test.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class FocusAreasPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_focus_areas_page() - - def test_01_focus_areas_page_has_expected_main_menu_links(self): - """web.content.FocusAreasPageContentTest 1. Focus Areas page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.FocusAreasPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_focus_areas_panel_has_expected_sections_and_all_projects_link(self): - """web.content.FocusAreasPageContentTest 3. Focus Areas panel has expected sections and all projects link""" - - self.assert_page_contains_text_items(["Focus Areas", - "Clean Water", - "International co-operation", - "Governance", - "Land & water"]) - self.assert_link_exists_starting_with_text("See a list of all projects") - - def test_04_clean_water_section_has_expected_links(self): - """web.content.FocusAreasPageContentTest 4. Clean Water section has expected links""" - - self.assert_links_exist_starting_with_text(["Learn more about clean water", - "See clean water projects"]) - - def test_05_international_cooperation_section_has_expected_links(self): - """web.content.FocusAreasPageContentTest 5. International co-operation section has expected links""" - - self.assert_links_exist_starting_with_text(["Learn more about International co-operation", - "See International co-operation projects"]) - - def test_06_governance_section_has_expected_links(self): - """web.content.FocusAreasPageContentTest 6. Governance section has expected links""" - - self.assert_links_exist_starting_with_text(["Learn more about governance", - "See governance projects"]) - - def test_07_land_and_water_section_has_expected_links(self): - """web.content.FocusAreasPageContentTest 7. Land & water section has expected links""" - - self.assert_links_exist_starting_with_text(["Learn more about land & water", - "See land & water projects"]) - - def test_08_dutch_water_history_panel_has_expected_content_and_links(self): - """web.content.FocusAreasPageContentTest 8. Dutch water history panel has expected content and links""" - - self.content_verifier.verify_dutch_water_history_panel() - - def test_09_holland_water_valley_panel_has_expected_content_and_links(self): - """web.content.FocusAreasPageContentTest 9. Holland water valley panel has expected content and links""" - - self.content_verifier.verify_holland_water_valley_panel() - - -def suite(): - return load_tests_from(FocusAreasPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/home_page_content_test.py b/tests/pvw/acceptance/web/content/home_page_content_test.py deleted file mode 100644 index cc831913ef..0000000000 --- a/tests/pvw/acceptance/web/content/home_page_content_test.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class HomePageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_home_page() - - def test_01_home_page_has_expected_main_menu_links(self): - """web.content.HomePageContentTest 1. Home page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_dws_intro_panel_has_expected_content_and_links(self): - """web.content.HomePageContentTest 2. DWS introduction panel has expected content and links""" - - self.assert_page_contains_text_items(["The Dutch water sector", - "Your worldwide partner for water"]) - self.assert_links_exist_starting_with_text(["Find a partner", - "Our story"]) - - def test_03_news_panel_has_expected_content_and_links(self): - """web.content.HomePageContentTest 3. News panel has expected content and links""" - - self.assert_page_contains_text_items(["Latest news", - "Recent articles", - "Focus Areas", - "Clean water", - "Governance", - "International cooperation", - "Land & water"]) - self.assert_links_exist_starting_with_text(["RSS", - "View earlier articles"]) - - def test_04_projects_worldwide_panel_has_expected_content_and_links(self): - """web.content.HomePageContentTest 4. Projects worldwide panel has expected content and links""" - - self.assert_page_contains_text("Projects worldwide") - self.assert_links_exist_starting_with_text(["See all", - "View large map"]) - - def test_05_focus_areas_panel_has_expected_content_and_links(self): - """web.content.HomePageContentTest 5. Focus Areas panel has expected content and links""" - - self.assert_page_contains_text_items(["Focus Areas", - "Clean water", - "Governance", - "International cooperation", - "Land & water"]) - self.assert_links_exist_starting_with_text(["See all", - "Read more", - "Clean water", - "Governance", - "International cooperation", - "Land & water"]) - - -def suite(): - return load_tests_from(HomePageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/netherlands_page_content_test.py b/tests/pvw/acceptance/web/content/netherlands_page_content_test.py deleted file mode 100644 index a8e07f6eb8..0000000000 --- a/tests/pvw/acceptance/web/content/netherlands_page_content_test.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class NetherlandsPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_netherlands_page() - - def test_01_netherlands_page_has_expected_main_menu_links(self): - """web.content.NetherlandsPageContentTest 1. Netherlands page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.NetherlandsPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_netherlands_now_panel_has_expected_content(self): - """web.content.NetherlandsPageContentTest 3. The Netherlands now panel has expected content""" - - self.assert_page_contains_text_items(["The Netherlands now", - "Part of our culture and history", - "Going Dutch, water style"]) - - def test_04_dutch_water_history_panel_has_expected_content_and_links(self): - """web.content.NetherlandsPageContentTest 4. Dutch water history panel has expected content and links""" - - self.content_verifier.verify_dutch_water_history_panel() - - def test_05_holland_water_valley_panel_has_expected_content_and_links(self): - """web.content.NetherlandsPageContentTest 5. Holland water valley panel has expected content and links""" - - self.content_verifier.verify_holland_water_valley_panel() - - -def suite(): - return load_tests_from(NetherlandsPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/news_page_content_test.py b/tests/pvw/acceptance/web/content/news_page_content_test.py deleted file mode 100644 index bef4e703a2..0000000000 --- a/tests/pvw/acceptance/web/content/news_page_content_test.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class NewsPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_news_page() - - def test_01_news_page_has_expected_main_menu_links(self): - """web.content.NewsPageContentTest 1. News page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.NewsPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_news_page_has_expected_sections_and_links(self): - """web.content.NewsPageContentTest 3. News page has expected sections and links""" - - self.assert_page_contains_text_items(["Search for", - "Recent Posts", - "Participate", - "Categories", - "Tags", - "Blogroll", - "Archives"]) - self.assert_links_exist(["Register", - "Log in", - "Entries RSS", - "Comments RSS", - "WordPress.org", - "Netherlands Water Partnership blog"]) - - -def suite(): - return load_tests_from(NewsPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/page_content_test_suite.py b/tests/pvw/acceptance/web/content/page_content_test_suite.py deleted file mode 100644 index d59d0a255c..0000000000 --- a/tests/pvw/acceptance/web/content/page_content_test_suite.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.content.home_page_content_test import HomePageContentTest -from web.content.focus_areas_page_content_test import FocusAreasPageContentTest -from web.content.projects_page_content_test import ProjectsPageContentTest -from web.content.netherlands_page_content_test import NetherlandsPageContentTest -from web.content.education_page_content_test import EducationPageContentTest -from web.content.directory_page_content_test import DirectoryPageContentTest -from web.content.news_page_content_test import NewsPageContentTest -from web.content.about_page_content_test import AboutPageContentTest - - -def page_content_suite(): - return create_test_suite_from_classes([HomePageContentTest, FocusAreasPageContentTest, ProjectsPageContentTest, - NetherlandsPageContentTest, EducationPageContentTest, DirectoryPageContentTest, - NewsPageContentTest, AboutPageContentTest]) - -if __name__ == "__main__": - run_test_suite(page_content_suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/content/projects_page_content_test.py b/tests/pvw/acceptance/web/content/projects_page_content_test.py deleted file mode 100644 index 2a497ff880..0000000000 --- a/tests/pvw/acceptance/web/content/projects_page_content_test.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase -from verifiers.sharedpagecontentverifier import SharedPageContentVerifier - - -class ProjectsPageContentTest(DWSWebTestCase): - - def setUp(self): - DWSWebTestCase.setUp(self) - self.content_verifier = SharedPageContentVerifier(self) - self.open_projects_page() - - def test_01_projects_page_has_expected_main_menu_links(self): - """web.content.ProjectsPageContentTest 1. Projects page has expected main menu links""" - - self.content_verifier.verify_expected_main_menu_links() - - def test_02_breadcrumb_bar_has_home_link(self): - """web.content.ProjectsPageContentTest 2. Breadcrumb bar has Home link""" - - self.assert_link_exists("Home") - - def test_03_all_projects_panel_has_expected_content_and_links(self): - """web.content.ProjectsPageContentTest 3. All projects panel has expected content and links""" - - self.assert_page_contains_text_items(["All projects", - "Our projects", - "results)"]) - self.assert_links_exist_starting_with_text(["list of all project participants", - "Name", - "Country", - "Continent", - "Status", - "Latest update"]) - - -def suite(): - return load_tests_from(ProjectsPageContentTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/general/__init__.py b/tests/pvw/acceptance/web/general/__init__.py deleted file mode 100644 index 34bebb5a4e..0000000000 --- a/tests/pvw/acceptance/web/general/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the web.general acceptance test package. diff --git a/tests/pvw/acceptance/web/general/general_test_suite.py b/tests/pvw/acceptance/web/general/general_test_suite.py deleted file mode 100644 index 1f32c234dd..0000000000 --- a/tests/pvw/acceptance/web/general/general_test_suite.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from web.general.site_components_smoke_test import SiteComponentsSmokeTest - - -def general_suite(): - return create_test_suite_from_classes([SiteComponentsSmokeTest]) - -if __name__ == "__main__": - run_test_suite(general_suite()) diff --git a/tests/pvw/acceptance/web/general/site_components_smoke_test.py b/tests/pvw/acceptance/web/general/site_components_smoke_test.py deleted file mode 100644 index 5ff3e05a82..0000000000 --- a/tests/pvw/acceptance/web/general/site_components_smoke_test.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from testcases.webtestcase import DWSWebTestCase - - -class SiteComponentsSmokeTest(DWSWebTestCase): - - def tearDown(self): - self.assert_page_does_not_contain_text_items(["Traceback", "Error", "error"]) - - def test_01_can_load_home_page(self): - """web.general.SiteComponentsSmokeTest 1. Can load Home page""" - - self.open_home_page() - self.assert_page_contains_text_items(["Recent articles", "Projects worldwide", "Focus areas"]) - - def test_02_can_load_focus_areas_page(self): - """web.general.SiteComponentsSmokeTest 2. Can load Focus Areas page (Drupal CMS content loads as expected)""" - - self.open_focus_areas_page() - self.assert_page_contains_text_items(["Focus Areas", "Clean Water", "Governance", "Dutch Water History"]) - - def test_03_can_load_projects_page(self): - """web.general.SiteComponentsSmokeTest 3. Can load Projects page, which redirects to All Projects page (Django + RSR operates as expected)""" - - self.open_projects_page() - self.assert_page_contains_text_items(["All projects", "Our projects"]) - - def test_04_can_load_all_projects_page(self): - """web.general.SiteComponentsSmokeTest 4. Can load All Projects page (Django + RSR operates as expected)""" - - self.open_all_projects_page() - self.assert_page_contains_text_items(["All projects", "Our projects"]) - - def test_05_can_load_netherlands_page(self): - """web.general.SiteComponentsSmokeTest 5. Can load Netherlands page (Drupal CMS content loads as expected)""" - - self.open_netherlands_page() - self.assert_page_contains_text_items(["The Netherlands now", "Dutch Water History"]) - - def test_06_can_load_education_page(self): - """web.general.SiteComponentsSmokeTest 6. Can load Education page (Drupal CMS content loads as expected)""" - - self.open_education_page() - self.assert_page_contains_text_items(["Education", "Institutions"]) - - def test_07_can_load_directory_page(self): - """web.general.SiteComponentsSmokeTest 7. Can load Directory page (Drupal CMS content loads as expected)""" - - self.open_directory_page() - self.assert_page_contains_text_items(["Directory of Dutch Water Expertise", "Dutch Water History"]) - - def test_08_can_load_news_page(self): - """web.general.SiteComponentsSmokeTest 8. Can load News page (blog content loads as expected)""" - - self.open_news_page() - self.assert_page_contains_text_items(["Recent Posts", "Categories", "Archives"]) - - def test_09_can_load_about_page(self): - """web.general.SiteComponentsSmokeTest 9. Can load About page (Drupal CMS content loads as expected)""" - - self.open_about_page() - self.assert_page_contains_text_items(["About", "Dutch Water sector", "an overview", "Dutch Water History"]) - - -def suite(): - return load_tests_from(SiteComponentsSmokeTest) - -if __name__ == "__main__": - run_test_suite(suite()) - SeleniumClient().stop() diff --git a/tests/pvw/acceptance/web/navigation/__init__.py b/tests/pvw/acceptance/web/navigation/__init__.py deleted file mode 100644 index 5ea32b64f5..0000000000 --- a/tests/pvw/acceptance/web/navigation/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the DWS web.navigation acceptance test package. diff --git a/tests/pvw/acceptance/web/navigation/footer_navigation_test.py b/tests/pvw/acceptance/web/navigation/footer_navigation_test.py deleted file mode 100644 index 1c7bc2b9a5..0000000000 --- a/tests/pvw/acceptance/web/navigation/footer_navigation_test.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.dwspaths import * -from helpers.dwsurls import * -from helpers.testexecution import * - -from web.navigation.footernavigationverifier import FooterNavigationVerifier - - -class FooterNavigationTest(TestCase): - - EXPECTED_HOME_PAGE_FOOTER_LINK_PATHS = [open_license_page(), terms_of_use_page(), privacy_policy_page(), credits_page(), - contact_us_page(), akvo_home_page()] - - EXPECTED_CMS_PAGE_FOOTER_LINK_PATHS = [open_license_page(), terms_of_use_page(), privacy_policy_page(), credits_page(), - admin_page(), contact_us_page()] - - EXPECTED_PROJECTS_PAGE_FOOTER_LINK_PATHS = [open_license_page(), terms_of_use_page(), privacy_policy_page(), credits_page(), - admin_page(), register_page(), sign_in_page(), contact_us_page()] - - def setUp(self): - self.navigation_verifier = FooterNavigationVerifier(self) - - def test_01_home_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 1. Home page has expected footer links""" - - self.verify_expected_footer_links(home_page_url(), 6, self.EXPECTED_HOME_PAGE_FOOTER_LINK_PATHS) - - def test_02_focus_areas_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 2. Focus Areas page has expected footer links""" - - self.verify_expected_cms_page_footer_links(focus_areas_url()) - - def test_03_projects_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 3. Projects page has expected footer links""" - - self.verify_expected_footer_links(projects_url(), 8, self.EXPECTED_PROJECTS_PAGE_FOOTER_LINK_PATHS) - - def test_04_netherlands_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 4. Netherlands page has expected footer links""" - - self.verify_expected_cms_page_footer_links(netherlands_url()) - - def test_05_education_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 5. Education page has expected footer links""" - - self.verify_expected_cms_page_footer_links(education_url()) - - def test_06_directory_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 6. Directory page has expected footer links""" - - self.verify_expected_cms_page_footer_links(directory_url()) - - def test_07_news_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 7. News page has expected footer links""" - - self.verify_expected_cms_page_footer_links(news_url()) - - def test_08_about_page_has_expected_footer_links(self): - """web.navigation.FooterNavigationTest 8. About page has expected footer links""" - - self.verify_expected_cms_page_footer_links(about_url()) - - def verify_expected_cms_page_footer_links(self, page_url): - self.verify_expected_footer_links(page_url, 6, self.EXPECTED_CMS_PAGE_FOOTER_LINK_PATHS) - - def verify_expected_footer_links(self, page_url, expected_number_of_links, expected_paths): - self.navigation_verifier.open_page(page_url) - self.navigation_verifier.expect_exactly(expected_number_of_links).footer_links() - self.navigation_verifier.verify_expected_footer_link_paths(expected_paths) - - -def suite(): - return load_tests_from(FooterNavigationTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/pvw/acceptance/web/navigation/footernavigationverifier.py b/tests/pvw/acceptance/web/navigation/footernavigationverifier.py deleted file mode 100644 index df8bef8bcd..0000000000 --- a/tests/pvw/acceptance/web/navigation/footernavigationverifier.py +++ /dev/null @@ -1,29 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * - -from verifiers.baseelementparsingverifier import BaseElementParsingVerifier - - -class FooterNavigationVerifier(BaseElementParsingVerifier): - - FOOTER_LINKS_XPATH = "//div[@id='footer']/p/a/@href" - - def footer_links(self): - actual_number_of_footer_links = len(values_at_xpath(self.page_root, self.FOOTER_LINKS_XPATH)) - - self.test_case.failUnlessEqual(self.expected_exact_value, actual_number_of_footer_links, - "\nExpected number of footer links: %i\n Actual number of footer links: %i" % - (self.expected_exact_value, actual_number_of_footer_links)) - - def verify_expected_footer_link_paths(self, list_of_expected_paths): - footer_link_paths = values_at_xpath(self.page_root, self.FOOTER_LINKS_XPATH) - - for index in range(len(list_of_expected_paths)): - expected_path = list_of_expected_paths[index] - actual_path = footer_link_paths[index] - self.test_case.failUnless(actual_path.find(expected_path) > -1, - "\nExpected footer link path at index %i: %s\n Actual footer link path at index %i: %s" % - (index, expected_path, index, actual_path)) diff --git a/tests/pvw/acceptance/web/navigation/menu_navigation_test.py b/tests/pvw/acceptance/web/navigation/menu_navigation_test.py deleted file mode 100644 index a268b1debb..0000000000 --- a/tests/pvw/acceptance/web/navigation/menu_navigation_test.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from unittest import TestCase - -from helpers.dwspaths import * -from helpers.dwsurls import * -from helpers.testexecution import * - -from web.navigation.menunavigationverifier import MenuNavigationVerifier - - -class MenuNavigationTest(TestCase): - - def setUp(self): - self.navigation_verifier = MenuNavigationVerifier(self) - - def test_01_home_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 1. Home page has expected menu sections""" - - self.verify_expected_menu_sections_for(home_page_url()) - - def test_02_focus_areas_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 2. Focus Areas page has expected menu sections""" - - self.verify_expected_menu_sections_for(focus_areas_url()) - - def test_03_projects_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 3. Projects page has expected menu sections""" - - self.verify_expected_menu_sections_for(all_projects_url()) - - def test_04_netherlands_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 4. Netherlands page has expected menu sections""" - - self.verify_expected_menu_sections_for(netherlands_url()) - - def test_05_education_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 5. Education page has expected menu sections""" - - self.verify_expected_menu_sections_for(education_url()) - - def test_06_directory_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 6. Directory page has expected menu sections""" - - self.verify_expected_menu_sections_for(directory_url()) - - def test_07_news_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 7. News page has expected menu sections""" - - self.verify_expected_menu_sections_for(news_url()) - - def test_08_about_page_has_expected_menu_sections(self): - """web.navigation.MenuNavigationTest 8. About page has expected menu sections""" - - self.verify_expected_menu_sections_for(about_url()) - - def verify_expected_menu_sections_for(self, page_url): - self.navigation_verifier.open_page(page_url) - self.navigation_verifier.expect_exactly(8).main_menu_sections() - self.navigation_verifier.verify_expected_main_menu_paths([home_page(), focus_areas_page(), projects_page(), - netherlands_page(), education_page(), directory_page(), - news_page(), about_page()]) - - -def suite(): - return load_tests_from(MenuNavigationTest) - -if __name__ == "__main__": - run_test_suite(suite()) diff --git a/tests/pvw/acceptance/web/navigation/menunavigationverifier.py b/tests/pvw/acceptance/web/navigation/menunavigationverifier.py deleted file mode 100644 index 33bb32ff8d..0000000000 --- a/tests/pvw/acceptance/web/navigation/menunavigationverifier.py +++ /dev/null @@ -1,29 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.elementparsing import * - -from verifiers.baseelementparsingverifier import BaseElementParsingVerifier - - -class MenuNavigationVerifier(BaseElementParsingVerifier): - - MAIN_MENU_PATHS_XPATH = "//div[@id='header_container']/a/@href | //div[@id='header_container']/ul/li/a/@href" - - def main_menu_sections(self): - actual_main_menu_sections = len(values_at_xpath(self.page_root, self.MAIN_MENU_PATHS_XPATH)) - - self.test_case.failUnlessEqual(self.expected_exact_value, actual_main_menu_sections, - "\nExpected main menu sections: %i\n Actual main menu sections: %i" % - (self.expected_exact_value, actual_main_menu_sections)) - - def verify_expected_main_menu_paths(self, expected_main_menu_paths): - main_menu_paths = values_at_xpath(self.page_root, self.MAIN_MENU_PATHS_XPATH) - - for index in range(len(expected_main_menu_paths)): - expected_path = expected_main_menu_paths[index] - actual_path = main_menu_paths[index] - self.test_case.failUnless(actual_path.find(expected_path) > -1, - "\nExpected main menu path at index %i: %s\n Actual main menu path at index %i: %s" % - (index, expected_path, index, actual_path)) diff --git a/tests/pvw/acceptance/web/navigation/navigation_test_suite.py b/tests/pvw/acceptance/web/navigation/navigation_test_suite.py deleted file mode 100644 index b1a7fabb3f..0000000000 --- a/tests/pvw/acceptance/web/navigation/navigation_test_suite.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.testexecution import * - -from web.navigation.menu_navigation_test import MenuNavigationTest -from web.navigation.footer_navigation_test import FooterNavigationTest - - -def navigation_suite(): - return create_test_suite_from_classes([MenuNavigationTest, FooterNavigationTest]) - -if __name__ == "__main__": - run_test_suite(navigation_suite()) diff --git a/tests/pvw/acceptance/web/web_test_suite.py b/tests/pvw/acceptance/web/web_test_suite.py deleted file mode 100644 index 9b781b8218..0000000000 --- a/tests/pvw/acceptance/web/web_test_suite.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python - -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -from helpers.seleniumclient import SeleniumClient -from helpers.testexecution import * - -from web.general.general_test_suite import general_suite -from web.navigation.navigation_test_suite import navigation_suite -from web.content.page_content_test_suite import page_content_suite - - -def web_suite(): - return create_test_suite_from_suites([general_suite(), navigation_suite(), page_content_suite()]) - -if __name__ == "__main__": - run_test_suite(web_suite()) - SeleniumClient().stop() diff --git a/tests/shared/testing/__init__.py b/tests/shared/testing/__init__.py deleted file mode 100644 index 0702ff1214..0000000000 --- a/tests/shared/testing/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the shared testing package. diff --git a/tests/shared/testing/helpers/__init__.py b/tests/shared/testing/helpers/__init__.py deleted file mode 100644 index 93eab2d782..0000000000 --- a/tests/shared/testing/helpers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - -# Initialiser for the shared testing.helpers package. diff --git a/tests/shared/testing/helpers/execution.py b/tests/shared/testing/helpers/execution.py deleted file mode 100644 index 732710e8c9..0000000000 --- a/tests/shared/testing/helpers/execution.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. - - -import nose - - -class TestSuiteLoader(object): - - def create_suite_from_classes(self, test_class_list): - return self.create_suite_from_list(map(lambda test_class: self.load_tests_from(test_class), test_class_list)) - - def create_suite_from_list(self, test_suite_list): - return nose.suite.LazySuite(test_suite_list) - - def load_tests_from(self, test_case): - return nose.loader.TestLoader().loadTestsFromTestCase(test_case) - - -class TestMode(object): - - NORMAL = 'normal' - CONTINUOUS_INTEGRATION = 'ci' - - -class TestRunner(object): - - def __init__(self, test_mode=TestMode.NORMAL): - self.test_mode = test_mode - - def run_test_suite(self, suite): - test_runner = nose.core.TextTestRunner(verbosity=2) - - if self.test_mode == TestMode.CONTINUOUS_INTEGRATION: - import teamcity.unittestpy - test_runner = teamcity.unittestpy.TeamcityTestRunner() - - return test_runner.run(suite) diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/unit/rsr/middleware/partner_sites_lookup_test.py b/tests/unit/rsr/middleware/partner_sites_lookup_test.py deleted file mode 100755 index 037bcc6cea..0000000000 --- a/tests/unit/rsr/middleware/partner_sites_lookup_test.py +++ /dev/null @@ -1,95 +0,0 @@ -from django.utils import unittest - -from testing.helpers.execution import TestSuiteLoader, TestRunner - - -class PartnerSitesLookup(object): - - PARTNER_SITES_DOMAINS = ('akvoapp.org', 'akvotest.org', 'akvotest2.org', 'akvoapp.dev') - - def __init__(self, partner_site_domains=PARTNER_SITES_DOMAINS): - self.partner_site_domains = partner_site_domains - - def is_partner_site(self, domain): - domain_parts = domain.split('.') - if len(domain_parts) >= 3: - domain_name = '%s.%s' % tuple(domain_parts[-2:]) - if domain_name in self.partner_site_domains: - return True - return False - - -class PartnerSitesLookupTest(unittest.TestCase): - - def setUp(self): - super(PartnerSitesLookupTest, self).setUp() - self.partner_sites_lookup = PartnerSitesLookup() - - def test_has_known_partner_site_domains(self): - """tests.rsr.middleware.partner_sites_lookup_test Can recognise non partner site domain""" - self.assertIn('akvoapp.org', PartnerSitesLookup.PARTNER_SITES_DOMAINS) - self.assertIn('akvotest.org', PartnerSitesLookup.PARTNER_SITES_DOMAINS) - self.assertIn('akvotest2.org', PartnerSitesLookup.PARTNER_SITES_DOMAINS) - self.assertIn('akvoapp.dev', PartnerSitesLookup.PARTNER_SITES_DOMAINS) - - def test_can_recoginse_non_partner_site_domain(self): - """tests.rsr.middleware.partner_sites_lookup_test Can recognise non partner site domain""" - self.assertFalse(self.partner_sites_lookup.is_partner_site('www.akvo.org'), 'Should not be recognised as a partner site') - - def test_can_recoginse_partner_site_domain(self): - """tests.rsr.middleware.partner_sites_lookup_test Can recognise partner site domain""" - self.assertTrue(self.partner_sites_lookup.is_partner_site('connect4change.akvoapp.org'), 'Should be recognised as a partner site') - - -def suite(): - return TestSuiteLoader().load_tests_from(PartnerSitesLookupTest) - - -if __name__ == '__main__': - from test_settings import TEST_MODE - TestRunner(TEST_MODE).run_test_suite(suite()) - - -import mox - -import os -os.environ['DJANGO_SETTINGS_MODULE'] = 'akvo.settings' - -from django.contrib.sites.models import Site, SiteManager - -from testing.helpers.execution import TestRunner, TestSuiteLoader - - -class SiteFinder(object): - - def __init__(self, site_objects): - self.site_objects = site_objects - - def find(self, domain_name): - return self.site_objects.get_or_create(domain=domain_name, name=domain_name) - - -class SiteFinderTest(mox.MoxTestBase): - - def setUp(self): - super(SiteFinderTest, self).setUp() - self.mock_site_model_manager = self.mox.CreateMock(SiteManager) - self.mock_site = self.mox.CreateMock(Site) - self.site_finder = SiteFinder(self.mock_site_model_manager) - - def test_can_find_site_object_given_domain_name(self): - """rsr.tests.middleware.site_finder_test Can find site object given a domain name""" - expected_site_tuple = (self.mock_site, True) - self.mock_site_model_manager.get_or_create(domain='some.domain.org', name='some.domain.org').AndReturn(expected_site_tuple) - self.mox.ReplayAll() - actual_site_tuple = self.site_finder.find('some.domain.org') - self.assertEqual(expected_site_tuple, actual_site_tuple) - - -def suite(): - return TestSuiteLoader().load_tests_from(SiteFinderTest) - - -if __name__ == '__main__': - from test_settings import TEST_MODE - TestRunner(TEST_MODE).run_test_suite(suite()) diff --git a/tests/unit/test_settings.py b/tests/unit/test_settings.py deleted file mode 100644 index dd320c07cf..0000000000 --- a/tests/unit/test_settings.py +++ /dev/null @@ -1 +0,0 @@ -TEST_MODE = 'normal' diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile index 11a7fde78e..222744c964 100644 --- a/vagrant/Vagrantfile +++ b/vagrant/Vagrantfile @@ -22,7 +22,7 @@ Vagrant.configure("2") do |config| config.vm.provision "shell", path: "./provisioning/install_dependencies.sh" config.vm.provision "shell", path: "./provisioning/install_dev_dependencies.sh" config.vm.provision "shell", run: "always", path: "./provisioning/fix_dns.sh" - config.vm.provision "shell", path: "./provisioning/load_test_db.sh" + config.vm.provision "shell", path: "./provisioning/prepare_test_db.sh" config.vm.provision "shell", run: "always", path: "./provisioning/prepare_rsr.sh" end diff --git a/vagrant/provisioning/load_test_db.sh b/vagrant/provisioning/prepare_test_db.sh similarity index 85% rename from vagrant/provisioning/load_test_db.sh rename to vagrant/provisioning/prepare_test_db.sh index f9a9b4765f..089ba821b2 100644 --- a/vagrant/provisioning/load_test_db.sh +++ b/vagrant/provisioning/prepare_test_db.sh @@ -1,6 +1,9 @@ #!/bin/bash set -e +# Make sure rsr user can create the test database +sudo -u postgres psql --command 'ALTER USER rsr CREATEDB;' + manage='sudo -H -u rsr /var/akvo/rsr/venv/bin/python /var/akvo/rsr/code/manage.py' # if we have already done the loading, don't do it again From 67b5afcd6349c9542cd67b57ea7bb88f35e20cc1 Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Fri, 27 Mar 2015 13:59:03 +0100 Subject: [PATCH 05/22] [#1351] Add IATI export checks --- akvo/iati/checks/__init__.py | 11 + akvo/iati/checks/v201.py | 747 ++++++++++++++++ akvo/iati/elements/budget.py | 12 +- akvo/iati/elements/conditions.py | 9 +- akvo/iati/elements/location.py | 15 +- akvo/iati/elements/sector.py | 9 +- akvo/iati/elements/transaction.py | 32 +- akvo/iati/mandatory_fields.py | 20 + akvo/rsr/admin.py | 41 +- .../rsr/migrations/0002_auto_20150326_1823.py | 218 +++++ ..._add_crsadd__add_crsaddotherflag__del_f.py | 842 ------------------ akvo/rsr/models/__init__.py | 7 +- akvo/rsr/models/budget_item.py | 2 - akvo/rsr/models/location.py | 28 +- akvo/rsr/models/project.py | 13 +- akvo/rsr/models/sector.py | 2 +- akvo/rsr/models/transaction.py | 40 +- akvo/templates/project_report.html | 8 - 18 files changed, 1125 insertions(+), 931 deletions(-) create mode 100644 akvo/iati/checks/__init__.py create mode 100644 akvo/iati/checks/v201.py create mode 100644 akvo/iati/mandatory_fields.py create mode 100644 akvo/rsr/migrations/0002_auto_20150326_1823.py delete mode 100644 akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py diff --git a/akvo/iati/checks/__init__.py b/akvo/iati/checks/__init__.py new file mode 100644 index 0000000000..8bbceec412 --- /dev/null +++ b/akvo/iati/checks/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from .v201 import V201Checks + +__all__ = [ + 'V201Checks', +] diff --git a/akvo/iati/checks/v201.py b/akvo/iati/checks/v201.py new file mode 100644 index 0000000000..db5166642d --- /dev/null +++ b/akvo/iati/checks/v201.py @@ -0,0 +1,747 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +from datetime import date + +CHECKS = [ + 'iati_identifier', + 'reporting_org', + 'title', + 'description', + 'partners', + 'activity_status', + 'dates', + 'recipients', + 'locations', + 'sectors', + 'country_budget_items', + 'policy_markers', + 'budgets', + 'planned_disbursements', + 'transactions', + 'document_link', + 'related_activity', + 'legacy_data', + 'conditions', + 'crs_add', + 'fss', +] + + +class V201Checks(object): + def iati_identifier(self): + """ + Check if a project has a IATI identifier. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + if self.project.iati_activity_id: + return [(u'success', u'has IATI identifier')] + else: + self.all_checks_passed = False + return [(u'error', u'IATI identifier missing')] + + def reporting_org(self): + """ + Check if a project has a reporting organisation and if the reporting organisation + has an IATI identifier. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if self.project.sync_owner: + checks.append((u'success', u'has reporting organisation')) + if self.project.sync_owner.iati_org_id: + checks.append((u'success', u'reporting organisation has IATI identifier')) + else: + self.all_checks_passed = False + checks.append((u'error', u'IATI identifier for reporting organisation missing')) + else: + self.all_checks_passed = False + checks.append((u'error', u'reporting organisation missing')) + checks.append((u'error', u'IATI identifier for reporting organisation missing')) + + return checks + + def title(self): + """ + Check if a project has a title. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + if self.project.title: + return [(u'success', u'has title')] + else: + self.all_checks_passed = False + return [(u'error', u'title missing')] + + def description(self): + """ + Check if a project has a description field. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + p = self.project + + if p.subtitle or p.project_plan_summary or p.background or p.project_plan \ + or p.current_status or p.sustainability or p.goals_overview or p.target_group: + return [(u'success', u'has description field(s)')] + else: + self.all_checks_passed = False + return [(u'error', u'description field(s) missing')] + + def partners(self): + """ + Check if a project has at least one valid partner and issue a warning if a partner + misses the role, IATI identifier or name. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + valid_partner = False + + for partnership in self.project.partnerships.all(): + if partnership.organisation: + org = partnership.organisation + org_name = org.long_name or org.name + if partnership.partner_type and (org.iati_org_id or org_name): + valid_partner = True + if not partnership.partner_type: + checks.append((u'warning', u'missing role for partner %s' % org_name)) + if not org.iati_org_id: + checks.append((u'warning', u'partner %s has no IATI identifier' % org_name)) + if not org_name: + checks.append((u'warning', u'%s partner has no organisation ' + u'name' % partnership.partner_type)) + else: + checks.append((u'warning', u'partnership has no organisation')) + + if valid_partner: + checks.insert(0, (u'success', u'has at least one valid partner')) + else: + self.all_checks_passed = False + checks.insert(0, (u'error', u'no valid partners')) + + return checks + + def activity_status(self): + """ + Check if a project has a status. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + if self.project.status: + return [(u'success', u'has status')] + else: + self.all_checks_passed = False + return [(u'error', u'status missing')] + + def dates(self): + """ + Check if a date start planned or actual is present + Check if the actual dates are today, or in the past + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if self.project.date_start_planned or self.project.date_start_actual: + checks.append((u'success', u'has planned or actual start date')) + else: + self.all_checks_passed = False + checks.append((u'error', u'planned or actual start date missing')) + + if self.project.date_start_actual: + if self.project.date_start_actual > date.today(): + self.all_checks_passed = False + checks.append((u'error', u'actual start date must be in the past')) + + if self.project.date_end_actual: + if self.project.date_end_actual > date.today(): + self.all_checks_passed = False + checks.append((u'error', u'actual end date must be in the past')) + + return checks + + def recipients(self): + """ + Check if recipient countries or regions are present only on project or transaction level. + In case there are multiple recipients, all must have a percentage specified. + Check if percentages for all reported countries and regions must add up to 100%. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if self.project.recipient_countries.all() or self.project.recipient_regions.all(): + for t in self.project.transactions.all(): + if t.recipient_country or t.recipient_region: + self.all_checks_passed = False + checks.append((u'error', u'recipient countries or regions present on project ' + u'and transaction level')) + else: + transaction_recipients = [] + for t in self.project.transactions.all(): + if t.recipient_country and t.recipient_region: + self.all_checks_passed = False + checks.append((u'error', u'transaction (id: %s) has a recipient country and ' + u'region specified' % str(t.pk))) + elif not (t.recipient_country or t.recipient_region): + transaction_recipients.append(False) + else: + transaction_recipients.append(True) + if len(set(transaction_recipients)) > 1: + self.all_checks_passed = False + checks.append((u'error', u'all transactions must have a recipient country or ' + u'region specified if at least one transaction has')) + + no_recipient_countries = self.project.recipient_countries.all().count() + no_recipient_regions = self.project.recipient_regions.all().count() + + if no_recipient_countries + no_recipient_regions > 1: + percentage = 0 + + for country in self.project.recipient_countries.all(): + if not country.percentage: + self.all_checks_passed = False + checks.append((u'error', u'recipient country %s has no ' + u'percentage' % country.country)) + else: + percentage += country.percentage + + for region in self.project.recipient_regions.all(): + if not region.percentage: + self.all_checks_passed = False + checks.append((u'error', u'recipient region %s has no ' + u'percentage' % region.region)) + else: + percentage += region.percentage + + if percentage == 100: + checks.append((u'success', u'country or region recipients percentage ' + u'adds up to 100')) + else: + self.all_checks_passed = False + checks.append((u'error', u'country or region recipients percentage does not ' + u'add up to 100')) + + if (self.project.recipient_countries.all() or self.project.recipient_regions.all()) \ + and not checks: + checks.append((u'success', u'has valid country or region recipient(s)')) + + return checks + + def locations(self): + """ + If a(n administrative) code is specified, a vocabulary needs to be specified + as well. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for location in self.project.locations.all(): + if location.location_code and not location.vocabulary: + checks.append((u'warning', u'location (id: %s) has code, ' + u'but no vocabulary' % str(location.pk))) + + for administrative in location.administratives.all(): + if administrative.code and not administrative.vocabulary: + checks.append((u'warning', u'administrative location (id: %s) has code, ' + u'but no vocabulary' % str(administrative.pk))) + + if self.project.locations.all() and not checks: + checks.append((u'success', u'has valid location(s)')) + + return checks + + def sectors(self): + """ + Check if sectors are present, either on project or transaction level, but not both. + If on transaction level, all transactions must have a sector. + Per sector vocabulary on project level, the percentages of the sectors + should add up to 100%. + On transaction level, each sector vocabulary should only occur once per transaction. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if self.project.sectors.all(): + for t in self.project.transactions.all(): + if t.sectors.all(): + self.all_checks_passed = False + checks.append((u'error', u'sectors present on project and transaction level')) + + if not checks: + sectors_dict = {} + for sector in self.project.sectors.all(): + if not sector.vocabulary or sector.vocabulary == 'DAC': + voc = '1' + elif sector.vocabulary == 'DAC-3': + voc = '2' + else: + voc = sector.vocabulary + + try: + sectors_dict[voc].append(sector.percentage) + except KeyError: + sectors_dict[voc] = [sector.percentage] + + for voc_key in sectors_dict.keys(): + if len(sectors_dict[voc_key]) > 1: + voc_percentage = 0 + for percentage in sectors_dict[voc_key]: + try: + voc_percentage += int(percentage) + except ValueError: + self.all_checks_passed = False + checks.append((u'error', u'multiple sectors for vocabulary %s, but ' + u'not all have a percentage ' + u'specified' % str(voc_key))) + + if voc_percentage == 100: + checks.append((u'success', u'sector percentages for vocabulary %s add ' + u'up to 100' % str(voc_key))) + else: + self.all_checks_passed = False + checks.append((u'error', u'sector percentages for vocabulary %s do not ' + u'add up to 100' % str(voc_key))) + + elif not self.project.transactions.all(): + self.all_checks_passed = False + checks.append((u'error', u'no sectors present on project or transaction level')) + + else: + for t in self.project.transactions.all(): + if not t.sectors.all(): + self.all_checks_passed = False + checks.append((u'error', u'no sectors on project level or transaction (id: %s) ' + u'missing sector' % str(t.pk))) + else: + t_sectors_vocs = [] + for t_sector in t.sectors.all(): + if not t_sector.vocabulary or t_sector.vocabulary == 'DAC': + voc = '1' + elif t_sector.vocabulary == 'DAC-3': + voc = '2' + else: + voc = t_sector.vocabulary + + if voc in t_sectors_vocs: + checks.append((u'error', u'multiple sectors with same vocabulary ' + u'specified for transaction ' + u'(id: %s)' % str(t.pk))) + else: + t_sectors_vocs.append(voc) + + if not checks: + checks.append((u'success', u'sectors specified on one level (project or transaction)')) + + return checks + + def country_budget_items(self): + """ + Check if vocabulary is present if there are any country budget items. + Check if percentages add up to 100 if there are multiple budgets. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if self.project.country_budget_items.all(): + if not self.project.country_budget_vocabulary: + checks.append((u'warning', u'vocabulary for country budget items not specified')) + + if self.project.country_budget_items.all().count() > 1: + percentage = 0 + for budget in self.project.country_budget_items.all(): + if not budget.percentage: + checks.append((u'warning', u'country budget item (id: %s) has no ' + u'percentage' % str(budget.pk))) + else: + percentage += budget.percentage + + if percentage == 100: + checks.append((u'success', u'country budget item percentages add up to 100')) + + return checks + + def policy_markers(self): + """ + Check if policy marker has a code and significance. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for policy_marker in self.project.policy_markers.all(): + if not policy_marker.policy_marker: + checks.append((u'warning', u'policy marker (id: %s) has no ' + u'code' % str(policy_marker.pk))) + if not policy_marker.significance: + checks.append((u'warning', u'policy marker (id: %s) has no ' + u'significance' % str(policy_marker.pk))) + + if self.project.policy_markers.all() and not checks: + checks.append((u'success', u'has valid policy marker(s)')) + + return checks + + def budgets(self): + """ + Check if budget has start date, end date and a value. + Check that start date lies before the end date. + Check if the budget has a currency if there is not default currency. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for budget in self.project.budget_items.all(): + if not budget.amount: + checks.append((u'warning', u'budget (id: %s) has no amount' % str(budget.pk))) + if not budget.period_start: + checks.append((u'warning', u'budget (id: %s) has no start date' % str(budget.pk))) + if not budget.period_end: + checks.append((u'warning', u'budget (id: %s) has no end date' % str(budget.pk))) + if budget.period_start and budget.period_end \ + and budget.period_start > budget.period_end: + checks.append((u'warning', u'budget (id: %s) has a start date before the ' + u'end date' % str(budget.pk))) + if not budget.currency and not self.project.currency: + checks.append((u'warning', u'budget (id: %s) has no currency and no default ' + u'currency specified' % str(budget.pk))) + + if self.project.budget_items.all() and not checks: + checks.append((u'success', u'has valid budget items')) + + return checks + + def planned_disbursements(self): + """ + Check if planned disbursement has start date, end date and a value. + Check that start date lies before the end date. + Check if the planned disbursement has a currency if there is not default currency. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for pd in self.project.planned_disbursements.all(): + if not pd.amount: + checks.append((u'warning', u'planned disbursement (id: %s) has ' + u'no amount' % str(pd.pk))) + if not pd.period_start: + checks.append((u'warning', u'planned disbursement (id: %s) has no start ' + u'date' % str(pd.pk))) + if not pd.period_end: + checks.append((u'warning', u'planned disbursement (id: %s) has no end ' + u'date' % str(pd.pk))) + if pd.period_start and pd.period_end and pd.period_start > pd.period_end: + checks.append((u'warning', u'planned disbursement (id: %s) has a start ' + u'date before the end date' % str(pd.pk))) + if not pd.currency and not self.project.currency: + checks.append((u'warning', u'planned disbursement (id: %s) has no currency and no ' + u'default currency specified' % str(pd.pk))) + + if self.project.planned_disbursements.all() and not checks: + checks.append((u'success', u'has valid planned disbursements')) + + return checks + + def transactions(self): + """ + Check if transaction has a type, date (in the past or today) and value. + Check if the transaction has a currency if there is not default currency. + Check if provider and receiver org have a IATI identifier. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for t in self.project.transactions.all(): + if not t.transaction_type: + checks.append((u'warning', u'transaction (id: %s) has no type' % str(t.pk))) + + if not t.transaction_date: + checks.append((u'warning', u'transaction (id: %s) has no date' % str(t.pk))) + elif t.transaction_date > date.today(): + checks.append((u'warning', u'transaction (id: %s) has a date in ' + u'the future' % str(t.pk))) + + if t.value: + checks.append((u'warning', u'transaction (id: %s) has no value' % str(t.pk))) + + if not (t.currency or self.project.currency): + checks.append((u'warning', u'transaction (id: %s) has no currency and no default ' + u'currency specified' % str(t.pk))) + + if t.receiver_organisation and not t.receiver_organisation.iati_org_id: + checks.append((u'warning', u'receiver organisation of transaction (id: %s) has no ' + u'IATI identifier' % str(t.pk))) + + if t.provider_organisation and not t.provider_organisation.iati_org_id: + checks.append((u'warning', u'provider organisation of transaction (id: %s) has no ' + u'IATI identifier' % str(t.pk))) + + if self.project.transactions.all() and not checks: + checks.append((u'success', u'has valid transaction(s)')) + + return checks + + def document_link(self): + """ + Check if document link has an url, format, title and category. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for doc in self.project.documents.all(): + if not (doc.url or doc.document): + checks.append((u'warning', u'document link (id: %s) has no url or document ' + u'specified' % str(doc.pk))) + + if not doc.format: + checks.append((u'warning', u'document link (id: %s) has no format ' + u'specified' % str(doc.pk))) + + if not doc.title: + checks.append((u'warning', u'document link (id: %s) has no title ' + u'specified' % str(doc.pk))) + + if not doc.category: + checks.append((u'warning', u'document link (id: %s) has no category ' + u'specified' % str(doc.pk))) + + if self.project.documents.all() and not checks: + checks.append((u'success', u'has valid document(s)')) + + return checks + + def related_activity(self): + """ + Check if related project has an IATI identifier and relation. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for related in self.project.related_projects.all(): + if not (related.related_project or related.related_iati_id): + checks.append((u'warning', u'related project or IATI identifier not specified')) + elif not (related.related_project.iati_activity_id or related.related_iati_id): + checks.append((u'warning', u'related project (id: %s) has no IATI identifier and ' + u'no IATI identifier ' + u'specified' % str(related.related_project.pk))) + + if not related.relation: + checks.append((u'warning', u'relation missing for related project')) + + for related_to in self.project.related_to_projects.all(): + if not (related_to.project or related_to.related_iati_id): + checks.append((u'warning', u'related to project or IATI identifier not specified')) + elif not (related_to.project.iati_activity_id or related_to.related_iati_id): + checks.append((u'warning', u'related to project (id: %s) has no IATI identifier ' + u'and no IATI identifier ' + u'specified' % str(related_to.project.pk))) + + if not related_to.relation: + checks.append((u'warning', u'relation missing for related to project')) + + if (self.project.related_projects.all() or self.project.related_to_projects.all()) \ + and not checks: + checks.append((u'success', u'has valid document(s)')) + + return checks + + def legacy_data(self): + """ + Check if legacy data has a name and value. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for ld in self.project.legacy_data.all(): + if not ld.name: + checks.append((u'warning', u'legacy data (id: %s) has no name ' + u'specified' % str(ld.pk))) + + if not ld.value: + checks.append((u'warning', u'legacy data (id: %s) has no value ' + u'specified' % str(ld.pk))) + + if self.project.legacy_data.all() and not checks: + checks.append((u'success', u'has valid legacy data')) + + return checks + + def conditions(self): + """ + Check if condition has a type and description. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + # TODO: Change conditions attached (1 if there are conditions else 0) + checks = [] + + for condition in self.project.conditions.all(): + if not condition.type: + checks.append((u'warning', u'condition (id: %s) has no type ' + u'specified' % str(condition.pk))) + + if not condition.text: + checks.append((u'warning', u'condition (id: %s) has no description ' + u'specified' % str(condition.pk))) + + if self.project.conditions.all() and not checks: + checks.append((u'success', u'has valid condition(s)')) + + return checks + + def results(self): + """ + Check if result has a type, title and at least one indicator. + Check if indicator has a measure and title. + Check if indicator baseline has year and value. + Check if indicator period has a start and end date, and start before end. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + for result in self.project.results.all(): + if not result.type: + checks.append((u'warning', u'result (id: %s) has no type ' + u'specified' % str(result.pk))) + + if not result.title: + checks.append((u'warning', u'result (id: %s) has no title ' + u'specified' % str(result.pk))) + + if not result.indicators.all(): + checks.append((u'warning', u'result (id: %s) has no indicators' % str(result.pk))) + + for indicator in result.indicators.all(): + if not indicator.measure: + checks.append((u'warning', u'indicator (id: %s) has no measure ' + u'specified' % str(indicator.pk))) + + if not indicator.title: + checks.append((u'warning', u'indicator (id: %s) has no title ' + u'specified' % str(indicator.pk))) + + if (indicator.baseline_value and not indicator.baseline_year) or \ + (not indicator.baseline_value and indicator.baseline_year): + checks.append((u'warning', u'indicator (id: %s) baseline has no value or year ' + u'specified' % str(indicator.pk))) + + for period in indicator.periods.all(): + if not (period.period_start or period.period_end): + checks.append((u'warning', u'indicator period (id: %s) has no start and ' + u'end date specified' % str(period.pk))) + elif period.period_start > period.period_end: + checks.append((u'warning', u'indicator period (id: %s) has a start date ' + u'later than the end date' % str(period.pk))) + + if self.project.results.all() and not checks: + checks.append((u'success', u'has valid result(s)')) + + return checks + + def crs_add(self): + """ + Check if crs add other flags have a code and significance. + Check if loan status year is present if any of the other loan status fields + is present. + Check if loan status currency or default currency is present if any of + the other loan status fields is present. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if hasattr(self.project, 'crsadd'): + c = self.project.crsadd + for flag in c.other_flags.all(): + if not flag.code: + checks.append((u'warning', u'CRS other flag (id: %s) has no code ' + u'specified' % str(flag.pk))) + + if not flag.significance: + checks.append((u'warning', u'CRS other flag (id: %s) has no significance ' + u'specified' % str(flag.pk))) + + if not c.loan_status_year and \ + (c.loan_status_currency or c.loan_status_value_date or c.interest_received + or c.principal_outstanding or c.principal_arrears or c.interest_arrears): + checks.append((u'warning', u'CRS (id: %s) has no loan status year ' + u'specified' % str(c.pk))) + + if not (c.loan_status_currency or self.project.currency) and \ + (c.loan_status_year or c.loan_status_value_date or c.interest_received + or c.principal_outstanding or c.principal_arrears or c.interest_arrears): + checks.append((u'warning', u'CRS (id: %s) has no loan status currency specified ' + u'and no default currency specified' % str(c.pk))) + + if not checks: + checks.append((u'success', u'has valid CRS')) + + return checks + + def fss(self): + """ + Check if fss has extraction date. + Check if fss forecast has value, year and currency or a default currency specified. + + :return: List of tuples; Boolean for check passed and string explaining the check + """ + checks = [] + + if hasattr(self.project, 'fss'): + if not self.project.fss.extraction_date: + checks.append((u'warning', u'FSS (id: %s) has no extraction date ' + u'specified' % str(self.project.fss.pk))) + + for forecast in self.project.fss.forecasts.all(): + if not forecast.value: + checks.append((u'warning', u'FSS forecast (id: %s) has no value ' + u'specified' % str(forecast.pk))) + + if not forecast.year: + checks.append((u'warning', u'FSS forecast (id: %s) has no year ' + u'specified' % str(forecast.pk))) + + if not (forecast.currency or self.project.currency): + checks.append((u'warning', u'FSS forecast (id: %s) has no currency specified ' + u'and no default currency ' + u'specified' % str(forecast.pk))) + + if not checks: + checks.append((u'success', u'has valid FSS')) + + return checks + + def execute_all_checks(self): + """ + Executes all checks for a Project. + """ + for check in CHECKS: + for check_result in getattr(self, check)(): + self.checks_results.append(check_result) + + def __init__(self, project): + """ + Check if a Project has all the mandatory fields for exporting a valid IATI v2.01 file. + + :param project: Project object + """ + self.all_checks_passed = True + self.checks_results = [] + self.project = project diff --git a/akvo/iati/elements/budget.py b/akvo/iati/elements/budget.py index 3bf9e04d34..304461de5d 100644 --- a/akvo/iati/elements/budget.py +++ b/akvo/iati/elements/budget.py @@ -17,19 +17,17 @@ def budget(project): budget_elements = [] for budget_item in project.budget_items.all(): - if budget_item.amount: + if budget_item.amount and budget_item.period_start and budget_item.period_end: element = etree.Element("budget") if budget_item.type: element.attrib['type'] = budget_item.type - if budget_item.period_start: - period_start_element = etree.SubElement(element, "period-start") - period_start_element.attrib['iso-date'] = str(budget_item.period_start) + period_start_element = etree.SubElement(element, "period-start") + period_start_element.attrib['iso-date'] = str(budget_item.period_start) - if budget_item.period_end: - period_end_element = etree.SubElement(element, "period-end") - period_end_element.attrib['iso-date'] = str(budget_item.period_end) + period_end_element = etree.SubElement(element, "period-end") + period_end_element.attrib['iso-date'] = str(budget_item.period_end) value_element = etree.SubElement(element, "value") value_element.text = str(budget_item.amount) diff --git a/akvo/iati/elements/conditions.py b/akvo/iati/elements/conditions.py index 5d43784b10..c4d31461a2 100644 --- a/akvo/iati/elements/conditions.py +++ b/akvo/iati/elements/conditions.py @@ -14,13 +14,12 @@ def conditions(project): :param project: Project object :return: A list of Etree elements """ + conditions_element = etree.Element("conditions") + if project.conditions.all(): - conditions_element = etree.Element("conditions") + conditions_element.attrib['attached'] = '1' else: - return [] - - if project.conditions_attached is not None: - conditions_element.attrib['attached'] = '1' if project.conditions_attached else '0' + conditions_element.attrib['attached'] = '0' for condition in project.conditions.all(): if condition.type: diff --git a/akvo/iati/elements/location.py b/akvo/iati/elements/location.py index 8b3c4208ae..c7518791d6 100644 --- a/akvo/iati/elements/location.py +++ b/akvo/iati/elements/location.py @@ -46,13 +46,14 @@ def location(project): narrative_element = etree.SubElement(activity_description_element, "narrative") narrative_element.text = loc.activity_description - if loc.administrative_code and loc.administrative_vocabulary: - administrative_element = etree.SubElement(element, "administrative") - administrative_element.attrib['vocabulary'] = loc.administrative_vocabulary - administrative_element.attrib['code'] = loc.administrative_code - - if loc.administrative_level: - administrative_element.attrib['level'] = str(loc.administrative_code) + for administrative in loc.administratives.all(): + if administrative.code and administrative.vocabulary: + administrative_element = etree.SubElement(element, "administrative") + administrative_element.attrib['vocabulary'] = administrative.vocabulary + administrative_element.attrib['code'] = administrative.code + + if administrative.level: + administrative_element.attrib['level'] = str(administrative.level) if loc.latitude and loc.longitude: point_element = etree.SubElement(element, "point") diff --git a/akvo/iati/elements/sector.py b/akvo/iati/elements/sector.py index 1d22e11da2..0c6056ed0f 100644 --- a/akvo/iati/elements/sector.py +++ b/akvo/iati/elements/sector.py @@ -21,12 +21,19 @@ def sector(project): element = etree.Element("sector") element.attrib['code'] = sec.sector_code - if sec.vocabulary: + if not sec.vocabulary or sec.vocabulary == 'DAC': + element.attrib['vocabulary'] = '1' + elif sec.vocabulary == 'DAC-3': + element.attrib['vocabulary'] = '2' + else: element.attrib['vocabulary'] = sec.vocabulary if sec.percentage: element.attrib['percentage'] = str(sec.percentage) + if sec.text: + element.text = sec.text + sector_elements.append(element) return sector_elements diff --git a/akvo/iati/elements/transaction.py b/akvo/iati/elements/transaction.py index f56bcf44c8..073b5c3fce 100644 --- a/akvo/iati/elements/transaction.py +++ b/akvo/iati/elements/transaction.py @@ -84,21 +84,23 @@ def transaction(project): disbursement_channel_element = etree.SubElement(element, "disbursement-channel") disbursement_channel_element.attrib['code'] = trans.disbursement_channel - if trans.sector: - sector_element = etree.SubElement(element, "sector") - sector_element.attrib['code'] = trans.sector - sector_element.attrib['vocabulary'] = '1' - - if trans.sector_category: - sector_category_element = etree.SubElement(element, "sector") - sector_category_element.attrib['code'] = trans.sector_category - sector_category_element.attrib['vocabulary'] = '2' - - if trans.sector_other: - sector_other_element = etree.SubElement(element, "sector") - sector_other_element.attrib['vocabulary'] = '99' - narrative_element = etree.SubElement(sector_other_element, "narrative") - narrative_element.text = trans.sector_other + for sector in trans.sectors.all(): + if sector.code: + sector_element = etree.SubElement(element, "sector") + sector_element.attrib['code'] = sector.code + + if not sector.vocabulary or sector.vocabulary == 'DAC': + sector_element.attrib['vocabulary'] = '1' + elif sector.vocabulary == 'DAC-3': + sector_element.attrib['vocabulary'] = '2' + else: + sector_element.attrib['vocabulary'] = sector.vocabulary + + if sector.percentage: + sector_element.attrib['percentage'] = str(sector.percentage) + + if sector.text: + sector_element.text = sector.text if trans.recipient_country: recipient_country_element = etree.SubElement(element, "recipient-country") diff --git a/akvo/iati/mandatory_fields.py b/akvo/iati/mandatory_fields.py new file mode 100644 index 0000000000..441e7edf50 --- /dev/null +++ b/akvo/iati/mandatory_fields.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +import checks + + +def check_export_fields(project, version='2.01'): + """ + :param project: Project object + :param version: String of IATI version + :return: List of checks + """ + # TODO: Add check for IATI versions (generic) + version_file = "V%sChecks" % version.replace('.', '') + project_checks = getattr(checks, version_file)(project) + project_checks.execute_all_checks() + return project_checks.all_checks_passed, project_checks.checks_results diff --git a/akvo/rsr/admin.py b/akvo/rsr/admin.py index e9a9e24deb..bd7b8adfce 100644 --- a/akvo/rsr/admin.py +++ b/akvo/rsr/admin.py @@ -161,15 +161,7 @@ class BudgetItemAdminInLine(NestedTabularInline): model = get_model('rsr', 'budgetitem') extra = 1 formset = BudgetItemAdminInLineFormSet - fieldsets = ( - (None, { - 'fields': ('label', 'other_extra', 'type', 'amount', 'period_start', 'period_end', 'value_date') - }), - ('IATI fields (advanced)', { - 'classes': ('collapse',), - 'fields': ('period_start_text', 'period_end_text', ) - }) - ) + fields = ('label', 'other_extra', 'type', 'amount', 'period_start', 'period_end', 'value_date') def get_extra(self, request, obj=None, **kwargs): if obj: @@ -319,17 +311,24 @@ def get_extra(self, request, obj=None, **kwargs): return 1 +class LocationAdministrativeInline(NestedTabularInline): + model = get_model('rsr', 'administrativelocation') + fields = ('code', 'vocabulary', 'level') + extra = 0 + + class ProjectLocationInline(NestedStackedInline): model = get_model('rsr', 'projectlocation') + inlines = (LocationAdministrativeInline,) fieldsets = ( (None, { - 'fields': ('latitude', 'longitude', 'country', 'city', 'state', 'address_1', 'address_2', 'postcode') + 'fields': ('latitude', 'longitude', 'country', 'city', 'state', 'address_1', + 'address_2', 'postcode') }), ('IATI fields (advanced)', { 'classes': ('collapse',), 'fields': ('reference', 'location_code', 'name', 'description', 'activity_description', - 'administrative_code', 'administrative_vocabulary', 'administrative_level', 'exactness', - 'location_reach', 'location_class', 'feature_designation') + 'exactness', 'location_reach', 'location_class', 'feature_designation') }), ) @@ -488,18 +487,26 @@ def get_extra(self, request, obj=None, **kwargs): return 1 +class TransactionSectorInline(NestedTabularInline): + model = get_model('rsr', 'TransactionSector') + fields = ('code', 'vocabulary', 'text') + extra = 0 + + class TransactionInline(NestedStackedInline): model = get_model('rsr', 'Transaction') + inlines = (TransactionSectorInline, ) fieldsets = ( (None, { 'fields': ('reference', 'transaction_type', 'value', 'transaction_date', 'description') }), ('IATI fields (advanced)', { 'classes': ('collapse',), - 'fields': ('currency', 'value_date', 'provider_organisation', 'provider_organisation_activity', - 'receiver_organisation', 'receiver_organisation_activity', 'aid_type', 'disbursement_channel', - 'finance_type', 'flow_type', 'tied_status', 'recipient_country', 'recipient_region', - 'recipient_region_vocabulary', 'sector', 'sector_category', 'sector_other') + 'fields': ('currency', 'value_date', 'provider_organisation', + 'provider_organisation_activity', 'receiver_organisation', + 'receiver_organisation_activity', 'aid_type', 'disbursement_channel', + 'finance_type', 'flow_type', 'tied_status', 'recipient_country', + 'recipient_region', 'recipient_region_vocabulary') }), ) @@ -676,7 +683,7 @@ class ProjectAdmin(TimestampsAdminDisplayMixin, ObjectPermissionsModelAdmin, Nes 'description': u'

%s

' % _( u'Optionally, you can add additional information based on the IATI standard.' ), - 'fields': ('conditions_attached',), + 'fields': (), }), (_(u'Keywords'), { 'description': u'

%s

' % _( diff --git a/akvo/rsr/migrations/0002_auto_20150326_1823.py b/akvo/rsr/migrations/0002_auto_20150326_1823.py new file mode 100644 index 0000000000..0732dc48f4 --- /dev/null +++ b/akvo/rsr/migrations/0002_auto_20150326_1823.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.db.models.deletion +import akvo.rsr.fields +import django.core.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('rsr', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='AdministrativeLocation', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('code', akvo.rsr.fields.ValidXMLCharField(max_length=25, verbose_name='administrative code', blank=True)), + ('vocabulary', akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='administrative vocabulary', blank=True)), + ('level', models.PositiveSmallIntegerField(max_length=1, null=True, verbose_name='administrative level', blank=True)), + ('location', models.ForeignKey(related_name='administratives', verbose_name='location', to='rsr.ProjectLocation')), + ], + options={ + 'verbose_name': 'location administrative', + 'verbose_name_plural': 'location administratives', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='CrsAdd', + fields=[ + ('project', models.OneToOneField(primary_key=True, serialize=False, to='rsr.Project')), + ('loan_terms_rate1', models.DecimalField(decimal_places=2, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)], max_digits=5, blank=True, null=True, verbose_name='rate 1')), + ('loan_terms_rate2', models.DecimalField(decimal_places=2, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)], max_digits=5, blank=True, null=True, verbose_name='rate 2')), + ('repayment_type', akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='repayment type')), + ('repayment_plan', akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='repayment plan')), + ('commitment_date', models.DateField(null=True, verbose_name='commitment date', blank=True)), + ('repayment_first_date', models.DateField(null=True, verbose_name='first repayment date', blank=True)), + ('repayment_final_date', models.DateField(null=True, verbose_name='final repayment date', blank=True)), + ('loan_status_year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='loan status year', blank=True)), + ('loan_status_currency', akvo.rsr.fields.ValidXMLCharField(max_length=3, verbose_name='currency', blank=True)), + ('loan_status_value_date', models.DateField(null=True, verbose_name='loan status value date', blank=True)), + ('interest_received', models.DecimalField(null=True, verbose_name='interest received', max_digits=10, decimal_places=2, blank=True)), + ('principal_outstanding', models.DecimalField(null=True, verbose_name='principal outstanding', max_digits=10, decimal_places=2, blank=True)), + ('principal_arrears', models.DecimalField(null=True, verbose_name='principal arrears', max_digits=10, decimal_places=2, blank=True)), + ('interest_arrears', models.DecimalField(null=True, verbose_name='interest arrears', max_digits=10, decimal_places=2, blank=True)), + ], + options={ + 'verbose_name': 'CRS reporting', + 'verbose_name_plural': 'CRS reporting', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='CrsAddOtherFlag', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('code', akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='code')), + ('significance', models.NullBooleanField(verbose_name='significance')), + ('crs', models.ForeignKey(related_name='other_flags', verbose_name='crs', to='rsr.CrsAdd')), + ], + options={ + 'verbose_name': 'CRS other flag', + 'verbose_name_plural': 'CRS other flags', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Fss', + fields=[ + ('project', models.OneToOneField(primary_key=True, serialize=False, to='rsr.Project')), + ('extraction_date', models.DateField(null=True, verbose_name='extraction date', blank=True)), + ('priority', models.NullBooleanField(verbose_name='priority')), + ('phaseout_year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='phaseout year', blank=True)), + ], + options={ + 'verbose_name': 'FSS', + 'verbose_name_plural': 'FSS', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='FssForecast', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='year', blank=True)), + ('value_date', models.DateField(null=True, verbose_name='value date', blank=True)), + ('currency', akvo.rsr.fields.ValidXMLCharField(max_length=3, verbose_name='currency', blank=True)), + ('value', models.DecimalField(null=True, verbose_name='interest received', max_digits=10, decimal_places=2, blank=True)), + ('fss', models.ForeignKey(related_name='forecasts', verbose_name='fss', to='rsr.Fss')), + ], + options={ + 'verbose_name': 'FSS forecast', + 'verbose_name_plural': 'FSS forecasts', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='TransactionSector', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('code', akvo.rsr.fields.ValidXMLCharField(max_length=5, verbose_name='sector', blank=True)), + ('text', akvo.rsr.fields.ValidXMLCharField(help_text='(max 100 characters)', max_length=100, verbose_name='description', blank=True)), + ('vocabulary', akvo.rsr.fields.ValidXMLCharField(max_length=5, verbose_name='vocabulary', blank=True)), + ('project', models.ForeignKey(related_name='sectors', verbose_name='transaction', to='rsr.Transaction')), + ], + options={ + 'verbose_name': 'transaction sector', + 'verbose_name_plural': 'transaction sectors', + }, + bases=(models.Model,), + ), + migrations.RemoveField( + model_name='budgetitem', + name='period_end_text', + ), + migrations.RemoveField( + model_name='budgetitem', + name='period_start_text', + ), + migrations.RemoveField( + model_name='countrybudgetitem', + name='vocabulary', + ), + migrations.RemoveField( + model_name='indicator', + name='description_type', + ), + migrations.RemoveField( + model_name='projectcondition', + name='attached', + ), + migrations.RemoveField( + model_name='projectlocation', + name='administrative_code', + ), + migrations.RemoveField( + model_name='projectlocation', + name='administrative_level', + ), + migrations.RemoveField( + model_name='projectlocation', + name='administrative_vocabulary', + ), + migrations.RemoveField( + model_name='result', + name='description_type', + ), + migrations.RemoveField( + model_name='transaction', + name='aid_type_text', + ), + migrations.RemoveField( + model_name='transaction', + name='disbursement_channel_text', + ), + migrations.RemoveField( + model_name='transaction', + name='finance_type_text', + ), + migrations.RemoveField( + model_name='transaction', + name='flow_type_text', + ), + migrations.RemoveField( + model_name='transaction', + name='tied_status_text', + ), + migrations.RemoveField( + model_name='transaction', + name='transaction_type_text', + ), + migrations.AddField( + model_name='project', + name='country_budget_vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='country budget vocabulary', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='relatedproject', + name='related_iati_id', + field=akvo.rsr.fields.ValidXMLCharField(help_text='The IATI Identifier for the related project.
Fill this in if the related project does not exist in RSR', max_length=100, verbose_name='related project IATI identifier', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='transaction', + name='recipient_country', + field=akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='recipient country', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='transaction', + name='recipient_region', + field=akvo.rsr.fields.ValidXMLCharField(max_length=3, verbose_name='recipient region', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='transaction', + name='recipient_region_vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='recipient region vocabulary', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='relatedproject', + name='related_project', + field=models.ForeignKey(related_name='related_to_projects', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='rsr.Project', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='relatedproject', + name='relation', + field=akvo.rsr.fields.ValidXMLCharField(help_text="The relation between a project and related project. (E.g. select the 'Parent' relation when the selected project here is the parent of this project).", max_length=1, verbose_name='relation'), + preserve_default=True, + ), + ] diff --git a/akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py b/akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py deleted file mode 100644 index 4b799cee06..0000000000 --- a/akvo/rsr/migrations/0094_auto__add_fssforecast__add_fss__add_crsadd__add_crsaddotherflag__del_f.py +++ /dev/null @@ -1,842 +0,0 @@ -# -*- coding: utf-8 -*- -from south.utils import datetime_utils as datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'FssForecast' - db.create_table(u'rsr_fssforecast', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('fss', self.gf('django.db.models.fields.related.ForeignKey')(related_name='forecasts', to=orm['rsr.Fss'])), - ('year', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=4, null=True, blank=True)), - ('value_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), - ('currency', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=3, blank=True)), - ('value', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), - )) - db.send_create_signal('rsr', ['FssForecast']) - - # Adding model 'Fss' - db.create_table(u'rsr_fss', ( - ('project', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['rsr.Project'], unique=True, primary_key=True)), - ('extraction_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), - ('priority', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), - ('phaseout_year', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=4, null=True, blank=True)), - )) - db.send_create_signal('rsr', ['Fss']) - - # Adding model 'CrsAdd' - db.create_table(u'rsr_crsadd', ( - ('project', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['rsr.Project'], unique=True, primary_key=True)), - ('loan_terms_rate1', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2, blank=True)), - ('loan_terms_rate2', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2, blank=True)), - ('repayment_type', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=1)), - ('repayment_plan', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=2)), - ('commitment_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), - ('repayment_first_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), - ('repayment_final_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), - ('loan_status_year', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=4, null=True, blank=True)), - ('loan_status_currency', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=3, blank=True)), - ('loan_status_value_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), - ('interest_received', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), - ('principal_outstanding', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), - ('principal_arrears', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), - ('interest_arrears', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=2, blank=True)), - )) - db.send_create_signal('rsr', ['CrsAdd']) - - # Adding model 'CrsAddOtherFlag' - db.create_table(u'rsr_crsaddotherflag', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('crs', self.gf('django.db.models.fields.related.ForeignKey')(related_name='other_flags', to=orm['rsr.CrsAdd'])), - ('code', self.gf('akvo.rsr.fields.ValidXMLCharField')(max_length=1)), - ('significance', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), - )) - db.send_create_signal('rsr', ['CrsAddOtherFlag']) - - # Deleting field 'Result.description_type' - db.delete_column(u'rsr_result', 'description_type') - - # Deleting field 'Indicator.description_type' - db.delete_column(u'rsr_indicator', 'description_type') - - # Adding field 'RelatedProject.related_iati_id' - db.add_column(u'rsr_relatedproject', 'related_iati_id', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - - # Changing field 'RelatedProject.related_project' - db.alter_column(u'rsr_relatedproject', 'related_project_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, on_delete=models.SET_NULL, to=orm['rsr.Project'])) - # Adding field 'Project.conditions_attached' - db.add_column(u'rsr_project', 'conditions_attached', - self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True), - keep_default=False) - - # Adding field 'Project.country_budget_vocabulary' - db.add_column(u'rsr_project', 'country_budget_vocabulary', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), - keep_default=False) - - # Deleting field 'CountryBudgetItem.vocabulary' - db.delete_column(u'rsr_countrybudgetitem', 'vocabulary') - - # Deleting field 'Transaction.finance_type_text' - db.delete_column(u'rsr_transaction', 'finance_type_text') - - # Deleting field 'Transaction.aid_type_text' - db.delete_column(u'rsr_transaction', 'aid_type_text') - - # Deleting field 'Transaction.transaction_type_text' - db.delete_column(u'rsr_transaction', 'transaction_type_text') - - # Deleting field 'Transaction.flow_type_text' - db.delete_column(u'rsr_transaction', 'flow_type_text') - - # Deleting field 'Transaction.disbursement_channel_text' - db.delete_column(u'rsr_transaction', 'disbursement_channel_text') - - # Deleting field 'Transaction.tied_status_text' - db.delete_column(u'rsr_transaction', 'tied_status_text') - - # Adding field 'Transaction.recipient_country' - db.add_column(u'rsr_transaction', 'recipient_country', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=2, blank=True), - keep_default=False) - - # Adding field 'Transaction.recipient_region' - db.add_column(u'rsr_transaction', 'recipient_region', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=3, blank=True), - keep_default=False) - - # Adding field 'Transaction.recipient_region_vocabulary' - db.add_column(u'rsr_transaction', 'recipient_region_vocabulary', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), - keep_default=False) - - # Adding field 'Transaction.sector' - db.add_column(u'rsr_transaction', 'sector', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=5, blank=True), - keep_default=False) - - # Adding field 'Transaction.sector_category' - db.add_column(u'rsr_transaction', 'sector_category', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=3, blank=True), - keep_default=False) - - # Adding field 'Transaction.sector_other' - db.add_column(u'rsr_transaction', 'sector_other', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=50, blank=True), - keep_default=False) - - # Deleting field 'ProjectCondition.attached' - db.delete_column(u'rsr_projectcondition', 'attached') - - - def backwards(self, orm): - # Deleting model 'FssForecast' - db.delete_table(u'rsr_fssforecast') - - # Deleting model 'Fss' - db.delete_table(u'rsr_fss') - - # Deleting model 'CrsAdd' - db.delete_table(u'rsr_crsadd') - - # Deleting model 'CrsAddOtherFlag' - db.delete_table(u'rsr_crsaddotherflag') - - # Adding field 'Result.description_type' - db.add_column(u'rsr_result', 'description_type', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), - keep_default=False) - - # Adding field 'Indicator.description_type' - db.add_column(u'rsr_indicator', 'description_type', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), - keep_default=False) - - # Deleting field 'RelatedProject.related_iati_id' - db.delete_column(u'rsr_relatedproject', 'related_iati_id') - - - # Changing field 'RelatedProject.related_project' - db.alter_column(u'rsr_relatedproject', 'related_project_id', self.gf('django.db.models.fields.related.ForeignKey')(default='', to=orm['rsr.Project'])) - # Deleting field 'Project.conditions_attached' - db.delete_column(u'rsr_project', 'conditions_attached') - - # Deleting field 'Project.country_budget_vocabulary' - db.delete_column(u'rsr_project', 'country_budget_vocabulary') - - # Adding field 'CountryBudgetItem.vocabulary' - db.add_column(u'rsr_countrybudgetitem', 'vocabulary', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=1, blank=True), - keep_default=False) - - # Adding field 'Transaction.finance_type_text' - db.add_column(u'rsr_transaction', 'finance_type_text', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - # Adding field 'Transaction.aid_type_text' - db.add_column(u'rsr_transaction', 'aid_type_text', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - # Adding field 'Transaction.transaction_type_text' - db.add_column(u'rsr_transaction', 'transaction_type_text', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - # Adding field 'Transaction.flow_type_text' - db.add_column(u'rsr_transaction', 'flow_type_text', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - # Adding field 'Transaction.disbursement_channel_text' - db.add_column(u'rsr_transaction', 'disbursement_channel_text', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - # Adding field 'Transaction.tied_status_text' - db.add_column(u'rsr_transaction', 'tied_status_text', - self.gf('akvo.rsr.fields.ValidXMLCharField')(default='', max_length=100, blank=True), - keep_default=False) - - # Deleting field 'Transaction.recipient_country' - db.delete_column(u'rsr_transaction', 'recipient_country') - - # Deleting field 'Transaction.recipient_region' - db.delete_column(u'rsr_transaction', 'recipient_region') - - # Deleting field 'Transaction.recipient_region_vocabulary' - db.delete_column(u'rsr_transaction', 'recipient_region_vocabulary') - - # Deleting field 'Transaction.sector' - db.delete_column(u'rsr_transaction', 'sector') - - # Deleting field 'Transaction.sector_category' - db.delete_column(u'rsr_transaction', 'sector_category') - - # Deleting field 'Transaction.sector_other' - db.delete_column(u'rsr_transaction', 'sector_other') - - # Adding field 'ProjectCondition.attached' - db.add_column(u'rsr_projectcondition', 'attached', - self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True), - keep_default=False) - - - models = { - u'auth.group': { - 'Meta': {'object_name': 'Group'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - u'auth.permission': { - 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - u'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'rsr.benchmark': { - 'Meta': {'ordering': "('category__name', 'name__order')", 'object_name': 'Benchmark'}, - 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Category']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Benchmarkname']"}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'benchmarks'", 'to': "orm['rsr.Project']"}), - 'value': ('django.db.models.fields.IntegerField', [], {}) - }, - 'rsr.benchmarkname': { - 'Meta': {'ordering': "['order', 'name']", 'object_name': 'Benchmarkname'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '80'}), - 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}) - }, - 'rsr.budgetitem': { - 'Meta': {'ordering': "('label',)", 'unique_together': "(('project', 'label'),)", 'object_name': 'BudgetItem'}, - 'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}), - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.BudgetItemLabel']"}), - 'other_extra': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), - 'period_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'period_end_text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'period_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'period_start_text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'budget_items'", 'to': "orm['rsr.Project']"}), - 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'rsr.budgetitemlabel': { - 'Meta': {'ordering': "('label',)", 'object_name': 'BudgetItemLabel'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'label': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '20', 'db_index': 'True'}) - }, - 'rsr.category': { - 'Meta': {'ordering': "['name']", 'object_name': 'Category'}, - 'benchmarknames': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['rsr.Benchmarkname']", 'symmetrical': 'False', 'blank': 'True'}), - 'focus_area': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'categories'", 'symmetrical': 'False', 'to': "orm['rsr.FocusArea']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'db_index': 'True'}) - }, - 'rsr.country': { - 'Meta': {'ordering': "['name']", 'object_name': 'Country'}, - 'continent': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'db_index': 'True'}), - 'continent_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'db_index': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'iso_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '2', 'db_index': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}) - }, - 'rsr.countrybudgetitem': { - 'Meta': {'object_name': 'CountryBudgetItem'}, - 'code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '6', 'blank': 'True'}), - 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'country_budget_items'", 'to': "orm['rsr.Project']"}) - }, - 'rsr.crsadd': { - 'Meta': {'object_name': 'CrsAdd'}, - 'commitment_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'interest_arrears': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'interest_received': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'loan_status_currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'loan_status_value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'loan_status_year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'loan_terms_rate1': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2', 'blank': 'True'}), - 'loan_terms_rate2': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2', 'blank': 'True'}), - 'principal_arrears': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'principal_outstanding': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True', 'primary_key': 'True'}), - 'repayment_final_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'repayment_first_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'repayment_plan': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2'}), - 'repayment_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}) - }, - 'rsr.crsaddotherflag': { - 'Meta': {'object_name': 'CrsAddOtherFlag'}, - 'code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}), - 'crs': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'other_flags'", 'to': "orm['rsr.CrsAdd']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'significance': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}) - }, - 'rsr.employment': { - 'Meta': {'object_name': 'Employment'}, - 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']", 'null': 'True', 'blank': 'True'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'employments'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.Group']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'job_title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'organisation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'employees'", 'to': "orm['rsr.Organisation']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'employers'", 'to': "orm['rsr.User']"}) - }, - 'rsr.focusarea': { - 'Meta': {'ordering': "['name']", 'object_name': 'FocusArea'}, - 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'max_length': '500'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'image': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100'}), - 'link_to': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}) - }, - 'rsr.fss': { - 'Meta': {'object_name': 'Fss'}, - 'extraction_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'phaseout_year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'priority': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'rsr.fssforecast': { - 'Meta': {'object_name': 'FssForecast'}, - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'fss': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'forecasts'", 'to': "orm['rsr.Fss']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'value': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}) - }, - 'rsr.goal': { - 'Meta': {'object_name': 'Goal'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'goals'", 'to': "orm['rsr.Project']"}), - 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}) - }, - 'rsr.indicator': { - 'Meta': {'object_name': 'Indicator'}, - 'ascending': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'baseline_comment': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'baseline_value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'baseline_year': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'measure': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'result': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'indicators'", 'to': "orm['rsr.Result']"}), - 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}) - }, - 'rsr.indicatorperiod': { - 'Meta': {'object_name': 'IndicatorPeriod'}, - 'actual_comment': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'actual_value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'indicator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'periods'", 'to': "orm['rsr.Indicator']"}), - 'period_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'period_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'target_comment': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'target_value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) - }, - 'rsr.internalorganisationid': { - 'Meta': {'unique_together': "(('recording_org', 'referenced_org'),)", 'object_name': 'InternalOrganisationID'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'identifier': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '200'}), - 'recording_org': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'internal_ids'", 'to': "orm['rsr.Organisation']"}), - 'referenced_org': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reference_ids'", 'to': "orm['rsr.Organisation']"}) - }, - 'rsr.invoice': { - 'Meta': {'ordering': "['-id']", 'object_name': 'Invoice'}, - 'amount': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'amount_received': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'bank': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '4', 'blank': 'True'}), - 'campaign_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '15', 'blank': 'True'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'engine': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'paypal'", 'max_length': '10'}), - 'http_referer': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'ipn': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invoices'", 'to': "orm['rsr.Project']"}), - 'status': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}), - 'test': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'transaction_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.User']", 'null': 'True', 'blank': 'True'}) - }, - 'rsr.keyword': { - 'Meta': {'ordering': "('label',)", 'object_name': 'Keyword'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'label': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '30', 'db_index': 'True'}) - }, - 'rsr.legacydata': { - 'Meta': {'object_name': 'LegacyData'}, - 'iati_equivalent': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'legacy_data'", 'to': "orm['rsr.Project']"}), - 'value': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}) - }, - 'rsr.link': { - 'Meta': {'object_name': 'Link'}, - 'caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'kind': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'links'", 'to': "orm['rsr.Project']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'rsr.molliegateway': { - 'Meta': {'object_name': 'MollieGateway'}, - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'EUR'", 'max_length': '3'}), - 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255'}), - 'notification_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'partner_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10'}) - }, - 'rsr.organisation': { - 'Meta': {'ordering': "['name']", 'object_name': 'Organisation'}, - 'allow_edit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'contact_email': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'contact_person': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), - 'content_owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Organisation']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), - 'facebook': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - 'fax': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'blank': 'True'}), - 'iati_org_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '75', 'unique': 'True', 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'internal_org_ids': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'recording_organisation'", 'symmetrical': 'False', 'through': "orm['rsr.InternalOrganisationID']", 'to': "orm['rsr.Organisation']"}), - 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '2'}), - 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'linkedin': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - 'logo': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'long_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), - 'mobile': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'blank': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'db_index': 'True'}), - 'new_organisation_type': ('django.db.models.fields.IntegerField', [], {'default': '22', 'db_index': 'True'}), - 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), - 'organisation_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'db_index': 'True'}), - 'partner_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['rsr.PartnerType']", 'symmetrical': 'False'}), - 'phone': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '20', 'blank': 'True'}), - 'primary_location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.OrganisationLocation']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), - 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) - }, - 'rsr.organisationaccount': { - 'Meta': {'object_name': 'OrganisationAccount'}, - 'account_level': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'archived'", 'max_length': '12'}), - 'organisation': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Organisation']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'rsr.organisationlocation': { - 'Meta': {'ordering': "['id']", 'object_name': 'OrganisationLocation'}, - 'address_1': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'address_2': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'city': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'latitude': ('akvo.rsr.fields.LatitudeField', [], {'default': '0', 'db_index': 'True'}), - 'location_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'locations'", 'null': 'True', 'to': "orm['rsr.Organisation']"}), - 'longitude': ('akvo.rsr.fields.LongitudeField', [], {'default': '0', 'db_index': 'True'}), - 'postcode': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10', 'blank': 'True'}), - 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}) - }, - 'rsr.partnership': { - 'Meta': {'ordering': "['partner_type']", 'object_name': 'Partnership'}, - 'funding_amount': ('django.db.models.fields.DecimalField', [], {'db_index': 'True', 'null': 'True', 'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'iati_activity_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'iati_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'internal_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'organisation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'partnerships'", 'to': "orm['rsr.Organisation']"}), - 'partner_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '8', 'db_index': 'True'}), - 'partner_type_extra': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'partnerships'", 'to': "orm['rsr.Project']"}), - 'related_activity_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) - }, - 'rsr.partnersite': { - 'Meta': {'ordering': "('organisation__name',)", 'object_name': 'PartnerSite'}, - 'about_box': ('akvo.rsr.fields.ValidXMLTextField', [], {'max_length': '500', 'blank': 'True'}), - 'about_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'cname': ('akvo.rsr.fields.NullCharField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'custom_css': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'custom_favicon': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'custom_logo': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'custom_return_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - 'custom_return_url_text': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), - 'default_language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '5'}), - 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'exclude_keywords': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'facebook_app_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), - 'facebook_button': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'google_translation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'hostname': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '50'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'keywords': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'partnersites'", 'blank': 'True', 'to': "orm['rsr.Keyword']"}), - 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), - 'organisation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Organisation']"}), - 'partner_projects': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'piwik_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'twitter_button': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'ui_translation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'rsr.partnertype': { - 'Meta': {'ordering': "('label',)", 'object_name': 'PartnerType'}, - 'id': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '8', 'primary_key': 'True'}), - 'label': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'rsr.paymentgatewayselector': { - 'Meta': {'object_name': 'PaymentGatewaySelector'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mollie_gateway': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['rsr.MollieGateway']"}), - 'paypal_gateway': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['rsr.PayPalGateway']"}), - 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True'}) - }, - 'rsr.paypalgateway': { - 'Meta': {'object_name': 'PayPalGateway'}, - 'account_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'EUR'", 'max_length': '3'}), - 'description': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'locale': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'US'", 'max_length': '2'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255'}), - 'notification_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}) - }, - 'rsr.planneddisbursement': { - 'Meta': {'object_name': 'PlannedDisbursement'}, - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'period_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'period_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'planned_disbursements'", 'to': "orm['rsr.Project']"}), - 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'updated': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'value': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2', 'blank': 'True'}), - 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'rsr.policymarker': { - 'Meta': {'object_name': 'PolicyMarker'}, - 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'policy_marker': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'policy_markers'", 'to': "orm['rsr.Project']"}), - 'significance': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}) - }, - 'rsr.project': { - 'Meta': {'ordering': "['-id']", 'object_name': 'Project'}, - 'background': ('akvo.rsr.fields.ProjectLimitedTextField', [], {'blank': 'True'}), - 'budget': ('django.db.models.fields.DecimalField', [], {'decimal_places': '2', 'default': '0', 'max_digits': '10', 'blank': 'True', 'null': 'True', 'db_index': 'True'}), - 'capital_spend_percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), - 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'projects'", 'blank': 'True', 'to': "orm['rsr.Category']"}), - 'collaboration_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'conditions_attached': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'country_budget_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'EUR'", 'max_length': '3'}), - 'current_image': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'current_image_caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'current_image_credit': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'current_status': ('akvo.rsr.fields.ProjectLimitedTextField', [], {'blank': 'True'}), - 'date_end_actual': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'date_end_planned': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'date_start_actual': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'date_start_planned': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'default_aid_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'default_finance_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'default_flow_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'default_tied_status': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'donate_button': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'funds': ('django.db.models.fields.DecimalField', [], {'decimal_places': '2', 'default': '0', 'max_digits': '10', 'blank': 'True', 'null': 'True', 'db_index': 'True'}), - 'funds_needed': ('django.db.models.fields.DecimalField', [], {'decimal_places': '2', 'default': '0', 'max_digits': '10', 'blank': 'True', 'null': 'True', 'db_index': 'True'}), - 'goals_overview': ('akvo.rsr.fields.ProjectLimitedTextField', [], {}), - 'hierarchy': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), - 'iati_activity_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'keywords': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'projects'", 'blank': 'True', 'to': "orm['rsr.Keyword']"}), - 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '2'}), - 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'last_update': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'the_project'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.ProjectUpdate']"}), - 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), - 'partners': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'projects'", 'symmetrical': 'False', 'through': "orm['rsr.Partnership']", 'to': "orm['rsr.Organisation']"}), - 'primary_location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.ProjectLocation']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), - 'project_plan': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), - 'project_plan_summary': ('akvo.rsr.fields.ProjectLimitedTextField', [], {}), - 'project_rating': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'project_scope': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'status': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'N'", 'max_length': '1', 'db_index': 'True'}), - 'subtitle': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75'}), - 'sustainability': ('akvo.rsr.fields.ValidXMLTextField', [], {}), - 'sync_owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Organisation']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), - 'sync_owner_secondary_reporter': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'target_group': ('akvo.rsr.fields.ProjectLimitedTextField', [], {'blank': 'True'}), - 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '45', 'db_index': 'True'}) - }, - 'rsr.projectcomment': { - 'Meta': {'ordering': "('-id',)", 'object_name': 'ProjectComment'}, - 'comment': ('akvo.rsr.fields.ValidXMLTextField', [], {}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['rsr.Project']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.User']"}) - }, - 'rsr.projectcondition': { - 'Meta': {'object_name': 'ProjectCondition'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'conditions'", 'to': "orm['rsr.Project']"}), - 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}) - }, - 'rsr.projectcontact': { - 'Meta': {'object_name': 'ProjectContact'}, - 'country': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'contacts'", 'null': 'True', 'to': "orm['rsr.Country']"}), - 'department': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'job_title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'mailing_address': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'organisation': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'person_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'to': "orm['rsr.Project']"}), - 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'telephone': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), - 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) - }, - 'rsr.projectdocument': { - 'Meta': {'ordering': "['-id']", 'object_name': 'ProjectDocument'}, - 'category': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'format': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'to': "orm['rsr.Project']"}), - 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'title_language': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) - }, - 'rsr.projectlocation': { - 'Meta': {'ordering': "['id']", 'object_name': 'ProjectLocation'}, - 'activity_description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'address_1': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'address_2': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'administrative_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), - 'administrative_level': ('django.db.models.fields.PositiveSmallIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), - 'administrative_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'city': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']"}), - 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'exactness': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'feature_designation': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'latitude': ('akvo.rsr.fields.LatitudeField', [], {'default': '0', 'db_index': 'True'}), - 'location_class': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'location_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), - 'location_reach': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'location_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'locations'", 'null': 'True', 'to': "orm['rsr.Project']"}), - 'longitude': ('akvo.rsr.fields.LongitudeField', [], {'default': '0', 'db_index': 'True'}), - 'name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'postcode': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10', 'blank': 'True'}), - 'reference': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}) - }, - 'rsr.projectupdate': { - 'Meta': {'ordering': "['-id']", 'object_name': 'ProjectUpdate'}, - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'language': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'en'", 'max_length': '2'}), - 'last_modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), - 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), - 'photo': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'photo_caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), - 'photo_credit': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), - 'primary_location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.ProjectUpdateLocation']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'project_updates'", 'to': "orm['rsr.Project']"}), - 'text': ('akvo.rsr.fields.ValidXMLTextField', [], {'blank': 'True'}), - 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'db_index': 'True'}), - 'update_method': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'W'", 'max_length': '1', 'db_index': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.User']"}), - 'user_agent': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "''", 'max_length': '200', 'blank': 'True'}), - 'uuid': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "''", 'max_length': '40', 'db_index': 'True', 'blank': 'True'}), - 'video': ('embed_video.fields.EmbedVideoField', [], {'max_length': '200', 'blank': 'True'}), - 'video_caption': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '75', 'blank': 'True'}), - 'video_credit': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}) - }, - 'rsr.projectupdatelocation': { - 'Meta': {'ordering': "['id']", 'object_name': 'ProjectUpdateLocation'}, - 'address_1': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'address_2': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'city': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rsr.Country']", 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'latitude': ('akvo.rsr.fields.LatitudeField', [], {'default': '0', 'db_index': 'True'}), - 'location_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'locations'", 'null': 'True', 'to': "orm['rsr.ProjectUpdate']"}), - 'longitude': ('akvo.rsr.fields.LongitudeField', [], {'default': '0', 'db_index': 'True'}), - 'postcode': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '10', 'blank': 'True'}), - 'state': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}) - }, - 'rsr.publishingstatus': { - 'Meta': {'ordering': "('-status', 'project')", 'object_name': 'PublishingStatus'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['rsr.Project']", 'unique': 'True'}), - 'status': ('akvo.rsr.fields.ValidXMLCharField', [], {'default': "'unpublished'", 'max_length': '30', 'db_index': 'True'}) - }, - 'rsr.recipientcountry': { - 'Meta': {'object_name': 'RecipientCountry'}, - 'country': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipient_countries'", 'to': "orm['rsr.Project']"}), - 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) - }, - 'rsr.recipientregion': { - 'Meta': {'object_name': 'RecipientRegion'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipient_regions'", 'to': "orm['rsr.Project']"}), - 'region': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'region_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}) - }, - 'rsr.relatedproject': { - 'Meta': {'ordering': "['project']", 'object_name': 'RelatedProject'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'related_projects'", 'to': "orm['rsr.Project']"}), - 'related_iati_id': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'related_project': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'related_to_projects'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.Project']"}), - 'relation': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1'}) - }, - 'rsr.result': { - 'Meta': {'object_name': 'Result'}, - 'aggregation_status': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'results'", 'to': "orm['rsr.Project']"}), - 'title': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}) - }, - 'rsr.sector': { - 'Meta': {'object_name': 'Sector'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'percentage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '4', 'decimal_places': '1', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectors'", 'to': "orm['rsr.Project']"}), - 'sector_code': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}), - 'text': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '100', 'blank': 'True'}), - 'vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}) - }, - 'rsr.transaction': { - 'Meta': {'object_name': 'Transaction'}, - 'aid_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'currency': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'description': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '255', 'blank': 'True'}), - 'disbursement_channel': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'finance_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'flow_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transactions'", 'to': "orm['rsr.Project']"}), - 'provider_organisation': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'providing_transactions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.Organisation']"}), - 'provider_organisation_activity': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'receiver_organisation': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'receiving_transactions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['rsr.Organisation']"}), - 'receiver_organisation_activity': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'recipient_country': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'recipient_region': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'recipient_region_vocabulary': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'reference': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '25', 'blank': 'True'}), - 'sector': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '5', 'blank': 'True'}), - 'sector_category': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '3', 'blank': 'True'}), - 'sector_other': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '50', 'blank': 'True'}), - 'tied_status': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '1', 'blank': 'True'}), - 'transaction_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'transaction_type': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '2', 'blank': 'True'}), - 'value': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '11', 'decimal_places': '2', 'blank': 'True'}), - 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'rsr.user': { - 'Meta': {'ordering': "['username']", 'object_name': 'User'}, - 'avatar': (u'sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'null': 'True'}), - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '254'}), - 'first_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_support': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('akvo.rsr.fields.ValidXMLCharField', [], {'max_length': '30', 'blank': 'True'}), - 'notes': ('akvo.rsr.fields.ValidXMLTextField', [], {'default': "''", 'blank': 'True'}), - 'organisations': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'users'", 'blank': 'True', 'through': "orm['rsr.Employment']", 'to': "orm['rsr.Organisation']"}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), - 'username': ('akvo.rsr.fields.ValidXMLCharField', [], {'unique': 'True', 'max_length': '254'}) - } - } - - complete_apps = ['rsr'] \ No newline at end of file diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py index 958bc3bbc8..ae6ae0149a 100644 --- a/akvo/rsr/models/__init__.py +++ b/akvo/rsr/models/__init__.py @@ -36,7 +36,8 @@ from .keyword import Keyword from .legacy_data import LegacyData from .link import Link -from .location import OrganisationLocation, ProjectLocation, ProjectUpdateLocation +from .location import (OrganisationLocation, ProjectLocation, ProjectUpdateLocation, + AdministrativeLocation) from .organisation import Organisation from .organisation_account import OrganisationAccount from .partner_site import PartnerSite @@ -56,7 +57,7 @@ from .related_project import RelatedProject from .result import Result from .sector import Sector -from .transaction import Transaction +from .transaction import Transaction, TransactionSector from .user import User __all__ = [ @@ -84,6 +85,7 @@ 'Link', 'OrganisationLocation', 'ProjectLocation', + 'AdministrativeLocation', 'ProjectUpdateLocation', 'Organisation', 'OrganisationAccount', @@ -107,6 +109,7 @@ 'Result', 'Sector', 'Transaction', + 'TransactionSector', 'User', ] diff --git a/akvo/rsr/models/budget_item.py b/akvo/rsr/models/budget_item.py index 63e9692f19..3a51f93f87 100644 --- a/akvo/rsr/models/budget_item.py +++ b/akvo/rsr/models/budget_item.py @@ -51,9 +51,7 @@ class BudgetItem(models.Model): help_text=u'Select whether this is a planned or actual budget of the project.' ) period_start = models.DateField(_(u'period start'), null=True, blank=True) - period_start_text = ValidXMLCharField(_(u'period start label'), max_length=50, blank=True) period_end = models.DateField(_(u'period end'), null=True, blank=True) - period_end_text = ValidXMLCharField(_(u'period end label'), max_length=50, blank=True) value_date = models.DateField(_(u'value date'), null=True, blank=True) currency = ValidXMLCharField(_(u'currency'), max_length=3, blank=True, choices=codelist_choices(Currency)) diff --git a/akvo/rsr/models/location.py b/akvo/rsr/models/location.py index 117570b7fd..07eca3f2d6 100644 --- a/akvo/rsr/models/location.py +++ b/akvo/rsr/models/location.py @@ -89,12 +89,6 @@ class ProjectLocation(BaseLocation): activity_description = ValidXMLCharField( _(u'activity description'), blank=True, max_length=255, help_text=_(u'(max 255 characters)') ) - administrative_code = ValidXMLCharField(_(u'administrative code'), blank=True, max_length=25) - administrative_vocabulary = ValidXMLCharField(_(u'administrative vocabulary'), blank=True, max_length=2, - choices=codelist_choices(GeographicVocabulary)) - administrative_level = models.PositiveSmallIntegerField( - _(u'administrative level'), blank=True, null=True, max_length=1 - ) exactness = ValidXMLCharField(_(u'exactness'), blank=True, max_length=1, choices=codelist_choices(GeographicExactness)) location_reach = ValidXMLCharField(_(u'reach'), blank=True, max_length=1, @@ -120,6 +114,28 @@ def iati_designation(self): return codelist_value(LocationType, self, 'feature_designation') +class AdministrativeLocation(models.Model): + location = models.ForeignKey( + 'ProjectLocation', verbose_name=_(u'location'), related_name='administratives' + ) + code = ValidXMLCharField(_(u'administrative code'), blank=True, max_length=25) + vocabulary = ValidXMLCharField( + _(u'administrative vocabulary'), blank=True, max_length=2, + choices=codelist_choices(GeographicVocabulary) + ) + level = models.PositiveSmallIntegerField( + _(u'administrative level'), blank=True, null=True, max_length=1 + ) + + def iati_vocabulary(self): + return codelist_value(GeographicVocabulary, self, 'vocabulary') + + class Meta: + app_label = 'rsr' + verbose_name = _(u'location administrative') + verbose_name_plural = _(u'location administratives') + + class ProjectUpdateLocation(BaseLocation): # the project update that's related to this location location_target = models.ForeignKey('ProjectUpdate', null=True, related_name='locations') diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py index 5c3d6d53ff..237fb9d0fe 100644 --- a/akvo/rsr/models/project.py +++ b/akvo/rsr/models/project.py @@ -25,6 +25,8 @@ BudgetIdentifierVocabulary) from akvo.utils import codelist_choices, codelist_value, rsr_image_path, rsr_show_keywords +from ...iati.mandatory_fields import check_export_fields + from ..fields import ProjectLimitedTextField, ValidXMLCharField, ValidXMLTextField from ..mixins import TimestampsMixin @@ -242,10 +244,10 @@ class Project(TimestampsMixin, models.Model): choices=codelist_choices(FlowType)) default_tied_status = ValidXMLCharField(_(u'default tied status'), blank=True, max_length=1, choices=codelist_choices(TiedStatus)) - conditions_attached = models.NullBooleanField(_(u'attached conditions'), blank=True) - country_budget_vocabulary = ValidXMLCharField(_(u'country budget vocabulary'), blank=True, max_length=1, - choices=codelist_choices(BudgetIdentifierVocabulary)) - + country_budget_vocabulary = ValidXMLCharField( + _(u'country budget vocabulary'), blank=True, max_length=1, + choices=codelist_choices(BudgetIdentifierVocabulary) + ) # denormalized data # ================= @@ -803,6 +805,9 @@ def has_indicators(self): return True return False + def check_mandatory_fields(self, version='2.01'): + return check_export_fields(self, version) + class Meta: app_label = 'rsr' verbose_name = _(u'project') diff --git a/akvo/rsr/models/sector.py b/akvo/rsr/models/sector.py index 35d2d7c4a5..0d54640861 100644 --- a/akvo/rsr/models/sector.py +++ b/akvo/rsr/models/sector.py @@ -39,7 +39,7 @@ class Sector(models.Model): ) def __unicode__(self): - return self.iati_sector() + return self.sector_code def iati_sector_codes(self): if self.sector_code and (self.vocabulary == '1' or self.vocabulary == 'DAC'): diff --git a/akvo/rsr/models/transaction.py b/akvo/rsr/models/transaction.py index f5d2a8a551..bcceb69d6b 100644 --- a/akvo/rsr/models/transaction.py +++ b/akvo/rsr/models/transaction.py @@ -10,8 +10,9 @@ from ..fields import ValidXMLCharField -from akvo.codelists.models import (AidType, Currency, DisbursementChannel, FinanceType, FlowType, TiedStatus, - TransactionType, Country, Region, RegionVocabulary, Sector, SectorCategory) +from akvo.codelists.models import (AidType, Currency, DisbursementChannel, FinanceType, FlowType, + TiedStatus, TransactionType, Country, Region, RegionVocabulary, + Sector, SectorCategory, SectorVocabulary) from akvo.utils import codelist_choices, codelist_value @@ -71,13 +72,6 @@ class Transaction(models.Model): ) recipient_region_vocabulary = ValidXMLCharField(_(u'recipient region vocabulary'), blank=True, max_length=1, choices=codelist_choices(RegionVocabulary)) - sector = ValidXMLCharField(_(u'sector'), blank=True, max_length=5, choices=codelist_choices(Sector)) - sector_category = ValidXMLCharField( - _(u'sector category'), blank=True, max_length=3, choices=codelist_choices(SectorCategory) - ) - sector_other = ValidXMLCharField( - _(u'other sector'), blank=True, max_length=50 - ) def __unicode__(self): return self.value @@ -100,13 +94,31 @@ def iati_recipient_region(self): def iati_recipient_region_vocabulary(self): return codelist_value(RegionVocabulary, self, 'recipient_region_vocabulary') + class Meta: + app_label = 'rsr' + verbose_name = _(u'transaction') + verbose_name_plural = _(u'transactions') + + +class TransactionSector(models.Model): + project = models.ForeignKey( + 'Transaction', verbose_name=_(u'transaction'), related_name='sectors' + ) + code = ValidXMLCharField(_(u'sector'), blank=True, max_length=5) + text = ValidXMLCharField( + _(u'description'), blank=True, max_length=100, help_text=_(u'(max 100 characters)') + ) + vocabulary = ValidXMLCharField( + _(u'vocabulary'), blank=True, max_length=5, choices=codelist_choices(SectorVocabulary) + ) + def iati_sector(self): - return codelist_value(Sector, self, 'sector') + return codelist_value(Sector, self, 'code') - def iati_sector_category(self): - return codelist_value(SectorCategory, self, 'sector_category') + def iati_vocabulary(self): + return codelist_value(SectorVocabulary, self, 'vocabulary') class Meta: app_label = 'rsr' - verbose_name = _(u'transaction') - verbose_name_plural = _(u'transactions') + verbose_name = _(u'transaction sector') + verbose_name_plural = _(u'transaction sectors') \ No newline at end of file diff --git a/akvo/templates/project_report.html b/akvo/templates/project_report.html index 660bdd372f..624c802ee2 100644 --- a/akvo/templates/project_report.html +++ b/akvo/templates/project_report.html @@ -185,9 +185,6 @@

{% trans "Locations" %}

{% trans "Description" %} {% trans "Latitude" %} {% trans "Longitude" %} - {% trans "Code" %} - {% trans "Vocabulary" %} - {% trans "Level" %} {% trans "Reach" %} {% trans "Exactness" %} {% trans "Class" %} @@ -202,9 +199,6 @@

{% trans "Locations" %}

{{location.description}} {{location.latitude}} {{location.longitude}} - {{location.location_code}} - {{location.iati_vocabulary}} - {{location.administrative_level|default_if_none:""}} {{location.iati_reach}} {{location.iati_exactness}} {{location.iati_class}} @@ -413,7 +407,6 @@

{% trans "Conditions" %}

{% trans "Condition" %} {% trans "Type" %} - {% trans "Attached" %} @@ -421,7 +414,6 @@

{% trans "Conditions" %}

{{condition.text}} {{condition.iati_type}} - {{condition.attached|yesno:"Attached,Not Attached,"}} {% endfor %} From eeff60bf419c5b9880aa1334eb10e846381702fc Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Fri, 27 Mar 2015 14:11:32 +0100 Subject: [PATCH 06/22] [#1351] Added newline at end of transaction.py --- akvo/rsr/models/transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akvo/rsr/models/transaction.py b/akvo/rsr/models/transaction.py index bcceb69d6b..a8809fbd55 100644 --- a/akvo/rsr/models/transaction.py +++ b/akvo/rsr/models/transaction.py @@ -121,4 +121,4 @@ def iati_vocabulary(self): class Meta: app_label = 'rsr' verbose_name = _(u'transaction sector') - verbose_name_plural = _(u'transaction sectors') \ No newline at end of file + verbose_name_plural = _(u'transaction sectors') From f1934d9478fb59907e758b586534fa6d71724eda Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Sat, 28 Mar 2015 01:10:24 +0100 Subject: [PATCH 07/22] [#1351] Fix IATI codelists in admin --- akvo/rsr/filters.py | 4 +- akvo/rsr/migrations/0001_initial.py | 4 +- .../rsr/migrations/0002_auto_20150326_1823.py | 218 --------- .../rsr/migrations/0002_auto_20150328_0054.py | 452 ++++++++++++++++++ akvo/rsr/models/budget_item.py | 14 +- akvo/rsr/models/country.py | 3 +- akvo/rsr/models/crs_add.py | 18 +- akvo/rsr/models/fss.py | 11 +- akvo/rsr/models/indicator.py | 14 +- akvo/rsr/models/location.py | 19 +- akvo/rsr/models/planned_disbursement.py | 7 +- akvo/rsr/models/policy_marker.py | 8 +- akvo/rsr/models/project.py | 17 +- akvo/rsr/models/project_condition.py | 7 +- akvo/rsr/models/project_contact.py | 23 +- akvo/rsr/models/project_document.py | 27 +- akvo/rsr/models/region.py | 5 +- akvo/rsr/models/related_project.py | 3 +- akvo/rsr/models/result.py | 5 +- akvo/rsr/models/sector.py | 5 +- akvo/rsr/models/transaction.py | 38 +- akvo/utils.py | 22 +- 22 files changed, 608 insertions(+), 316 deletions(-) delete mode 100644 akvo/rsr/migrations/0002_auto_20150326_1823.py create mode 100644 akvo/rsr/migrations/0002_auto_20150328_0054.py diff --git a/akvo/rsr/filters.py b/akvo/rsr/filters.py index 6ac97177f9..45118152fc 100644 --- a/akvo/rsr/filters.py +++ b/akvo/rsr/filters.py @@ -14,7 +14,7 @@ from .models import Project, Organisation, Category, ProjectUpdate from .m49 import M49_CODES, M49_HIERARCHY -from akvo.codelists.models import SectorCategory +from akvo.codelists.store.codelists_v201 import SECTOR_CATEGORY from akvo.utils import codelist_choices ANY_CHOICE = (('', 'All'), ) @@ -22,7 +22,7 @@ def sectors(): sectors_list = [] - for sector in codelist_choices(SectorCategory): + for sector in codelist_choices(SECTOR_CATEGORY): if Project.objects.filter(sectors__sector_code=sector[0]): sectors_list.append(sector) return sectors_list diff --git a/akvo/rsr/migrations/0001_initial.py b/akvo/rsr/migrations/0001_initial.py index da21014667..64770a6d32 100644 --- a/akvo/rsr/migrations/0001_initial.py +++ b/akvo/rsr/migrations/0001_initial.py @@ -848,8 +848,8 @@ class Migration(migrations.Migration): ('provider_organisation_activity', akvo.rsr.fields.ValidXMLCharField(max_length=50, verbose_name='provider organisation activity id', blank=True)), ('receiver_organisation_activity', akvo.rsr.fields.ValidXMLCharField(max_length=50, verbose_name='receiver organisation activity id', blank=True)), ('project', models.ForeignKey(related_name='transactions', verbose_name='project', to='rsr.Project')), - ('provider_organisation', models.ForeignKey(related_name='providing_transactions', on_delete=django.db.models.deletion.SET_NULL, verbose_name='provider organisation', blank=True, to='rsr.Organisation', null=True)), - ('receiver_organisation', models.ForeignKey(related_name='receiving_transactions', on_delete=django.db.models.deletion.SET_NULL, verbose_name='receiver organisation', blank=True, to='rsr.Organisation', null=True)), + ('provider_organisation', models.ForeignKey(related_name='providing_transactions', verbose_name='provider organisation', blank=True, to='rsr.Organisation')), + ('receiver_organisation', models.ForeignKey(related_name='receiving_transactions', verbose_name='receiver organisation', blank=True, to='rsr.Organisation')), ], options={ 'verbose_name': 'transaction', diff --git a/akvo/rsr/migrations/0002_auto_20150326_1823.py b/akvo/rsr/migrations/0002_auto_20150326_1823.py deleted file mode 100644 index 0732dc48f4..0000000000 --- a/akvo/rsr/migrations/0002_auto_20150326_1823.py +++ /dev/null @@ -1,218 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django.db.models.deletion -import akvo.rsr.fields -import django.core.validators - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsr', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='AdministrativeLocation', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('code', akvo.rsr.fields.ValidXMLCharField(max_length=25, verbose_name='administrative code', blank=True)), - ('vocabulary', akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='administrative vocabulary', blank=True)), - ('level', models.PositiveSmallIntegerField(max_length=1, null=True, verbose_name='administrative level', blank=True)), - ('location', models.ForeignKey(related_name='administratives', verbose_name='location', to='rsr.ProjectLocation')), - ], - options={ - 'verbose_name': 'location administrative', - 'verbose_name_plural': 'location administratives', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='CrsAdd', - fields=[ - ('project', models.OneToOneField(primary_key=True, serialize=False, to='rsr.Project')), - ('loan_terms_rate1', models.DecimalField(decimal_places=2, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)], max_digits=5, blank=True, null=True, verbose_name='rate 1')), - ('loan_terms_rate2', models.DecimalField(decimal_places=2, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)], max_digits=5, blank=True, null=True, verbose_name='rate 2')), - ('repayment_type', akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='repayment type')), - ('repayment_plan', akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='repayment plan')), - ('commitment_date', models.DateField(null=True, verbose_name='commitment date', blank=True)), - ('repayment_first_date', models.DateField(null=True, verbose_name='first repayment date', blank=True)), - ('repayment_final_date', models.DateField(null=True, verbose_name='final repayment date', blank=True)), - ('loan_status_year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='loan status year', blank=True)), - ('loan_status_currency', akvo.rsr.fields.ValidXMLCharField(max_length=3, verbose_name='currency', blank=True)), - ('loan_status_value_date', models.DateField(null=True, verbose_name='loan status value date', blank=True)), - ('interest_received', models.DecimalField(null=True, verbose_name='interest received', max_digits=10, decimal_places=2, blank=True)), - ('principal_outstanding', models.DecimalField(null=True, verbose_name='principal outstanding', max_digits=10, decimal_places=2, blank=True)), - ('principal_arrears', models.DecimalField(null=True, verbose_name='principal arrears', max_digits=10, decimal_places=2, blank=True)), - ('interest_arrears', models.DecimalField(null=True, verbose_name='interest arrears', max_digits=10, decimal_places=2, blank=True)), - ], - options={ - 'verbose_name': 'CRS reporting', - 'verbose_name_plural': 'CRS reporting', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='CrsAddOtherFlag', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('code', akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='code')), - ('significance', models.NullBooleanField(verbose_name='significance')), - ('crs', models.ForeignKey(related_name='other_flags', verbose_name='crs', to='rsr.CrsAdd')), - ], - options={ - 'verbose_name': 'CRS other flag', - 'verbose_name_plural': 'CRS other flags', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Fss', - fields=[ - ('project', models.OneToOneField(primary_key=True, serialize=False, to='rsr.Project')), - ('extraction_date', models.DateField(null=True, verbose_name='extraction date', blank=True)), - ('priority', models.NullBooleanField(verbose_name='priority')), - ('phaseout_year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='phaseout year', blank=True)), - ], - options={ - 'verbose_name': 'FSS', - 'verbose_name_plural': 'FSS', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='FssForecast', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='year', blank=True)), - ('value_date', models.DateField(null=True, verbose_name='value date', blank=True)), - ('currency', akvo.rsr.fields.ValidXMLCharField(max_length=3, verbose_name='currency', blank=True)), - ('value', models.DecimalField(null=True, verbose_name='interest received', max_digits=10, decimal_places=2, blank=True)), - ('fss', models.ForeignKey(related_name='forecasts', verbose_name='fss', to='rsr.Fss')), - ], - options={ - 'verbose_name': 'FSS forecast', - 'verbose_name_plural': 'FSS forecasts', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='TransactionSector', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('code', akvo.rsr.fields.ValidXMLCharField(max_length=5, verbose_name='sector', blank=True)), - ('text', akvo.rsr.fields.ValidXMLCharField(help_text='(max 100 characters)', max_length=100, verbose_name='description', blank=True)), - ('vocabulary', akvo.rsr.fields.ValidXMLCharField(max_length=5, verbose_name='vocabulary', blank=True)), - ('project', models.ForeignKey(related_name='sectors', verbose_name='transaction', to='rsr.Transaction')), - ], - options={ - 'verbose_name': 'transaction sector', - 'verbose_name_plural': 'transaction sectors', - }, - bases=(models.Model,), - ), - migrations.RemoveField( - model_name='budgetitem', - name='period_end_text', - ), - migrations.RemoveField( - model_name='budgetitem', - name='period_start_text', - ), - migrations.RemoveField( - model_name='countrybudgetitem', - name='vocabulary', - ), - migrations.RemoveField( - model_name='indicator', - name='description_type', - ), - migrations.RemoveField( - model_name='projectcondition', - name='attached', - ), - migrations.RemoveField( - model_name='projectlocation', - name='administrative_code', - ), - migrations.RemoveField( - model_name='projectlocation', - name='administrative_level', - ), - migrations.RemoveField( - model_name='projectlocation', - name='administrative_vocabulary', - ), - migrations.RemoveField( - model_name='result', - name='description_type', - ), - migrations.RemoveField( - model_name='transaction', - name='aid_type_text', - ), - migrations.RemoveField( - model_name='transaction', - name='disbursement_channel_text', - ), - migrations.RemoveField( - model_name='transaction', - name='finance_type_text', - ), - migrations.RemoveField( - model_name='transaction', - name='flow_type_text', - ), - migrations.RemoveField( - model_name='transaction', - name='tied_status_text', - ), - migrations.RemoveField( - model_name='transaction', - name='transaction_type_text', - ), - migrations.AddField( - model_name='project', - name='country_budget_vocabulary', - field=akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='country budget vocabulary', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='relatedproject', - name='related_iati_id', - field=akvo.rsr.fields.ValidXMLCharField(help_text='The IATI Identifier for the related project.
Fill this in if the related project does not exist in RSR', max_length=100, verbose_name='related project IATI identifier', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='transaction', - name='recipient_country', - field=akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='recipient country', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='transaction', - name='recipient_region', - field=akvo.rsr.fields.ValidXMLCharField(max_length=3, verbose_name='recipient region', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='transaction', - name='recipient_region_vocabulary', - field=akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='recipient region vocabulary', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='relatedproject', - name='related_project', - field=models.ForeignKey(related_name='related_to_projects', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='rsr.Project', null=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='relatedproject', - name='relation', - field=akvo.rsr.fields.ValidXMLCharField(help_text="The relation between a project and related project. (E.g. select the 'Parent' relation when the selected project here is the parent of this project).", max_length=1, verbose_name='relation'), - preserve_default=True, - ), - ] diff --git a/akvo/rsr/migrations/0002_auto_20150328_0054.py b/akvo/rsr/migrations/0002_auto_20150328_0054.py new file mode 100644 index 0000000000..e72dd7ed91 --- /dev/null +++ b/akvo/rsr/migrations/0002_auto_20150328_0054.py @@ -0,0 +1,452 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.db.models.deletion +import akvo.rsr.fields +import django.core.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('rsr', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='AdministrativeLocation', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('code', akvo.rsr.fields.ValidXMLCharField(max_length=25, verbose_name='administrative code', blank=True)), + ('vocabulary', akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='administrative vocabulary', choices=[('A1', 'A1 - Global Admininistrative Unit Layers'), ('A2', 'A2 - UN Second Administrative Level Boundary Project'), ('A3', 'A3 - Global Administrative Areas'), ('A4', 'A4 - ISO Country (3166-1 alpha-2)'), ('G1', 'G1 - Geonames'), ('G2', 'G2 - OpenStreetMap')])), + ('level', models.PositiveSmallIntegerField(max_length=1, null=True, verbose_name='administrative level', blank=True)), + ('location', models.ForeignKey(related_name='administratives', verbose_name='location', to='rsr.ProjectLocation')), + ], + options={ + 'verbose_name': 'location administrative', + 'verbose_name_plural': 'location administratives', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='CrsAdd', + fields=[ + ('project', models.OneToOneField(primary_key=True, serialize=False, to='rsr.Project')), + ('loan_terms_rate1', models.DecimalField(decimal_places=2, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)], max_digits=5, blank=True, null=True, verbose_name='rate 1')), + ('loan_terms_rate2', models.DecimalField(decimal_places=2, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)], max_digits=5, blank=True, null=True, verbose_name='rate 2')), + ('repayment_type', akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='repayment type', choices=[('1', '1 - Equal Principal Payments (EPP)'), ('2', '2 - Annuity'), ('3', '3 - Lump sum'), ('5', '5 - Other')])), + ('repayment_plan', akvo.rsr.fields.ValidXMLCharField(max_length=2, verbose_name='repayment plan', choices=[('1', '1 - Annual'), ('2', '2 - Semi-annual'), ('4', '4 - Quarterly'), ('12', '12 - Monthly')])), + ('commitment_date', models.DateField(null=True, verbose_name='commitment date', blank=True)), + ('repayment_first_date', models.DateField(null=True, verbose_name='first repayment date', blank=True)), + ('repayment_final_date', models.DateField(null=True, verbose_name='final repayment date', blank=True)), + ('loan_status_year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='loan status year', blank=True)), + ('loan_status_currency', akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='currency', choices=[('AED', 'AED - UAE Dirham'), ('AFN', 'AFN - Afghani'), ('ALL', 'ALL - Lek'), ('AMD', 'AMD - Armenian Dram'), ('ANG', 'ANG - Netherlands Antillian Guilder'), ('AOA', 'AOA - Kwanza'), ('ARS', 'ARS - Argentine Peso'), ('AUD', 'AUD - Australian Dollar'), ('AWG', 'AWG - Aruban Guilder'), ('AZN', 'AZN - Azerbaijanian Manat'), ('BAM', 'BAM - Convertible Marks'), ('BBD', 'BBD - Barbados Dollar'), ('BDT', 'BDT - Taka'), ('BGN', 'BGN - Bulgarian Lev'), ('BHD', 'BHD - Bahraini Dinar'), ('BIF', 'BIF - Burundi Franc'), ('BMD', 'BMD - Bermudian Dollar'), ('BND', 'BND - Brunei Dollar'), ('BOB', 'BOB - Boliviano'), ('BOV', 'BOV - Mvdol'), ('BRL', 'BRL - Brazilian Real'), ('BSD', 'BSD - Bahamian Dollar'), ('BTN', 'BTN - Ngultrum'), ('BWP', 'BWP - Pula'), ('BYR', 'BYR - Belarussian Ruble'), ('BZD', 'BZD - Belize Dollar'), ('CAD', 'CAD - Canadian Dollar'), ('CDF', 'CDF - Congolese Franc'), ('CHF', 'CHF - Swiss Franc'), ('CLF', 'CLF - Unidades de fomento'), ('CLP', 'CLP - Chilean Peso'), ('CNY', 'CNY - Yuan Renminbi'), ('COP', 'COP - Colombian Peso'), ('COU', 'COU - Unidad de Valor Real'), ('CRC', 'CRC - Costa Rican Colon'), ('CUC', 'CUC - Peso Convertible'), ('CUP', 'CUP - Cuban Peso'), ('CVE', 'CVE - Cape Verde Escudo'), ('CZK', 'CZK - Czech Koruna'), ('DJF', 'DJF - Djibouti Franc'), ('DKK', 'DKK - Danish Krone'), ('DOP', 'DOP - Dominican Peso'), ('DZD', 'DZD - Algerian Dinar'), ('EEK', 'EEK - Kroon'), ('EGP', 'EGP - Egyptian Pound'), ('ERN', 'ERN - Nakfa'), ('ETB', 'ETB - Ethiopian Birr'), ('EUR', 'EUR - Euro'), ('FJD', 'FJD - Fiji Dollar'), ('FKP', 'FKP - Falkland Islands Pound'), ('GBP', 'GBP - Pound Sterling'), ('GEL', 'GEL - Lari'), ('GHS', 'GHS - Cedi'), ('GIP', 'GIP - Gibraltar Pound'), ('GMD', 'GMD - Dalasi'), ('GNF', 'GNF - Guinea Franc'), ('GTQ', 'GTQ - Quetzal'), ('GYD', 'GYD - Guyana Dollar'), ('HKD', 'HKD - Hong Kong Dollar'), ('HNL', 'HNL - Lempira'), ('HRK', 'HRK - Croatian Kuna'), ('HTG', 'HTG - Gourde'), ('HUF', 'HUF - Forint'), ('IDR', 'IDR - Rupiah'), ('ILS', 'ILS - New Israeli Sheqel'), ('INR', 'INR - Indian Rupee'), ('IQD', 'IQD - Iraqi Dinar'), ('IRR', 'IRR - Iranian Rial'), ('ISK', 'ISK - Iceland Krona'), ('JMD', 'JMD - Jamaican Dollar'), ('JOD', 'JOD - Jordanian Dinar'), ('JPY', 'JPY - Yen'), ('KES', 'KES - Kenyan Shilling'), ('KGS', 'KGS - Som'), ('KHR', 'KHR - Riel'), ('KMF', 'KMF - Comoro Franc'), ('KPW', 'KPW - North Korean Won'), ('KRW', 'KRW - Won'), ('KWD', 'KWD - Kuwaiti Dinar'), ('KYD', 'KYD - Cayman Islands Dollar'), ('KZT', 'KZT - Tenge'), ('LAK', 'LAK - Kip'), ('LBP', 'LBP - Lebanese Pound'), ('LKR', 'LKR - Sri Lanka Rupee'), ('LRD', 'LRD - Liberian Dollar'), ('LSL', 'LSL - Loti'), ('LTL', 'LTL - Lithuanian Litas'), ('LVL', 'LVL - Latvian Lats'), ('LYD', 'LYD - Libyan Dinar'), ('MAD', 'MAD - Moroccan Dirham'), ('MDL', 'MDL - Moldovan Leu'), ('MGA', 'MGA - Malagasy Ariary'), ('MKD', 'MKD - Denar'), ('MMK', 'MMK - Kyat'), ('MNT', 'MNT - Tugrik'), ('MOP', 'MOP - Pataca'), ('MRO', 'MRO - Ouguiya'), ('MUR', 'MUR - Mauritius Rupee'), ('MVR', 'MVR - Rufiyaa'), ('MWK', 'MWK - Malawi Kwacha'), ('MXN', 'MXN - Mexican Peso'), ('MXV', 'MXV - Mexican Unidad de Inversion (UDI)'), ('MYR', 'MYR - Malaysian Ringgit'), ('MZN', 'MZN - Metical'), ('NAD', 'NAD - Namibia Dollar'), ('NGN', 'NGN - Naira'), ('NIO', 'NIO - Cordoba Oro'), ('NOK', 'NOK - Norwegian Krone'), ('NPR', 'NPR - Nepalese Rupee'), ('NZD', 'NZD - New Zealand Dollar'), ('OMR', 'OMR - Rial Omani'), ('PAB', 'PAB - Balboa'), ('PEN', 'PEN - Nuevo Sol'), ('PGK', 'PGK - Kina'), ('PHP', 'PHP - Philippine Peso'), ('PKR', 'PKR - Pakistan Rupee'), ('PLN', 'PLN - Zloty'), ('PYG', 'PYG - Guarani'), ('QAR', 'QAR - Qatari Rial'), ('RON', 'RON - New Leu'), ('RSD', 'RSD - Serbian Dinar'), ('RUB', 'RUB - Russian Ruble'), ('RWF', 'RWF - Rwanda Franc'), ('SAR', 'SAR - Saudi Riyal'), ('SBD', 'SBD - Solomon Islands Dollar'), ('SCR', 'SCR - Seychelles Rupee'), ('SDG', 'SDG - Sudanese Pound'), ('SEK', 'SEK - Swedish Krona'), ('SGD', 'SGD - Singapore Dollar'), ('SHP', 'SHP - Saint Helena Pound'), ('SLL', 'SLL - Leone'), ('SOS', 'SOS - Somali Shilling'), ('SSP', 'SSP - South Sudanese Pound'), ('SRD', 'SRD - Surinam Dollar'), ('STD', 'STD - Dobra'), ('SVC', 'SVC - El Salvador Colon'), ('SYP', 'SYP - Syrian Pound'), ('SZL', 'SZL - Lilangeni'), ('THB', 'THB - Baht'), ('TJS', 'TJS - Somoni'), ('TMT', 'TMT - Manat'), ('TND', 'TND - Tunisian Dinar'), ('TOP', 'TOP - Paanga'), ('TRY', 'TRY - Turkish Lira'), ('TTD', 'TTD - Trinidad and Tobago Dollar'), ('TWD', 'TWD - New Taiwan Dollar'), ('TZS', 'TZS - Tanzanian Shilling'), ('UAH', 'UAH - Hryvnia'), ('UGX', 'UGX - Uganda Shilling'), ('USD', 'USD - US Dollar'), ('USN', 'USN - US Dollar (Next day)'), ('USS', 'USS - US Dollar (Same day)'), ('UYI', 'UYI - Uruguay Peso en Unidades Indexadas'), ('UYU', 'UYU - Peso Uruguayo'), ('UZS', 'UZS - Uzbekistan Sum'), ('VEF', 'VEF - Bolivar'), ('VND', 'VND - Dong'), ('VUV', 'VUV - Vatu'), ('WST', 'WST - Tala'), ('XAF', 'XAF - CFA Franc BEAC'), ('XCD', 'XCD - East Caribbean Dollar'), ('XOF', 'XOF - CFA Franc BCEAO'), ('XPF', 'XPF - CFP Franc'), ('YER', 'YER - Yemeni Rial'), ('ZAR', 'ZAR - Rand'), ('ZMK', 'ZMK - Zambian Kwacha'), ('ZWL', 'ZWL - Zimbabwe Dollar')])), + ('loan_status_value_date', models.DateField(null=True, verbose_name='loan status value date', blank=True)), + ('interest_received', models.DecimalField(null=True, verbose_name='interest received', max_digits=10, decimal_places=2, blank=True)), + ('principal_outstanding', models.DecimalField(null=True, verbose_name='principal outstanding', max_digits=10, decimal_places=2, blank=True)), + ('principal_arrears', models.DecimalField(null=True, verbose_name='principal arrears', max_digits=10, decimal_places=2, blank=True)), + ('interest_arrears', models.DecimalField(null=True, verbose_name='interest arrears', max_digits=10, decimal_places=2, blank=True)), + ], + options={ + 'verbose_name': 'CRS reporting', + 'verbose_name_plural': 'CRS reporting', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='CrsAddOtherFlag', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('code', akvo.rsr.fields.ValidXMLCharField(max_length=1, verbose_name='code', choices=[('1', '1 - Free standing technical cooperation'), ('2', '2 - Programme-based approach'), ('3', '3 - Investment project'), ('4', '4 - Associated financing')])), + ('significance', models.NullBooleanField(verbose_name='significance')), + ('crs', models.ForeignKey(related_name='other_flags', verbose_name='crs', to='rsr.CrsAdd')), + ], + options={ + 'verbose_name': 'CRS other flag', + 'verbose_name_plural': 'CRS other flags', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Fss', + fields=[ + ('project', models.OneToOneField(primary_key=True, serialize=False, to='rsr.Project')), + ('extraction_date', models.DateField(null=True, verbose_name='extraction date', blank=True)), + ('priority', models.NullBooleanField(verbose_name='priority')), + ('phaseout_year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='phaseout year', blank=True)), + ], + options={ + 'verbose_name': 'FSS', + 'verbose_name_plural': 'FSS', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='FssForecast', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('year', models.PositiveIntegerField(max_length=4, null=True, verbose_name='year', blank=True)), + ('value_date', models.DateField(null=True, verbose_name='value date', blank=True)), + ('currency', akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='currency', choices=[('AED', 'AED - UAE Dirham'), ('AFN', 'AFN - Afghani'), ('ALL', 'ALL - Lek'), ('AMD', 'AMD - Armenian Dram'), ('ANG', 'ANG - Netherlands Antillian Guilder'), ('AOA', 'AOA - Kwanza'), ('ARS', 'ARS - Argentine Peso'), ('AUD', 'AUD - Australian Dollar'), ('AWG', 'AWG - Aruban Guilder'), ('AZN', 'AZN - Azerbaijanian Manat'), ('BAM', 'BAM - Convertible Marks'), ('BBD', 'BBD - Barbados Dollar'), ('BDT', 'BDT - Taka'), ('BGN', 'BGN - Bulgarian Lev'), ('BHD', 'BHD - Bahraini Dinar'), ('BIF', 'BIF - Burundi Franc'), ('BMD', 'BMD - Bermudian Dollar'), ('BND', 'BND - Brunei Dollar'), ('BOB', 'BOB - Boliviano'), ('BOV', 'BOV - Mvdol'), ('BRL', 'BRL - Brazilian Real'), ('BSD', 'BSD - Bahamian Dollar'), ('BTN', 'BTN - Ngultrum'), ('BWP', 'BWP - Pula'), ('BYR', 'BYR - Belarussian Ruble'), ('BZD', 'BZD - Belize Dollar'), ('CAD', 'CAD - Canadian Dollar'), ('CDF', 'CDF - Congolese Franc'), ('CHF', 'CHF - Swiss Franc'), ('CLF', 'CLF - Unidades de fomento'), ('CLP', 'CLP - Chilean Peso'), ('CNY', 'CNY - Yuan Renminbi'), ('COP', 'COP - Colombian Peso'), ('COU', 'COU - Unidad de Valor Real'), ('CRC', 'CRC - Costa Rican Colon'), ('CUC', 'CUC - Peso Convertible'), ('CUP', 'CUP - Cuban Peso'), ('CVE', 'CVE - Cape Verde Escudo'), ('CZK', 'CZK - Czech Koruna'), ('DJF', 'DJF - Djibouti Franc'), ('DKK', 'DKK - Danish Krone'), ('DOP', 'DOP - Dominican Peso'), ('DZD', 'DZD - Algerian Dinar'), ('EEK', 'EEK - Kroon'), ('EGP', 'EGP - Egyptian Pound'), ('ERN', 'ERN - Nakfa'), ('ETB', 'ETB - Ethiopian Birr'), ('EUR', 'EUR - Euro'), ('FJD', 'FJD - Fiji Dollar'), ('FKP', 'FKP - Falkland Islands Pound'), ('GBP', 'GBP - Pound Sterling'), ('GEL', 'GEL - Lari'), ('GHS', 'GHS - Cedi'), ('GIP', 'GIP - Gibraltar Pound'), ('GMD', 'GMD - Dalasi'), ('GNF', 'GNF - Guinea Franc'), ('GTQ', 'GTQ - Quetzal'), ('GYD', 'GYD - Guyana Dollar'), ('HKD', 'HKD - Hong Kong Dollar'), ('HNL', 'HNL - Lempira'), ('HRK', 'HRK - Croatian Kuna'), ('HTG', 'HTG - Gourde'), ('HUF', 'HUF - Forint'), ('IDR', 'IDR - Rupiah'), ('ILS', 'ILS - New Israeli Sheqel'), ('INR', 'INR - Indian Rupee'), ('IQD', 'IQD - Iraqi Dinar'), ('IRR', 'IRR - Iranian Rial'), ('ISK', 'ISK - Iceland Krona'), ('JMD', 'JMD - Jamaican Dollar'), ('JOD', 'JOD - Jordanian Dinar'), ('JPY', 'JPY - Yen'), ('KES', 'KES - Kenyan Shilling'), ('KGS', 'KGS - Som'), ('KHR', 'KHR - Riel'), ('KMF', 'KMF - Comoro Franc'), ('KPW', 'KPW - North Korean Won'), ('KRW', 'KRW - Won'), ('KWD', 'KWD - Kuwaiti Dinar'), ('KYD', 'KYD - Cayman Islands Dollar'), ('KZT', 'KZT - Tenge'), ('LAK', 'LAK - Kip'), ('LBP', 'LBP - Lebanese Pound'), ('LKR', 'LKR - Sri Lanka Rupee'), ('LRD', 'LRD - Liberian Dollar'), ('LSL', 'LSL - Loti'), ('LTL', 'LTL - Lithuanian Litas'), ('LVL', 'LVL - Latvian Lats'), ('LYD', 'LYD - Libyan Dinar'), ('MAD', 'MAD - Moroccan Dirham'), ('MDL', 'MDL - Moldovan Leu'), ('MGA', 'MGA - Malagasy Ariary'), ('MKD', 'MKD - Denar'), ('MMK', 'MMK - Kyat'), ('MNT', 'MNT - Tugrik'), ('MOP', 'MOP - Pataca'), ('MRO', 'MRO - Ouguiya'), ('MUR', 'MUR - Mauritius Rupee'), ('MVR', 'MVR - Rufiyaa'), ('MWK', 'MWK - Malawi Kwacha'), ('MXN', 'MXN - Mexican Peso'), ('MXV', 'MXV - Mexican Unidad de Inversion (UDI)'), ('MYR', 'MYR - Malaysian Ringgit'), ('MZN', 'MZN - Metical'), ('NAD', 'NAD - Namibia Dollar'), ('NGN', 'NGN - Naira'), ('NIO', 'NIO - Cordoba Oro'), ('NOK', 'NOK - Norwegian Krone'), ('NPR', 'NPR - Nepalese Rupee'), ('NZD', 'NZD - New Zealand Dollar'), ('OMR', 'OMR - Rial Omani'), ('PAB', 'PAB - Balboa'), ('PEN', 'PEN - Nuevo Sol'), ('PGK', 'PGK - Kina'), ('PHP', 'PHP - Philippine Peso'), ('PKR', 'PKR - Pakistan Rupee'), ('PLN', 'PLN - Zloty'), ('PYG', 'PYG - Guarani'), ('QAR', 'QAR - Qatari Rial'), ('RON', 'RON - New Leu'), ('RSD', 'RSD - Serbian Dinar'), ('RUB', 'RUB - Russian Ruble'), ('RWF', 'RWF - Rwanda Franc'), ('SAR', 'SAR - Saudi Riyal'), ('SBD', 'SBD - Solomon Islands Dollar'), ('SCR', 'SCR - Seychelles Rupee'), ('SDG', 'SDG - Sudanese Pound'), ('SEK', 'SEK - Swedish Krona'), ('SGD', 'SGD - Singapore Dollar'), ('SHP', 'SHP - Saint Helena Pound'), ('SLL', 'SLL - Leone'), ('SOS', 'SOS - Somali Shilling'), ('SSP', 'SSP - South Sudanese Pound'), ('SRD', 'SRD - Surinam Dollar'), ('STD', 'STD - Dobra'), ('SVC', 'SVC - El Salvador Colon'), ('SYP', 'SYP - Syrian Pound'), ('SZL', 'SZL - Lilangeni'), ('THB', 'THB - Baht'), ('TJS', 'TJS - Somoni'), ('TMT', 'TMT - Manat'), ('TND', 'TND - Tunisian Dinar'), ('TOP', 'TOP - Paanga'), ('TRY', 'TRY - Turkish Lira'), ('TTD', 'TTD - Trinidad and Tobago Dollar'), ('TWD', 'TWD - New Taiwan Dollar'), ('TZS', 'TZS - Tanzanian Shilling'), ('UAH', 'UAH - Hryvnia'), ('UGX', 'UGX - Uganda Shilling'), ('USD', 'USD - US Dollar'), ('USN', 'USN - US Dollar (Next day)'), ('USS', 'USS - US Dollar (Same day)'), ('UYI', 'UYI - Uruguay Peso en Unidades Indexadas'), ('UYU', 'UYU - Peso Uruguayo'), ('UZS', 'UZS - Uzbekistan Sum'), ('VEF', 'VEF - Bolivar'), ('VND', 'VND - Dong'), ('VUV', 'VUV - Vatu'), ('WST', 'WST - Tala'), ('XAF', 'XAF - CFA Franc BEAC'), ('XCD', 'XCD - East Caribbean Dollar'), ('XOF', 'XOF - CFA Franc BCEAO'), ('XPF', 'XPF - CFP Franc'), ('YER', 'YER - Yemeni Rial'), ('ZAR', 'ZAR - Rand'), ('ZMK', 'ZMK - Zambian Kwacha'), ('ZWL', 'ZWL - Zimbabwe Dollar')])), + ('value', models.DecimalField(null=True, verbose_name='interest received', max_digits=10, decimal_places=2, blank=True)), + ('fss', models.ForeignKey(related_name='forecasts', verbose_name='fss', to='rsr.Fss')), + ], + options={ + 'verbose_name': 'FSS forecast', + 'verbose_name_plural': 'FSS forecasts', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='TransactionSector', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('code', akvo.rsr.fields.ValidXMLCharField(max_length=5, verbose_name='sector', blank=True)), + ('text', akvo.rsr.fields.ValidXMLCharField(help_text='(max 100 characters)', max_length=100, verbose_name='description', blank=True)), + ('vocabulary', akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=5, verbose_name='vocabulary', choices=[('1', '1 - OECD DAC CRS Purpose Codes (5 digit)'), ('2', '2 - OECD DAC CRS Purpose Codes (3 digit)'), ('3', '3 - Classification of the Functions of Government (UN)'), ('4', '4 - Statistical classification of economic activities in the European Community'), ('5', '5 - National Taxonomy for Exempt Entities (USA)'), ('6', '6 - AidData'), ('99', '99 - Reporting Organisation'), ('98', '98 - Reporting Organisation 2')])), + ('project', models.ForeignKey(related_name='sectors', verbose_name='transaction', to='rsr.Transaction')), + ], + options={ + 'verbose_name': 'transaction sector', + 'verbose_name_plural': 'transaction sectors', + }, + bases=(models.Model,), + ), + migrations.RemoveField( + model_name='budgetitem', + name='period_end_text', + ), + migrations.RemoveField( + model_name='budgetitem', + name='period_start_text', + ), + migrations.RemoveField( + model_name='countrybudgetitem', + name='vocabulary', + ), + migrations.RemoveField( + model_name='indicator', + name='description_type', + ), + migrations.RemoveField( + model_name='projectcondition', + name='attached', + ), + migrations.RemoveField( + model_name='projectlocation', + name='administrative_code', + ), + migrations.RemoveField( + model_name='projectlocation', + name='administrative_level', + ), + migrations.RemoveField( + model_name='projectlocation', + name='administrative_vocabulary', + ), + migrations.RemoveField( + model_name='result', + name='description_type', + ), + migrations.RemoveField( + model_name='transaction', + name='aid_type_text', + ), + migrations.RemoveField( + model_name='transaction', + name='disbursement_channel_text', + ), + migrations.RemoveField( + model_name='transaction', + name='finance_type_text', + ), + migrations.RemoveField( + model_name='transaction', + name='flow_type_text', + ), + migrations.RemoveField( + model_name='transaction', + name='tied_status_text', + ), + migrations.RemoveField( + model_name='transaction', + name='transaction_type_text', + ), + migrations.AddField( + model_name='project', + name='country_budget_vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='country budget vocabulary', choices=[('1', '1 - IATI'), ('2', '2 - Country Chart of Accounts'), ('3', '3 - Other Country System'), ('4', '4 - Reporting Organisation'), ('5', '5 - Other')]), + preserve_default=True, + ), + migrations.AddField( + model_name='relatedproject', + name='related_iati_id', + field=akvo.rsr.fields.ValidXMLCharField(help_text='The IATI Identifier for the related project.
Fill this in if the related project does not exist in RSR', max_length=100, verbose_name='related project IATI identifier', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='transaction', + name='recipient_country', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='recipient country', choices=[('AF', 'AF - Afghanistan'), ('AX', 'AX - \xc5land Islands'), ('AL', 'AL - Albania'), ('DZ', 'DZ - Algeria'), ('AS', 'AS - American Samoa'), ('AD', 'AD - Andorra'), ('AO', 'AO - Angola'), ('AI', 'AI - Anguilla'), ('AQ', 'AQ - Antarctica'), ('AG', 'AG - Antigua and Barbuda'), ('AR', 'AR - Argentina'), ('AM', 'AM - Armenia'), ('AW', 'AW - Aruba'), ('AU', 'AU - Australia'), ('AT', 'AT - Austria'), ('AZ', 'AZ - Azerbaijan'), ('BS', 'BS - Bahamas'), ('BH', 'BH - Bahrain'), ('BD', 'BD - Bangladesh'), ('BB', 'BB - Barbados'), ('BY', 'BY - Belarus'), ('BE', 'BE - Belgium'), ('BZ', 'BZ - Belize'), ('BJ', 'BJ - Benin'), ('BM', 'BM - Bermuda'), ('BT', 'BT - Bhutan'), ('BO', 'BO - Bolivia, Plurinational State of'), ('BQ', 'BQ - Bonaire, Saint Eustatius and Saba'), ('BA', 'BA - Bosnia and Herzegovina'), ('BW', 'BW - Botswana'), ('BV', 'BV - Bouvet Island'), ('BR', 'BR - Brazil'), ('IO', 'IO - British Indian Ocean Territory'), ('BN', 'BN - Brunei Darussalam'), ('BG', 'BG - Bulgaria'), ('BF', 'BF - Burkina Faso'), ('BI', 'BI - Burundi'), ('KH', 'KH - Cambodia'), ('CM', 'CM - Cameroon'), ('CA', 'CA - Canada'), ('CV', 'CV - Cape Verde'), ('KY', 'KY - Cayman Islands'), ('CF', 'CF - Central African Republic'), ('TD', 'TD - Chad'), ('CL', 'CL - Chile'), ('CN', 'CN - China'), ('CX', 'CX - Christmas Island'), ('CC', 'CC - Cocos (Keeling) Islands'), ('CO', 'CO - Colombia'), ('KM', 'KM - Comoros'), ('CG', 'CG - Congo'), ('CD', 'CD - Congo, The Democratic Republic of the'), ('CK', 'CK - Cook Islands'), ('CR', 'CR - Costa Rica'), ('CI', 'CI - C\xf4te Divoire'), ('HR', 'HR - Croatia'), ('CU', 'CU - Cuba'), ('CW', 'CW - Cura\xe7ao'), ('CY', 'CY - Cyprus'), ('CZ', 'CZ - Czech Republic'), ('DK', 'DK - Denmark'), ('DJ', 'DJ - Djibouti'), ('DM', 'DM - Dominica'), ('DO', 'DO - Dominican Republic'), ('EC', 'EC - Ecuador'), ('EG', 'EG - Egypt'), ('SV', 'SV - El Salvador'), ('GQ', 'GQ - Equatorial Guinea'), ('ER', 'ER - Eritrea'), ('EE', 'EE - Estonia'), ('ET', 'ET - Ethiopia'), ('FK', 'FK - Falkland Islands (Malvinas)'), ('FO', 'FO - Faroe Islands'), ('FJ', 'FJ - Fiji'), ('FI', 'FI - Finland'), ('FR', 'FR - France'), ('GF', 'GF - French Guiana'), ('PF', 'PF - French Polynesia'), ('TF', 'TF - French Southern Territories'), ('GA', 'GA - Gabon'), ('GM', 'GM - Gambia'), ('GE', 'GE - Georgia'), ('DE', 'DE - Germany'), ('GH', 'GH - Ghana'), ('GI', 'GI - Gibraltar'), ('GR', 'GR - Greece'), ('GL', 'GL - Greenland'), ('GD', 'GD - Grenada'), ('GP', 'GP - Guadeloupe'), ('GU', 'GU - Guam'), ('GT', 'GT - Guatemala'), ('GG', 'GG - Guernsey'), ('GN', 'GN - Guinea'), ('GW', 'GW - Guinea-Bissau'), ('GY', 'GY - Guyana'), ('HT', 'HT - Haiti'), ('HM', 'HM - Heard Island and Mcdonald Islands'), ('VA', 'VA - Holy See (Vatican City State)'), ('HN', 'HN - Honduras'), ('HK', 'HK - Hong Kong'), ('HU', 'HU - Hungary'), ('IS', 'IS - Iceland'), ('IN', 'IN - India'), ('ID', 'ID - Indonesia'), ('IR', 'IR - Iran, Islamic Republic of'), ('IQ', 'IQ - Iraq'), ('IE', 'IE - Ireland'), ('IM', 'IM - Isle of Man'), ('IL', 'IL - Israel'), ('IT', 'IT - Italy'), ('JM', 'JM - Jamaica'), ('JP', 'JP - Japan'), ('JE', 'JE - Jersey'), ('JO', 'JO - Jordan'), ('KZ', 'KZ - Kazakhstan'), ('KE', 'KE - Kenya'), ('KI', 'KI - Kiribati'), ('KP', 'KP - Korea, Democratic Peoples Republic of'), ('KR', 'KR - Korea, Republic of'), ('XK', 'XK - Kosovo'), ('KW', 'KW - Kuwait'), ('KG', 'KG - Kyrgyzstan'), ('LA', 'LA - Lao Peoples Democratic Republic'), ('LV', 'LV - Latvia'), ('LB', 'LB - Lebanon'), ('LS', 'LS - Lesotho'), ('LR', 'LR - Liberia'), ('LY', 'LY - Libyan Arab Jamahiriya'), ('LI', 'LI - Liechtenstein'), ('LT', 'LT - Lithuania'), ('LU', 'LU - Luxembourg'), ('MO', 'MO - Macao'), ('MK', 'MK - Macedonia, The Former Yugoslav Republic of'), ('MG', 'MG - Madagascar'), ('MW', 'MW - Malawi'), ('MY', 'MY - Malaysia'), ('MV', 'MV - Maldives'), ('ML', 'ML - Mali'), ('MT', 'MT - Malta'), ('MH', 'MH - Marshall Islands'), ('MQ', 'MQ - Martinique'), ('MR', 'MR - Mauritania'), ('MU', 'MU - Mauritius'), ('YT', 'YT - Mayotte'), ('MX', 'MX - Mexico'), ('FM', 'FM - Micronesia, Federated States of'), ('MD', 'MD - Moldova, Republic of'), ('MC', 'MC - Monaco'), ('MN', 'MN - Mongolia'), ('ME', 'ME - Montenegro'), ('MS', 'MS - Montserrat'), ('MA', 'MA - Morocco'), ('MZ', 'MZ - Mozambique'), ('MM', 'MM - Myanmar'), ('NA', 'NA - Namibia'), ('NR', 'NR - Nauru'), ('NP', 'NP - Nepal'), ('NL', 'NL - Netherlands'), ('AN', 'AN - Netherland Antilles'), ('NC', 'NC - New Caledonia'), ('NZ', 'NZ - New Zealand'), ('NI', 'NI - Nicaragua'), ('NE', 'NE - Niger'), ('NG', 'NG - Nigeria'), ('NU', 'NU - Niue'), ('NF', 'NF - Norfolk Island'), ('MP', 'MP - Northern Mariana Islands'), ('NO', 'NO - Norway'), ('OM', 'OM - Oman'), ('PK', 'PK - Pakistan'), ('PW', 'PW - Palau'), ('PS', 'PS - Palestinian Territory, Occupied'), ('PA', 'PA - Panama'), ('PG', 'PG - Papua New Guinea'), ('PY', 'PY - Paraguay'), ('PE', 'PE - Peru'), ('PH', 'PH - Philippines'), ('PN', 'PN - Pitcairn'), ('PL', 'PL - Poland'), ('PT', 'PT - Portugal'), ('PR', 'PR - Puerto Rico'), ('QA', 'QA - Qatar'), ('RE', 'RE - Reunion'), ('RO', 'RO - Romania'), ('RU', 'RU - Russian Federation'), ('RW', 'RW - Rwanda'), ('BL', 'BL - Saint Barth\xe9lemy'), ('SH', 'SH - Saint Helena, Ascension and Tristan da Cunha'), ('KN', 'KN - Saint Kitts and Nevis'), ('LC', 'LC - Saint Lucia'), ('MF', 'MF - Saint Martin (French Part)'), ('PM', 'PM - Saint Pierre and Miquelon'), ('VC', 'VC - Saint Vincent and the Grenadines'), ('WS', 'WS - Samoa'), ('SM', 'SM - San Marino'), ('ST', 'ST - Sao Tome and Principe'), ('SA', 'SA - Saudi Arabia'), ('SN', 'SN - Senegal'), ('RS', 'RS - Serbia'), ('SC', 'SC - Seychelles'), ('SL', 'SL - Sierra Leone'), ('SG', 'SG - Singapore'), ('SX', 'SX - Sint Maarten (Dutch Part)'), ('SK', 'SK - Slovakia'), ('SI', 'SI - Slovenia'), ('SB', 'SB - Solomon Islands'), ('SO', 'SO - Somalia'), ('ZA', 'ZA - South Africa'), ('GS', 'GS - South Georgia and the South Sandwich Islands'), ('SS', 'SS - South Sudan'), ('ES', 'ES - Spain'), ('LK', 'LK - Sri Lanka'), ('SD', 'SD - Sudan'), ('SR', 'SR - Suriname'), ('SJ', 'SJ - Svalbard and Jan Mayen'), ('SZ', 'SZ - Swaziland'), ('SE', 'SE - Sweden'), ('CH', 'CH - Switzerland'), ('SY', 'SY - Syrian Arab Republic'), ('TW', 'TW - Taiwan, Province of China'), ('TJ', 'TJ - Tajikistan'), ('TZ', 'TZ - Tanzania, United Republic of'), ('TH', 'TH - Thailand'), ('TL', 'TL - Timor-Leste'), ('TG', 'TG - Togo'), ('TK', 'TK - Tokelau'), ('TO', 'TO - Tonga'), ('TT', 'TT - Trinidad and Tobago'), ('TN', 'TN - Tunisia'), ('TR', 'TR - Turkey'), ('TM', 'TM - Turkmenistan'), ('TC', 'TC - Turks and Caicos Islands'), ('TV', 'TV - Tuvalu'), ('UG', 'UG - Uganda'), ('UA', 'UA - Ukraine'), ('AE', 'AE - United Arab Emirates'), ('GB', 'GB - United Kingdom'), ('US', 'US - United States'), ('UM', 'UM - United States Minor Outlying Islands'), ('UY', 'UY - Uruguay'), ('UZ', 'UZ - Uzbekistan'), ('VU', 'VU - Vanuatu'), ('VE', 'VE - Venezuela, Bolivarian Republic of'), ('VN', 'VN - Viet Nam'), ('VG', 'VG - Virgin Islands, British'), ('VI', 'VI - Virgin Islands, U.S.'), ('WF', 'WF - Wallis and Futuna'), ('EH', 'EH - Western Sahara'), ('YE', 'YE - Yemen'), ('ZM', 'ZM - Zambia'), ('ZW', 'ZW - Zimbabwe')]), + preserve_default=True, + ), + migrations.AddField( + model_name='transaction', + name='recipient_region', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='recipient region', choices=[('88', '88 - States Ex-Yugoslavia unspecified'), ('89', '89 - Europe, regional'), ('189', '189 - North of Sahara, regional'), ('289', '289 - South of Sahara, regional'), ('298', '298 - Africa, regional'), ('380', '380 - West Indies, regional'), ('389', '389 - North and Central America, regional'), ('489', '489 - South America, regional'), ('498', '498 - America, regional'), ('589', '589 - Middle East, regional'), ('619', '619 - Central Asia, regional'), ('679', '679 - South Asia, regional'), ('689', '689 - South and Central Asia, regional'), ('789', '789 - Far East Asia, regional'), ('798', '798 - Asia, regional'), ('889', '889 - Oceania, regional'), ('998', '998 - Developing countries, unspecified')]), + preserve_default=True, + ), + migrations.AddField( + model_name='transaction', + name='recipient_region_vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='recipient region vocabulary', choices=[('1', '1 - OECD DAC'), ('2', '2 - UN')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='budgetitem', + name='currency', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='currency', choices=[('AED', 'AED - UAE Dirham'), ('AFN', 'AFN - Afghani'), ('ALL', 'ALL - Lek'), ('AMD', 'AMD - Armenian Dram'), ('ANG', 'ANG - Netherlands Antillian Guilder'), ('AOA', 'AOA - Kwanza'), ('ARS', 'ARS - Argentine Peso'), ('AUD', 'AUD - Australian Dollar'), ('AWG', 'AWG - Aruban Guilder'), ('AZN', 'AZN - Azerbaijanian Manat'), ('BAM', 'BAM - Convertible Marks'), ('BBD', 'BBD - Barbados Dollar'), ('BDT', 'BDT - Taka'), ('BGN', 'BGN - Bulgarian Lev'), ('BHD', 'BHD - Bahraini Dinar'), ('BIF', 'BIF - Burundi Franc'), ('BMD', 'BMD - Bermudian Dollar'), ('BND', 'BND - Brunei Dollar'), ('BOB', 'BOB - Boliviano'), ('BOV', 'BOV - Mvdol'), ('BRL', 'BRL - Brazilian Real'), ('BSD', 'BSD - Bahamian Dollar'), ('BTN', 'BTN - Ngultrum'), ('BWP', 'BWP - Pula'), ('BYR', 'BYR - Belarussian Ruble'), ('BZD', 'BZD - Belize Dollar'), ('CAD', 'CAD - Canadian Dollar'), ('CDF', 'CDF - Congolese Franc'), ('CHF', 'CHF - Swiss Franc'), ('CLF', 'CLF - Unidades de fomento'), ('CLP', 'CLP - Chilean Peso'), ('CNY', 'CNY - Yuan Renminbi'), ('COP', 'COP - Colombian Peso'), ('COU', 'COU - Unidad de Valor Real'), ('CRC', 'CRC - Costa Rican Colon'), ('CUC', 'CUC - Peso Convertible'), ('CUP', 'CUP - Cuban Peso'), ('CVE', 'CVE - Cape Verde Escudo'), ('CZK', 'CZK - Czech Koruna'), ('DJF', 'DJF - Djibouti Franc'), ('DKK', 'DKK - Danish Krone'), ('DOP', 'DOP - Dominican Peso'), ('DZD', 'DZD - Algerian Dinar'), ('EEK', 'EEK - Kroon'), ('EGP', 'EGP - Egyptian Pound'), ('ERN', 'ERN - Nakfa'), ('ETB', 'ETB - Ethiopian Birr'), ('EUR', 'EUR - Euro'), ('FJD', 'FJD - Fiji Dollar'), ('FKP', 'FKP - Falkland Islands Pound'), ('GBP', 'GBP - Pound Sterling'), ('GEL', 'GEL - Lari'), ('GHS', 'GHS - Cedi'), ('GIP', 'GIP - Gibraltar Pound'), ('GMD', 'GMD - Dalasi'), ('GNF', 'GNF - Guinea Franc'), ('GTQ', 'GTQ - Quetzal'), ('GYD', 'GYD - Guyana Dollar'), ('HKD', 'HKD - Hong Kong Dollar'), ('HNL', 'HNL - Lempira'), ('HRK', 'HRK - Croatian Kuna'), ('HTG', 'HTG - Gourde'), ('HUF', 'HUF - Forint'), ('IDR', 'IDR - Rupiah'), ('ILS', 'ILS - New Israeli Sheqel'), ('INR', 'INR - Indian Rupee'), ('IQD', 'IQD - Iraqi Dinar'), ('IRR', 'IRR - Iranian Rial'), ('ISK', 'ISK - Iceland Krona'), ('JMD', 'JMD - Jamaican Dollar'), ('JOD', 'JOD - Jordanian Dinar'), ('JPY', 'JPY - Yen'), ('KES', 'KES - Kenyan Shilling'), ('KGS', 'KGS - Som'), ('KHR', 'KHR - Riel'), ('KMF', 'KMF - Comoro Franc'), ('KPW', 'KPW - North Korean Won'), ('KRW', 'KRW - Won'), ('KWD', 'KWD - Kuwaiti Dinar'), ('KYD', 'KYD - Cayman Islands Dollar'), ('KZT', 'KZT - Tenge'), ('LAK', 'LAK - Kip'), ('LBP', 'LBP - Lebanese Pound'), ('LKR', 'LKR - Sri Lanka Rupee'), ('LRD', 'LRD - Liberian Dollar'), ('LSL', 'LSL - Loti'), ('LTL', 'LTL - Lithuanian Litas'), ('LVL', 'LVL - Latvian Lats'), ('LYD', 'LYD - Libyan Dinar'), ('MAD', 'MAD - Moroccan Dirham'), ('MDL', 'MDL - Moldovan Leu'), ('MGA', 'MGA - Malagasy Ariary'), ('MKD', 'MKD - Denar'), ('MMK', 'MMK - Kyat'), ('MNT', 'MNT - Tugrik'), ('MOP', 'MOP - Pataca'), ('MRO', 'MRO - Ouguiya'), ('MUR', 'MUR - Mauritius Rupee'), ('MVR', 'MVR - Rufiyaa'), ('MWK', 'MWK - Malawi Kwacha'), ('MXN', 'MXN - Mexican Peso'), ('MXV', 'MXV - Mexican Unidad de Inversion (UDI)'), ('MYR', 'MYR - Malaysian Ringgit'), ('MZN', 'MZN - Metical'), ('NAD', 'NAD - Namibia Dollar'), ('NGN', 'NGN - Naira'), ('NIO', 'NIO - Cordoba Oro'), ('NOK', 'NOK - Norwegian Krone'), ('NPR', 'NPR - Nepalese Rupee'), ('NZD', 'NZD - New Zealand Dollar'), ('OMR', 'OMR - Rial Omani'), ('PAB', 'PAB - Balboa'), ('PEN', 'PEN - Nuevo Sol'), ('PGK', 'PGK - Kina'), ('PHP', 'PHP - Philippine Peso'), ('PKR', 'PKR - Pakistan Rupee'), ('PLN', 'PLN - Zloty'), ('PYG', 'PYG - Guarani'), ('QAR', 'QAR - Qatari Rial'), ('RON', 'RON - New Leu'), ('RSD', 'RSD - Serbian Dinar'), ('RUB', 'RUB - Russian Ruble'), ('RWF', 'RWF - Rwanda Franc'), ('SAR', 'SAR - Saudi Riyal'), ('SBD', 'SBD - Solomon Islands Dollar'), ('SCR', 'SCR - Seychelles Rupee'), ('SDG', 'SDG - Sudanese Pound'), ('SEK', 'SEK - Swedish Krona'), ('SGD', 'SGD - Singapore Dollar'), ('SHP', 'SHP - Saint Helena Pound'), ('SLL', 'SLL - Leone'), ('SOS', 'SOS - Somali Shilling'), ('SSP', 'SSP - South Sudanese Pound'), ('SRD', 'SRD - Surinam Dollar'), ('STD', 'STD - Dobra'), ('SVC', 'SVC - El Salvador Colon'), ('SYP', 'SYP - Syrian Pound'), ('SZL', 'SZL - Lilangeni'), ('THB', 'THB - Baht'), ('TJS', 'TJS - Somoni'), ('TMT', 'TMT - Manat'), ('TND', 'TND - Tunisian Dinar'), ('TOP', 'TOP - Paanga'), ('TRY', 'TRY - Turkish Lira'), ('TTD', 'TTD - Trinidad and Tobago Dollar'), ('TWD', 'TWD - New Taiwan Dollar'), ('TZS', 'TZS - Tanzanian Shilling'), ('UAH', 'UAH - Hryvnia'), ('UGX', 'UGX - Uganda Shilling'), ('USD', 'USD - US Dollar'), ('USN', 'USN - US Dollar (Next day)'), ('USS', 'USS - US Dollar (Same day)'), ('UYI', 'UYI - Uruguay Peso en Unidades Indexadas'), ('UYU', 'UYU - Peso Uruguayo'), ('UZS', 'UZS - Uzbekistan Sum'), ('VEF', 'VEF - Bolivar'), ('VND', 'VND - Dong'), ('VUV', 'VUV - Vatu'), ('WST', 'WST - Tala'), ('XAF', 'XAF - CFA Franc BEAC'), ('XCD', 'XCD - East Caribbean Dollar'), ('XOF', 'XOF - CFA Franc BCEAO'), ('XPF', 'XPF - CFP Franc'), ('YER', 'YER - Yemeni Rial'), ('ZAR', 'ZAR - Rand'), ('ZMK', 'ZMK - Zambian Kwacha'), ('ZWL', 'ZWL - Zimbabwe Dollar')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='budgetitem', + name='type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select whether this is a planned or actual budget of the project.', max_length=1, verbose_name='budget type', choices=[('1', '1 - Original'), ('2', '2 - Revised')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='countrybudgetitem', + name='code', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=6, verbose_name='budget item', choices=[('1.1.1', '1.1.1 - Executive - executive'), ('1.2.1', '1.2.1 - Legislative - legislative'), ('1.3.1', '1.3.1 - Accountability - macroeconomic policy'), ('1.3.2', '1.3.2 - Accountability - budgeting'), ('1.3.3', '1.3.3 - Accountability - planning'), ('1.3.4', '1.3.4 - Accountability - Treasury/Accounts'), ('1.3.5', '1.3.5 - Accountability - debt and aid management'), ('1.3.6', '1.3.6 - Accountability - tax policy'), ('1.3.7', '1.3.7 - Accountability - tax collection'), ('1.3.8', '1.3.8 - Accountability - local government finance'), ('1.3.9', '1.3.9 - Accountability - other central transfers to institutions '), ('1.3.10', '1.3.10 - Accountability - national audit'), ('1.3.11', '1.3.11 - Accountability - national monitoring and evaluation'), ('1.3.12', '1.3.12 - Accountability - monetary institutions'), ('1.3.13', '1.3.13 - Accountability - financial sector policy and regulation'), ('1.4.1', '1.4.1 - External Affairs - foreign affairs '), ('1.4.2', '1.4.2 - External Affairs - diplomatic missions'), ('1.4.3', '1.4.3 - External Affairs - official development assistance'), ('1.5.1', '1.5.1 - General Personnel Services - general personnel services'), ('1.6.1', '1.6.1 - Statistics - statistics'), ('1.7.1', '1.7.1 - Other General Services - support to civil society '), ('1.7.2', '1.7.2 - Other General Services - central procurement'), ('1.7.3', '1.7.3 - Other General Services - Local Government Administration'), ('1.7.4', '1.7.4 - Other General Services - other general services'), ('1.8.1', '1.8.1 - Elections - elections'), ('2.1.1', '2.1.1 - Justice, Law and Order - policy, planning and administration'), ('2.1.2', '2.1.2 - Justice, Law and Order - police'), ('2.1.2', '2.1.2 - Justice, Law and Order - fire'), ('2.1.3', '2.1.3 - Justice, Law and Order - judicial affairs'), ('2.1.4', '2.1.4 - Justice, Law and Order - Ombudsman'), ('2.1.5', '2.1.5 - Justice, Law and Order - human rights affairs'), ('2.1.6', '2.1.6 - Justice, Law and Order - immigration'), ('2.1.7', '2.1.7 - Justice, Law and Order - anti corruption'), ('2.1.8', '2.1.8 - Justice, Law and Order - prisons'), ('2.1.9', '2.1.9 - Justice, Law and Order - peace building'), ('2.1.10', '2.1.10 - Justice, Law and Order - demobilisation'), ('2.2.1', '2.2.1 - Defence - policy, planning and administration'), ('2.2.2', '2.2.2 - Defence - military'), ('2.2.3', '2.2.3 - Defence - civil defence'), ('2.2.4', '2.2.4 - Defence - foreign military aid'), ('3.1.1', '3.1.1 - General Economic, Commercial and Labour Affairs - policy, planning and administration'), ('3.1.2', '3.1.2 - General Economic, Commercial and Labour Affairs - general economic affairs'), ('3.1.3', '3.1.3 - General Economic, Commercial and Labour Affairs - investment promotion'), ('3.1.4', '3.1.4 - General Economic, Commercial and Labour Affairs - privatisation'), ('3.1.5', '3.1.5 - General Economic, Commercial and Labour Affairs - trade'), ('3.1.6', '3.1.6 - General Economic, Commercial and Labour Affairs - labour'), ('3.1.7', '3.1.7 - General Economic, Commercial and Labour Affairs - national standards development'), ('3.2.1', '3.2.1 - Public Works - policy, planning and administration'), ('3.2.2', '3.2.2 - Public Works - construction regulation'), ('3.2.3', '3.2.3 - Public Works - mechanical services'), ('3.3.1', '3.3.1 - Agriculture - policy, planning and administration'), ('3.3.2', '3.3.2 - Agriculture - irrigation'), ('3.3.3', '3.3.3 - Agriculture - inputs'), ('3.3.4', '3.3.4 - Agriculture - food crop'), ('3.3.5', '3.3.5 - Agriculture - industrial crop'), ('3.3.6', '3.3.6 - Agriculture - livestock'), ('3.3.7', '3.3.7 - Agriculture - agricultural training and extension'), ('3.3.8', '3.3.8 - Agriculture - research'), ('3.3.9', '3.3.9 - Agriculture - other services'), ('3.4.1', '3.4.1 - Forestry - policy, planning and administration'), ('3.4.2', '3.4.2 - Forestry - development and services'), ('3.4.3', '3.4.3 - Forestry - education/training'), ('3.4.4', '3.4.4 - Forestry - research'), ('3.5.1', '3.5.1 - Fishing and Hunting - policy, planning and administration'), ('3.5.2', '3.5.2 - Fishing and Hunting - development and services'), ('3.5.3', '3.5.3 - Fishing and Hunting - education and training'), ('3.5.4', '3.5.4 - Fishing and Hunting - research'), ('3.6.1', '3.6.1 - Energy - policy, planning and administration'), ('3.6.2', '3.6.2 - Energy - education and training'), ('3.6.3', '3.6.3 - Energy - energy regulation'), ('3.6.4', '3.6.4 - Energy - electricity transmission'), ('3.6.5', '3.6.5 - Energy - nuclear'), ('3.6.6', '3.6.6 - Energy - power generation'), ('3.6.7', '3.6.7 - Energy - gas '), ('3.7.1', '3.7.1 - Mining and Mineral Development - policy, planning and administration'), ('3.7.2', '3.7.2 - Mining and Mineral Development - prospection and exploration'), ('3.7.3', '3.7.3 - Mining and Mineral Development - coal and other solid mineral fuels'), ('3.7.4', '3.7.4 - Mining and Mineral Development - petroleum and gas'), ('3.7.6', '3.7.6 - Mining and Mineral Development - other fuel'), ('3.7.7', '3.7.7 - Mining and Mineral Development - non fuel minerals'), ('3.8.1', '3.8.1 - Transport - policy, planning and administration'), ('3.8.2', '3.8.2 - Transport - transport regulation'), ('3.8.3', '3.8.3 - Transport - feeder road construction'), ('3.8.4', '3.8.4 - Transport - feeder road maintenance'), ('3.8.5', '3.8.5 - Transport - national road construction'), ('3.8.6', '3.8.6 - Transport - national road maintenance'), ('3.8.7', '3.8.7 - Transport - rail'), ('3.8.8', '3.8.8 - Transport - water'), ('3.8.9', '3.8.9 - Transport - air'), ('3.8.10', '3.8.10 - Transport - pipeline'), ('3.8.11', '3.8.11 - Transport - storage and distribution'), ('3.8.12', '3.8.12 - Transport - public transport services'), ('3.8.13', '3.8.13 - Transport - meteorological services'), ('3.8.14', '3.8.14 - Transport - education and training'), ('3.9.1', '3.9.1 - Industry - policy, planning and administration'), ('3.9.2', '3.9.2 - Industry - development and services'), ('3.9.3', '3.9.3 - Industry - industrial research'), ('3.9.4', '3.9.4 - Industry - (investment in industry)'), ('3.10.1', '3.10.1 - Communications - policy, planning and administration'), ('3.10.2', '3.10.2 - Communications - ICT Infrastructure'), ('3.10.3', '3.10.3 - Communications - telecoms and postal services'), ('3.10.4', '3.10.4 - Communications - information services'), ('3.11.1', '3.11.1 - Tourism - policy, planning and administration'), ('3.11.2', '3.11.2 - Tourism - services'), ('3.12.1', '3.12.1 - Microfinance and financial services - Microfinance and financial services'), ('4.1.1', '4.1.1 - Water supply and Sanitation - policy, planning and administration'), ('4.1.2', '4.1.2 - Water supply and Sanitation - education/training'), ('4.1.3', '4.1.3 - Water supply and Sanitation - rural water supply and sanitation'), ('4.1.4', '4.1.4 - Water supply and Sanitation - urban water supply and sanitation'), ('4.1.5', '4.1.5 - Water supply and Sanitation - rural water supply'), ('4.1.6', '4.1.6 - Water supply and Sanitation - urban water supply'), ('4.1.7', '4.1.7 - Water supply and Sanitation - rural sanitation'), ('4.1.8', '4.1.8 - Water supply and Sanitation - urban sanitation'), ('4.1.9', '4.1.9 - Water supply and Sanitation - sewage and waste management'), ('4.2.1', '4.2.1 - Environment - policy, planning and administration'), ('4.2.2', '4.2.2 - Environment - research/ education and training'), ('4.2.3', '4.2.3 - Environment - natural resource management'), ('4.2.4', '4.2.4 - Environment - water resources management'), ('4.2.5', '4.2.5 - Environment - wildlife protection, parks and site preservation'), ('5.1.1', '5.1.1 - Health - policy, planning and administration'), ('5.2.1', '5.2.1 - Recreation, Culture and Religion - recreation and sport'), ('5.2.2', '5.2.2 - Recreation, Culture and Religion - culture'), ('5.2.3', '5.2.3 - Recreation, Culture and Religion - broadcasting and publishing'), ('5.2.4', '5.2.4 - Recreation, Culture and Religion - religion'), ('5.3.1', '5.3.1 - Education - administration, policy and planning'), ('5.3.2', '5.3.2 - Education - research'), ('5.3.3', '5.3.3 - Education - pre-primary'), ('5.3.4', '5.3.4 - Education - primary'), ('5.3.5', '5.3.5 - Education - lower secondary'), ('5.3.6', '5.3.6 - Education - upper secondary'), ('5.3.7', '5.3.7 - Education - post secondary non tertiary '), ('5.3.8', '5.3.8 - Education - tertiary'), ('5.3.9', '5.3.9 - Education - vocational training'), ('5.3.10', '5.3.10 - Education - advanced technical and managerial training'), ('5.3.11', '5.3.11 - Education - basic adult education'), ('5.3.12', '5.3.12 - Education - teacher training'), ('5.3.13', '5.3.13 - Education - subsidiary services'), ('5.4.1', '5.4.1 - Social Protection, Land Housing and Community Amenities - policy, planning and administration'), ('5.4.2', '5.4.2 - Social Protection, Land Housing and Community Amenities - social security (excl pensions)'), ('5.4.3', '5.4.3 - Social Protection, Land Housing and Community Amenities - general pensions'), ('5.4.4', '5.4.4 - Social Protection, Land Housing and Community Amenities - civil service and military pensions'), ('5.4.5', '5.4.5 - Social Protection, Land Housing and Community Amenities - social services (incl youth development and women+ children)'), ('5.4.6', '5.4.6 - Social Protection, Land Housing and Community Amenities - land policy and management'), ('5.4.7', '5.4.7 - Social Protection, Land Housing and Community Amenities - rural devt'), ('5.4.8', '5.4.8 - Social Protection, Land Housing and Community Amenities - urban devt'), ('5.4.9', '5.4.9 - Social Protection, Land Housing and Community Amenities - housing and community amenities'), ('5.4.10', '5.4.10 - Social Protection, Land Housing and Community Amenities - emergency relief'), ('5.4.11', '5.4.11 - Social Protection, Land Housing and Community Amenities - disaster prevention and preparedness'), ('5.4.12', '5.4.12 - Social Protection, Land Housing and Community Amenities - support to refugees and internally displaced persons'), ('6.1.1', '6.1.1 - Development Partner affairs - policy planning and administration'), ('6.1.2', '6.1.2 - Development Partner affairs - Technical staff services'), ('7.1.1', '7.1.1 - External to government sector - External to general government sector'), ('7.2.1', '7.2.1 - General Budget Support - General Budget Support')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='indicator', + name='measure', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select whether the indicator counts units or evaluates a percentage.', max_length=1, verbose_name='measure', choices=[('1', '1 - Unit'), ('2', '2 - Percentage')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='planneddisbursement', + name='currency', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='currency', choices=[('AED', 'AED - UAE Dirham'), ('AFN', 'AFN - Afghani'), ('ALL', 'ALL - Lek'), ('AMD', 'AMD - Armenian Dram'), ('ANG', 'ANG - Netherlands Antillian Guilder'), ('AOA', 'AOA - Kwanza'), ('ARS', 'ARS - Argentine Peso'), ('AUD', 'AUD - Australian Dollar'), ('AWG', 'AWG - Aruban Guilder'), ('AZN', 'AZN - Azerbaijanian Manat'), ('BAM', 'BAM - Convertible Marks'), ('BBD', 'BBD - Barbados Dollar'), ('BDT', 'BDT - Taka'), ('BGN', 'BGN - Bulgarian Lev'), ('BHD', 'BHD - Bahraini Dinar'), ('BIF', 'BIF - Burundi Franc'), ('BMD', 'BMD - Bermudian Dollar'), ('BND', 'BND - Brunei Dollar'), ('BOB', 'BOB - Boliviano'), ('BOV', 'BOV - Mvdol'), ('BRL', 'BRL - Brazilian Real'), ('BSD', 'BSD - Bahamian Dollar'), ('BTN', 'BTN - Ngultrum'), ('BWP', 'BWP - Pula'), ('BYR', 'BYR - Belarussian Ruble'), ('BZD', 'BZD - Belize Dollar'), ('CAD', 'CAD - Canadian Dollar'), ('CDF', 'CDF - Congolese Franc'), ('CHF', 'CHF - Swiss Franc'), ('CLF', 'CLF - Unidades de fomento'), ('CLP', 'CLP - Chilean Peso'), ('CNY', 'CNY - Yuan Renminbi'), ('COP', 'COP - Colombian Peso'), ('COU', 'COU - Unidad de Valor Real'), ('CRC', 'CRC - Costa Rican Colon'), ('CUC', 'CUC - Peso Convertible'), ('CUP', 'CUP - Cuban Peso'), ('CVE', 'CVE - Cape Verde Escudo'), ('CZK', 'CZK - Czech Koruna'), ('DJF', 'DJF - Djibouti Franc'), ('DKK', 'DKK - Danish Krone'), ('DOP', 'DOP - Dominican Peso'), ('DZD', 'DZD - Algerian Dinar'), ('EEK', 'EEK - Kroon'), ('EGP', 'EGP - Egyptian Pound'), ('ERN', 'ERN - Nakfa'), ('ETB', 'ETB - Ethiopian Birr'), ('EUR', 'EUR - Euro'), ('FJD', 'FJD - Fiji Dollar'), ('FKP', 'FKP - Falkland Islands Pound'), ('GBP', 'GBP - Pound Sterling'), ('GEL', 'GEL - Lari'), ('GHS', 'GHS - Cedi'), ('GIP', 'GIP - Gibraltar Pound'), ('GMD', 'GMD - Dalasi'), ('GNF', 'GNF - Guinea Franc'), ('GTQ', 'GTQ - Quetzal'), ('GYD', 'GYD - Guyana Dollar'), ('HKD', 'HKD - Hong Kong Dollar'), ('HNL', 'HNL - Lempira'), ('HRK', 'HRK - Croatian Kuna'), ('HTG', 'HTG - Gourde'), ('HUF', 'HUF - Forint'), ('IDR', 'IDR - Rupiah'), ('ILS', 'ILS - New Israeli Sheqel'), ('INR', 'INR - Indian Rupee'), ('IQD', 'IQD - Iraqi Dinar'), ('IRR', 'IRR - Iranian Rial'), ('ISK', 'ISK - Iceland Krona'), ('JMD', 'JMD - Jamaican Dollar'), ('JOD', 'JOD - Jordanian Dinar'), ('JPY', 'JPY - Yen'), ('KES', 'KES - Kenyan Shilling'), ('KGS', 'KGS - Som'), ('KHR', 'KHR - Riel'), ('KMF', 'KMF - Comoro Franc'), ('KPW', 'KPW - North Korean Won'), ('KRW', 'KRW - Won'), ('KWD', 'KWD - Kuwaiti Dinar'), ('KYD', 'KYD - Cayman Islands Dollar'), ('KZT', 'KZT - Tenge'), ('LAK', 'LAK - Kip'), ('LBP', 'LBP - Lebanese Pound'), ('LKR', 'LKR - Sri Lanka Rupee'), ('LRD', 'LRD - Liberian Dollar'), ('LSL', 'LSL - Loti'), ('LTL', 'LTL - Lithuanian Litas'), ('LVL', 'LVL - Latvian Lats'), ('LYD', 'LYD - Libyan Dinar'), ('MAD', 'MAD - Moroccan Dirham'), ('MDL', 'MDL - Moldovan Leu'), ('MGA', 'MGA - Malagasy Ariary'), ('MKD', 'MKD - Denar'), ('MMK', 'MMK - Kyat'), ('MNT', 'MNT - Tugrik'), ('MOP', 'MOP - Pataca'), ('MRO', 'MRO - Ouguiya'), ('MUR', 'MUR - Mauritius Rupee'), ('MVR', 'MVR - Rufiyaa'), ('MWK', 'MWK - Malawi Kwacha'), ('MXN', 'MXN - Mexican Peso'), ('MXV', 'MXV - Mexican Unidad de Inversion (UDI)'), ('MYR', 'MYR - Malaysian Ringgit'), ('MZN', 'MZN - Metical'), ('NAD', 'NAD - Namibia Dollar'), ('NGN', 'NGN - Naira'), ('NIO', 'NIO - Cordoba Oro'), ('NOK', 'NOK - Norwegian Krone'), ('NPR', 'NPR - Nepalese Rupee'), ('NZD', 'NZD - New Zealand Dollar'), ('OMR', 'OMR - Rial Omani'), ('PAB', 'PAB - Balboa'), ('PEN', 'PEN - Nuevo Sol'), ('PGK', 'PGK - Kina'), ('PHP', 'PHP - Philippine Peso'), ('PKR', 'PKR - Pakistan Rupee'), ('PLN', 'PLN - Zloty'), ('PYG', 'PYG - Guarani'), ('QAR', 'QAR - Qatari Rial'), ('RON', 'RON - New Leu'), ('RSD', 'RSD - Serbian Dinar'), ('RUB', 'RUB - Russian Ruble'), ('RWF', 'RWF - Rwanda Franc'), ('SAR', 'SAR - Saudi Riyal'), ('SBD', 'SBD - Solomon Islands Dollar'), ('SCR', 'SCR - Seychelles Rupee'), ('SDG', 'SDG - Sudanese Pound'), ('SEK', 'SEK - Swedish Krona'), ('SGD', 'SGD - Singapore Dollar'), ('SHP', 'SHP - Saint Helena Pound'), ('SLL', 'SLL - Leone'), ('SOS', 'SOS - Somali Shilling'), ('SSP', 'SSP - South Sudanese Pound'), ('SRD', 'SRD - Surinam Dollar'), ('STD', 'STD - Dobra'), ('SVC', 'SVC - El Salvador Colon'), ('SYP', 'SYP - Syrian Pound'), ('SZL', 'SZL - Lilangeni'), ('THB', 'THB - Baht'), ('TJS', 'TJS - Somoni'), ('TMT', 'TMT - Manat'), ('TND', 'TND - Tunisian Dinar'), ('TOP', 'TOP - Paanga'), ('TRY', 'TRY - Turkish Lira'), ('TTD', 'TTD - Trinidad and Tobago Dollar'), ('TWD', 'TWD - New Taiwan Dollar'), ('TZS', 'TZS - Tanzanian Shilling'), ('UAH', 'UAH - Hryvnia'), ('UGX', 'UGX - Uganda Shilling'), ('USD', 'USD - US Dollar'), ('USN', 'USN - US Dollar (Next day)'), ('USS', 'USS - US Dollar (Same day)'), ('UYI', 'UYI - Uruguay Peso en Unidades Indexadas'), ('UYU', 'UYU - Peso Uruguayo'), ('UZS', 'UZS - Uzbekistan Sum'), ('VEF', 'VEF - Bolivar'), ('VND', 'VND - Dong'), ('VUV', 'VUV - Vatu'), ('WST', 'WST - Tala'), ('XAF', 'XAF - CFA Franc BEAC'), ('XCD', 'XCD - East Caribbean Dollar'), ('XOF', 'XOF - CFA Franc BCEAO'), ('XPF', 'XPF - CFP Franc'), ('YER', 'YER - Yemeni Rial'), ('ZAR', 'ZAR - Rand'), ('ZMK', 'ZMK - Zambian Kwacha'), ('ZWL', 'ZWL - Zimbabwe Dollar')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='planneddisbursement', + name='type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='type', choices=[('1', '1 - Original'), ('2', '2 - Revised')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='policymarker', + name='policy_marker', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='policy marker', choices=[('1', '1 - Gender Equality'), ('2', '2 - Aid to Environment'), ('3', '3 - Participatory Development/Good Governance'), ('4', '4 - Trade Development'), ('5', '5 - Aid Targeting the Objectives of the Convention on Biological Diversity'), ('6', '6 - Aid Targeting the Objectives of the Framework Convention on Climate Change - Mitigation'), ('7', '7 - Aid Targeting the Objectives of the Framework Convention on Climate Change - Adaptation'), ('8', '8 - Aid Targeting the Objectives of the Convention to Combat Desertification'), ('9', '9 - Reproductive, Maternal, Newborn and Child Health (RMNCH)')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='policymarker', + name='significance', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='significance', choices=[('0', '0 - not targeted'), ('1', '1 - significant objective'), ('2', '2 - principal objective'), ('3', '3 - principal objective AND in support of an action programme'), ('4', '4 - Explicit primary objective')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='policymarker', + name='vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=5, verbose_name='vocabulary', choices=[('1', '1 - OECD DAC CRS'), ('99', '99 - Reporting Organisation')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='project', + name='collaboration_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='collaboration type', choices=[('1', '1 - Bilateral'), ('2', '2 - Multilateral'), ('3', '3 - Bilateral, core contributions to NGOs and other private bodies / PPPs'), ('4', '4 - Multilateral outflows'), ('6', '6 - Private sector outflow'), ('7', '7 - Bilateral, ex-post reporting on NGOs activities funded through core contributions')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='project', + name='default_aid_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='default aid type', choices=[('A01', 'A01 - General budget support'), ('A02', 'A02 - Sector budget support'), ('B01', 'B01 - Core support to NGOs, other private bodies, PPPs and research institutes'), ('B02', 'B02 - Core contributions to multilateral institutions'), ('B03', 'B03 - Contributions to specific-purpose programmes and funds managed by international organisations (multilateral, INGO)'), ('B04', 'B04 - Basket funds/pooled funding'), ('C01', 'C01 - Project-type interventions'), ('D01', 'D01 - Donor country personnel'), ('D02', 'D02 - Other technical assistance'), ('E01', 'E01 - Scholarships/training in donor country'), ('E02', 'E02 - Imputed student costs'), ('F01', 'F01 - Debt relief'), ('G01', 'G01 - Administrative costs not included elsewhere'), ('H01', 'H01 - Development awareness'), ('H02', 'H02 - Refugees in donor countries')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='project', + name='default_finance_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='default finance type', choices=[('110', '110 - Aid grant excluding debt reorganisation'), ('111', '111 - Subsidies to national private investors'), ('210', '210 - Interest subsidy grant in AF'), ('211', '211 - Interest subsidy to national private exporters'), ('310', '310 - Deposit basis'), ('311', '311 - Encashment basis'), ('410', '410 - Aid loan excluding debt reorganisation'), ('411', '411 - Investment-related loan to developing countries'), ('412', '412 - Loan in a joint venture with the recipient'), ('413', '413 - Loan to national private investor'), ('414', '414 - Loan to national private exporter'), ('451', '451 - Non-banks guaranteed export credits'), ('452', '452 - Non-banks non-guaranteed portions of guaranteed export credits'), ('453', '453 - Bank export credits'), ('510', '510 - Acquisition of equity as part of a joint venture with the recipient'), ('511', '511 - Acquisition of equity not part of joint venture in developing countries'), ('512', '512 - Other acquisition of equity. Investment in a country on the DAC List of ODA Recipients that is not made to acquire a lasting interest in an enterprise.'), ('610', '610 - Debt forgiveness: ODA claims (P)'), ('611', '611 - Debt forgiveness: ODA claims (I)'), ('612', '612 - Debt forgiveness: OOF claims (P)'), ('613', '613 - Debt forgiveness: OOF claims (I)'), ('614', '614 - Debt forgiveness: Private claims (P)'), ('615', '615 - Debt forgiveness: Private claims (I)'), ('616', '616 - Debt forgiveness: OOF claims (DSR)'), ('617', '617 - Debt forgiveness: Private claims (DSR)'), ('618', '618 - Debt forgiveness: Other'), ('620', '620 - Debt rescheduling: ODA claims (P)'), ('621', '621 - Debt rescheduling: ODA claims (I)'), ('622', '622 - Debt rescheduling: OOF claims (P)'), ('623', '623 - Debt rescheduling: OOF claims (I)'), ('624', '624 - Debt rescheduling: Private claims (P)'), ('625', '625 - Debt rescheduling: Private claims (I)'), ('626', '626 - Debt rescheduling: OOF claims (DSR)'), ('627', '627 - Debt rescheduling: Private claims (DSR)'), ('630', '630 - Debt rescheduling: OOF claim (DSR - original loan principal)'), ('631', '631 - Debt rescheduling: OOF claim (DSR - original loan interest)'), ('632', '632 - Debt rescheduling: Private claim (DSR - original loan principal)'), ('710', '710 - Foreign direct investment'), ('711', '711 - Other foreign direct investment, including reinvested earnings'), ('810', '810 - Bank bonds'), ('811', '811 - Non-bank bonds'), ('910', '910 - Other bank securities/claims'), ('911', '911 - Other non-bank securities/claims'), ('912', '912 - Securities and other instruments issued by multilateral agencies')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='project', + name='default_flow_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='default flow type', choices=[('10', '10 - ODA'), ('20', '20 - OOF'), ('30', '30 - Private NGO and other private sources'), ('35', '35 - Private Market'), ('40', '40 - Non flow'), ('50', '50 - Other flows')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='project', + name='default_tied_status', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='default tied status', choices=[('3', '3 - Partially tied'), ('4', '4 - Tied'), ('5', '5 - Untied')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='project', + name='project_scope', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select the geographical scope of the project.', max_length=2, verbose_name='project scope', choices=[('1', '1 - Global'), ('2', '2 - Regional'), ('3', '3 - Multi-national'), ('4', '4 - National'), ('5', '5 - Sub-national: Multi-first-level administrative areas'), ('6', '6 - Sub-national: Single first-level administrative area'), ('7', '7 - Sub-national: Single second-level administrative area'), ('8', '8 - Single location')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectcondition', + name='type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='condition type', choices=[('1', '1 - Policy'), ('2', '2 - Performance'), ('3', '3 - Fiduciary')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectcontact', + name='type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='type', choices=[('1', '1 - General Enquiries'), ('2', '2 - Project Management'), ('3', '3 - Financial Management'), ('4', '4 - Communications')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectdocument', + name='category', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select a document category.', max_length=3, verbose_name='category', choices=[('A01', 'A01 - Pre- and post-project impact appraisal'), ('A02', 'A02 - Objectives / Purpose of activity'), ('A03', 'A03 - Intended ultimate beneficiaries'), ('A04', 'A04 - Conditions'), ('A05', 'A05 - Budget'), ('A06', 'A06 - Summary information about contract'), ('A07', 'A07 - Review of project performance and evaluation'), ('A08', 'A08 - Results, outcomes and outputs'), ('A09', 'A09 - Memorandum of understanding (If agreed by all parties)'), ('A10', 'A10 - Tender'), ('A11', 'A11 - Contract'), ('A12', 'A12 - Activity web page'), ('B01', 'B01 - Annual report'), ('B02', 'B02 - Institutional Strategy paper'), ('B03', 'B03 - Country strategy paper'), ('B04', 'B04 - Aid Allocation Policy'), ('B05', 'B05 - Procurement Policy and Procedure'), ('B06', 'B06 - Institutional Audit Report'), ('B07', 'B07 - Country Audit Report'), ('B08', 'B08 - Exclusions Policy'), ('B09', 'B09 - Institutional Evaluation Report'), ('B10', 'B10 - Country Evaluation Report'), ('B11', 'B11 - Sector strategy'), ('B12', 'B12 - Thematic strategy'), ('B13', 'B13 - Country-level Memorandum of Understanding'), ('B14', 'B14 - Evaluations policy'), ('B15', 'B15 - General Terms and Conditions'), ('B16', 'B16 - Organisation web page'), ('B17', 'B17 - Country/Region web page'), ('B18', 'B18 - Sector web page')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectdocument', + name='language', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select the language that the document is written in.', max_length=2, verbose_name='language', choices=[('aa', 'aa - Afar'), ('ab', 'ab - Abkhazian'), ('ae', 'ae - Avestan'), ('af', 'af - Afrikaans'), ('ak', 'ak - Akan'), ('am', 'am - Amharic'), ('an', 'an - Aragonese'), ('ar', 'ar - Arabic'), ('as', 'as - Assamese'), ('av', 'av - Avaric'), ('ay', 'ay - Aymara'), ('az', 'az - Azerbaijani'), ('ba', 'ba - Bashkir'), ('be', 'be - Belarusian'), ('bg', 'bg - Bulgarian'), ('bh', 'bh - Bihari languages'), ('bi', 'bi - Bislama'), ('bm', 'bm - Bambara'), ('bn', 'bn - Bengali'), ('bo', 'bo - Tibetan'), ('br', 'br - Breton'), ('bs', 'bs - Bosnian'), ('ca', 'ca - Catalan; Valencian'), ('ce', 'ce - Chechen'), ('ch', 'ch - Chamorro'), ('co', 'co - Corsican'), ('cr', 'cr - Cree'), ('cs', 'cs - Czech'), ('cv', 'cv - Chuvash'), ('cy', 'cy - Welsh'), ('da', 'da - Danish'), ('de', 'de - German'), ('dv', 'dv - Divehi; Dhivehi; Maldivian'), ('dz', 'dz - Dzongkha'), ('ee', 'ee - Ewe'), ('el', 'el - Greek'), ('en', 'en - English'), ('eo', 'eo - Esperanto'), ('es', 'es - Spanish; Castilian'), ('et', 'et - Estonian'), ('eu', 'eu - Basque'), ('fa', 'fa - Persian'), ('ff', 'ff - Fulah'), ('fi', 'fi - Finnish'), ('fj', 'fj - Fijian'), ('fo', 'fo - Faroese'), ('fr', 'fr - French'), ('fy', 'fy - Western Frisian'), ('ga', 'ga - Irish'), ('gd', 'gd - Gaelic; Scottish Gaelic'), ('gl', 'gl - Galician'), ('gn', 'gn - Guarani'), ('gu', 'gu - Gujarati'), ('gv', 'gv - Manx'), ('ha', 'ha - Hausa'), ('he', 'he - Hebrew'), ('hi', 'hi - Hindi'), ('ho', 'ho - Hiri Motu'), ('hr', 'hr - Croatian'), ('ht', 'ht - Haitian; Haitian Creole'), ('hu', 'hu - Hungarian'), ('hy', 'hy - Armenian'), ('hz', 'hz - Herero'), ('id', 'id - Indonesian'), ('ig', 'ig - Igbo'), ('ii', 'ii - Sichuan Yi; Nuosu'), ('ik', 'ik - Inupiaq'), ('io', 'io - Ido'), ('is', 'is - Icelandic'), ('it', 'it - Italian'), ('iu', 'iu - Inuktitut'), ('ja', 'ja - Japanese'), ('jv', 'jv - Javanese'), ('ka', 'ka - Georgian'), ('kg', 'kg - Kongo'), ('ki', 'ki - Kikuyu; Gikuyu'), ('kj', 'kj - Kuanyama; Kwanyama'), ('kk', 'kk - Kazakh'), ('kl', 'kl - Kalaallisut; Greenlandic'), ('km', 'km - Central Khmer'), ('kn', 'kn - Kannada'), ('ko', 'ko - Korean'), ('kr', 'kr - Kanuri'), ('ks', 'ks - Kashmiri'), ('ku', 'ku - Kurdish'), ('kv', 'kv - Komi'), ('kw', 'kw - Cornish'), ('ky', 'ky - Kirghiz; Kyrgyz'), ('la', 'la - Latin'), ('lb', 'lb - Luxembourgish; Letzeburgesch'), ('lg', 'lg - Ganda'), ('li', 'li - Limburgan; Limburger; Limburgish'), ('ln', 'ln - Lingala'), ('lo', 'lo - Lao'), ('lt', 'lt - Lithuanian'), ('lu', 'lu - Luba-Katanga'), ('lv', 'lv - Latvian'), ('mg', 'mg - Malagasy'), ('mh', 'mh - Marshallese'), ('mi', 'mi - Maori'), ('mk', 'mk - Macedonian'), ('ml', 'ml - Malayalam'), ('mn', 'mn - Mongolian'), ('mr', 'mr - Marathi'), ('ms', 'ms - Malay'), ('mt', 'mt - Maltese'), ('my', 'my - Burmese'), ('na', 'na - Nauru'), ('nb', 'nb - Bokm\u0102\u013dl, Norwegian; Norwegian Bokm\u0102\u013dl'), ('nd', 'nd - Ndebele, North; North Ndebele'), ('ne', 'ne - Nepali'), ('ng', 'ng - Ndonga'), ('nl', 'nl - Dutch; Flemish'), ('nn', 'nn - Norwegian Nynorsk; Nynorsk, Norwegian'), ('no', 'no - Norwegian'), ('nr', 'nr - Ndebele, South; South Ndebele'), ('nv', 'nv - Navajo; Navaho'), ('ny', 'ny - Chichewa; Chewa; Nyanja'), ('oc', 'oc - Occitan (post 1500)'), ('oj', 'oj - Ojibwa'), ('om', 'om - Oromo'), ('or', 'or - Oriya'), ('os', 'os - Ossetian; Ossetic'), ('pa', 'pa - Panjabi; Punjabi'), ('pi', 'pi - Pali'), ('pl', 'pl - Polish'), ('ps', 'ps - Pushto; Pashto'), ('pt', 'pt - Portuguese'), ('qu', 'qu - Quechua'), ('rm', 'rm - Romansh'), ('rn', 'rn - Rundi'), ('ro', 'ro - Romanian; Moldavian; Moldovan'), ('ru', 'ru - Russian'), ('rw', 'rw - Kinyarwanda'), ('sa', 'sa - Sanskrit'), ('sc', 'sc - Sardinian'), ('sd', 'sd - Sindhi'), ('se', 'se - Northern Sami'), ('sg', 'sg - Sango'), ('si', 'si - Sinhala; Sinhalese'), ('sk', 'sk - Slovak'), ('sl', 'sl - Slovenian'), ('sm', 'sm - Samoan'), ('sn', 'sn - Shona'), ('so', 'so - Somali'), ('sq', 'sq - Albanian'), ('sr', 'sr - Serbian'), ('ss', 'ss - Swati'), ('st', 'st - Sotho, Southern'), ('su', 'su - Sundanese'), ('sv', 'sv - Swedish'), ('sw', 'sw - Swahili'), ('ta', 'ta - Tamil'), ('te', 'te - Telugu'), ('tg', 'tg - Tajik'), ('th', 'th - Thai'), ('ti', 'ti - Tigrinya'), ('tk', 'tk - Turkmen'), ('tl', 'tl - Tagalog'), ('tn', 'tn - Tswana'), ('to', 'to - Tonga (Tonga Islands)'), ('tr', 'tr - Turkish'), ('ts', 'ts - Tsonga'), ('tt', 'tt - Tatar'), ('tw', 'tw - Twi'), ('ty', 'ty - Tahitian'), ('ug', 'ug - Uighur; Uyghur'), ('uk', 'uk - Ukrainian'), ('ur', 'ur - Urdu'), ('uz', 'uz - Uzbek'), ('ve', 've - Venda'), ('vi', 'vi - Vietnamese'), ('vo', 'vo - Volap\u0102\u017ak'), ('wa', 'wa - Walloon'), ('wo', 'wo - Wolof'), ('xh', 'xh - Xhosa'), ('yi', 'yi - Yiddish'), ('yo', 'yo - Yoruba'), ('za', 'za - Zhuang; Chuang'), ('zh', 'zh - Chinese'), ('zu', 'zu - Zulu')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectdocument', + name='title_language', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select the language of the document title.', max_length=2, verbose_name='title language', choices=[('aa', 'aa - Afar'), ('ab', 'ab - Abkhazian'), ('ae', 'ae - Avestan'), ('af', 'af - Afrikaans'), ('ak', 'ak - Akan'), ('am', 'am - Amharic'), ('an', 'an - Aragonese'), ('ar', 'ar - Arabic'), ('as', 'as - Assamese'), ('av', 'av - Avaric'), ('ay', 'ay - Aymara'), ('az', 'az - Azerbaijani'), ('ba', 'ba - Bashkir'), ('be', 'be - Belarusian'), ('bg', 'bg - Bulgarian'), ('bh', 'bh - Bihari languages'), ('bi', 'bi - Bislama'), ('bm', 'bm - Bambara'), ('bn', 'bn - Bengali'), ('bo', 'bo - Tibetan'), ('br', 'br - Breton'), ('bs', 'bs - Bosnian'), ('ca', 'ca - Catalan; Valencian'), ('ce', 'ce - Chechen'), ('ch', 'ch - Chamorro'), ('co', 'co - Corsican'), ('cr', 'cr - Cree'), ('cs', 'cs - Czech'), ('cv', 'cv - Chuvash'), ('cy', 'cy - Welsh'), ('da', 'da - Danish'), ('de', 'de - German'), ('dv', 'dv - Divehi; Dhivehi; Maldivian'), ('dz', 'dz - Dzongkha'), ('ee', 'ee - Ewe'), ('el', 'el - Greek'), ('en', 'en - English'), ('eo', 'eo - Esperanto'), ('es', 'es - Spanish; Castilian'), ('et', 'et - Estonian'), ('eu', 'eu - Basque'), ('fa', 'fa - Persian'), ('ff', 'ff - Fulah'), ('fi', 'fi - Finnish'), ('fj', 'fj - Fijian'), ('fo', 'fo - Faroese'), ('fr', 'fr - French'), ('fy', 'fy - Western Frisian'), ('ga', 'ga - Irish'), ('gd', 'gd - Gaelic; Scottish Gaelic'), ('gl', 'gl - Galician'), ('gn', 'gn - Guarani'), ('gu', 'gu - Gujarati'), ('gv', 'gv - Manx'), ('ha', 'ha - Hausa'), ('he', 'he - Hebrew'), ('hi', 'hi - Hindi'), ('ho', 'ho - Hiri Motu'), ('hr', 'hr - Croatian'), ('ht', 'ht - Haitian; Haitian Creole'), ('hu', 'hu - Hungarian'), ('hy', 'hy - Armenian'), ('hz', 'hz - Herero'), ('id', 'id - Indonesian'), ('ig', 'ig - Igbo'), ('ii', 'ii - Sichuan Yi; Nuosu'), ('ik', 'ik - Inupiaq'), ('io', 'io - Ido'), ('is', 'is - Icelandic'), ('it', 'it - Italian'), ('iu', 'iu - Inuktitut'), ('ja', 'ja - Japanese'), ('jv', 'jv - Javanese'), ('ka', 'ka - Georgian'), ('kg', 'kg - Kongo'), ('ki', 'ki - Kikuyu; Gikuyu'), ('kj', 'kj - Kuanyama; Kwanyama'), ('kk', 'kk - Kazakh'), ('kl', 'kl - Kalaallisut; Greenlandic'), ('km', 'km - Central Khmer'), ('kn', 'kn - Kannada'), ('ko', 'ko - Korean'), ('kr', 'kr - Kanuri'), ('ks', 'ks - Kashmiri'), ('ku', 'ku - Kurdish'), ('kv', 'kv - Komi'), ('kw', 'kw - Cornish'), ('ky', 'ky - Kirghiz; Kyrgyz'), ('la', 'la - Latin'), ('lb', 'lb - Luxembourgish; Letzeburgesch'), ('lg', 'lg - Ganda'), ('li', 'li - Limburgan; Limburger; Limburgish'), ('ln', 'ln - Lingala'), ('lo', 'lo - Lao'), ('lt', 'lt - Lithuanian'), ('lu', 'lu - Luba-Katanga'), ('lv', 'lv - Latvian'), ('mg', 'mg - Malagasy'), ('mh', 'mh - Marshallese'), ('mi', 'mi - Maori'), ('mk', 'mk - Macedonian'), ('ml', 'ml - Malayalam'), ('mn', 'mn - Mongolian'), ('mr', 'mr - Marathi'), ('ms', 'ms - Malay'), ('mt', 'mt - Maltese'), ('my', 'my - Burmese'), ('na', 'na - Nauru'), ('nb', 'nb - Bokm\u0102\u013dl, Norwegian; Norwegian Bokm\u0102\u013dl'), ('nd', 'nd - Ndebele, North; North Ndebele'), ('ne', 'ne - Nepali'), ('ng', 'ng - Ndonga'), ('nl', 'nl - Dutch; Flemish'), ('nn', 'nn - Norwegian Nynorsk; Nynorsk, Norwegian'), ('no', 'no - Norwegian'), ('nr', 'nr - Ndebele, South; South Ndebele'), ('nv', 'nv - Navajo; Navaho'), ('ny', 'ny - Chichewa; Chewa; Nyanja'), ('oc', 'oc - Occitan (post 1500)'), ('oj', 'oj - Ojibwa'), ('om', 'om - Oromo'), ('or', 'or - Oriya'), ('os', 'os - Ossetian; Ossetic'), ('pa', 'pa - Panjabi; Punjabi'), ('pi', 'pi - Pali'), ('pl', 'pl - Polish'), ('ps', 'ps - Pushto; Pashto'), ('pt', 'pt - Portuguese'), ('qu', 'qu - Quechua'), ('rm', 'rm - Romansh'), ('rn', 'rn - Rundi'), ('ro', 'ro - Romanian; Moldavian; Moldovan'), ('ru', 'ru - Russian'), ('rw', 'rw - Kinyarwanda'), ('sa', 'sa - Sanskrit'), ('sc', 'sc - Sardinian'), ('sd', 'sd - Sindhi'), ('se', 'se - Northern Sami'), ('sg', 'sg - Sango'), ('si', 'si - Sinhala; Sinhalese'), ('sk', 'sk - Slovak'), ('sl', 'sl - Slovenian'), ('sm', 'sm - Samoan'), ('sn', 'sn - Shona'), ('so', 'so - Somali'), ('sq', 'sq - Albanian'), ('sr', 'sr - Serbian'), ('ss', 'ss - Swati'), ('st', 'st - Sotho, Southern'), ('su', 'su - Sundanese'), ('sv', 'sv - Swedish'), ('sw', 'sw - Swahili'), ('ta', 'ta - Tamil'), ('te', 'te - Telugu'), ('tg', 'tg - Tajik'), ('th', 'th - Thai'), ('ti', 'ti - Tigrinya'), ('tk', 'tk - Turkmen'), ('tl', 'tl - Tagalog'), ('tn', 'tn - Tswana'), ('to', 'to - Tonga (Tonga Islands)'), ('tr', 'tr - Turkish'), ('ts', 'ts - Tsonga'), ('tt', 'tt - Tatar'), ('tw', 'tw - Twi'), ('ty', 'ty - Tahitian'), ('ug', 'ug - Uighur; Uyghur'), ('uk', 'uk - Ukrainian'), ('ur', 'ur - Urdu'), ('uz', 'uz - Uzbek'), ('ve', 've - Venda'), ('vi', 'vi - Vietnamese'), ('vo', 'vo - Volap\u0102\u017ak'), ('wa', 'wa - Walloon'), ('wo', 'wo - Wolof'), ('xh', 'xh - Xhosa'), ('yi', 'yi - Yiddish'), ('yo', 'yo - Yoruba'), ('za', 'za - Zhuang; Chuang'), ('zh', 'zh - Chinese'), ('zu', 'zu - Zulu')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectlocation', + name='exactness', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='exactness', choices=[('1', '1 - Exact'), ('2', '2 - Approximate')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectlocation', + name='feature_designation', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=5, verbose_name='feature designation', choices=[('AIRQ', 'AIRQ - abandoned airfield'), ('CMPQ', 'CMPQ - abandoned camp'), ('CNLQ', 'CNLQ - abandoned canal'), ('MFGQ', 'MFGQ - abandoned factory'), ('FRMQ', 'FRMQ - abandoned farm'), ('MNQ', 'MNQ - abandoned mine'), ('MSSNQ', 'MSSNQ - abandoned mission'), ('OILQ', 'OILQ - abandoned oil well'), ('PPQ', 'PPQ - abandoned police post'), ('PPLQ', 'PPLQ - abandoned populated place'), ('PRNQ', 'PRNQ - abandoned prison'), ('RRQ', 'RRQ - abandoned railroad'), ('RSTNQ', 'RSTNQ - abandoned railroad station'), ('RSTPQ', 'RSTPQ - abandoned railroad stop'), ('STMQ', 'STMQ - abandoned watercourse'), ('WLLQ', 'WLLQ - abandoned well'), ('ADMD', 'ADMD - administrative division'), ('ADMF', 'ADMF - administrative facility'), ('AGRC', 'AGRC - agricultural colony'), ('AGRF', 'AGRF - agricultural facility'), ('RESA', 'RESA - agricultural reserve'), ('SCHA', 'SCHA - agricultural school'), ('AIRB', 'AIRB - airbase'), ('AIRF', 'AIRF - airfield'), ('AIRP', 'AIRP - airport'), ('AMTH', 'AMTH - amphitheater'), ('STMA', 'STMA - anabranch'), ('ANCH', 'ANCH - anchorage'), ('RDA', 'RDA - ancient road'), ('ANS', 'ANS - ancient site'), ('WALLA', 'WALLA - ancient wall'), ('BLDA', 'BLDA - apartment building'), ('AQC', 'AQC - aquaculture facility'), ('CNLA', 'CNLA - aqueduct'), ('ARCH', 'ARCH - arch'), ('LAND', 'LAND - Arctic land'), ('AREA', 'AREA - area'), ('ISLF', 'ISLF - artificial island'), ('RNGA', 'RNGA - artillery range'), ('ASPH', 'ASPH - asphalt lake'), ('ASTR', 'ASTR - astronomical station'), ('ASYL', 'ASYL - asylum'), ('ATHF', 'ATHF - athletic field'), ('ATOL', 'ATOL - atoll(s)'), ('CTRA', 'CTRA - atomic center'), ('BDLD', 'BDLD - badlands'), ('BSTN', 'BSTN - baling station'), ('ESTB', 'ESTB - banana plantation'), ('BAN', 'BAN - bank'), ('BNK', 'BNK - bank(s)'), ('BAR', 'BAR - bar'), ('BRKS', 'BRKS - barracks'), ('BTL', 'BTL - battlefield'), ('BAY', 'BAY - bay'), ('BAYS', 'BAYS - bays'), ('BCH', 'BCH - beach'), ('RDGB', 'RDGB - beach ridge'), ('BCHS', 'BCHS - beaches'), ('BCN', 'BCN - beacon'), ('BNCH', 'BNCH - bench'), ('BGHT', 'BGHT - bight(s)'), ('BLHL', 'BLHL - blowhole(s)'), ('BLOW', 'BLOW - blowout(s)'), ('BTYD', 'BTYD - boatyard'), ('BOG', 'BOG - bog(s)'), ('PSTB', 'PSTB - border post'), ('BLDR', 'BLDR - boulder field'), ('BP', 'BP - boundary marker'), ('BRKW', 'BRKW - breakwater'), ('MFGB', 'MFGB - brewery'), ('BDG', 'BDG - bridge'), ('ZNB', 'ZNB - buffer zone'), ('BLDG', 'BLDG - building(s)'), ('BUR', 'BUR - burial cave(s)'), ('BUSH', 'BUSH - bush(es)'), ('CTRB', 'CTRB - business center'), ('BUTE', 'BUTE - butte(s)'), ('CARN', 'CARN - cairn'), ('CLDA', 'CLDA - caldera'), ('CMP', 'CMP - camp(s)'), ('CNL', 'CNL - canal'), ('CNLB', 'CNLB - canal bend'), ('TNLC', 'TNLC - canal tunnel'), ('STMC', 'STMC - canalized stream'), ('MFGC', 'MFGC - cannery'), ('CNYN', 'CNYN - canyon'), ('CAPE', 'CAPE - cape'), ('PPLC', 'PPLC - capital of a political entity'), ('RTE', 'RTE - caravan route'), ('CSNO', 'CSNO - casino'), ('CSTL', 'CSTL - castle'), ('TNKD', 'TNKD - cattle dipping tank'), ('CSWY', 'CSWY - causeway'), ('CAVE', 'CAVE - cave(s)'), ('CMTY', 'CMTY - cemetery'), ('CHN', 'CHN - channel'), ('MNCR', 'MNCR - chrome mine(s)'), ('CH', 'CH - church'), ('CRQ', 'CRQ - cirque'), ('CRQS', 'CRQS - cirques'), ('CLG', 'CLG - clearing'), ('CFT', 'CFT - cleft(s)'), ('CLF', 'CLF - cliff(s)'), ('HSPC', 'HSPC - clinic'), ('MNC', 'MNC - coal mine(s)'), ('COLF', 'COLF - coalfield'), ('CST', 'CST - coast'), ('STNC', 'STNC - coast guard station'), ('GRVC', 'GRVC - coconut grove'), ('SCHC', 'SCHC - college'), ('CMN', 'CMN - common'), ('COMC', 'COMC - communication center'), ('CTRCM', 'CTRCM - community center'), ('CNS', 'CNS - concession area'), ('CONE', 'CONE - cone(s)'), ('CNFL', 'CNFL - confluence'), ('CRSU', 'CRSU - continental rise'), ('CVNT', 'CVNT - convent'), ('MNCU', 'MNCU - copper mine(s)'), ('MFGCU', 'MFGCU - copper works'), ('RFC', 'RFC - coral reef(s)'), ('CRRL', 'CRRL - corral(s)'), ('CRDR', 'CRDR - corridor'), ('ESTC', 'ESTC - cotton plantation'), ('HSEC', 'HSEC - country house'), ('CTHSE', 'CTHSE - courthouse'), ('COVE', 'COVE - cove(s)'), ('LKC', 'LKC - crater lake'), ('LKSC', 'LKSC - crater lakes'), ('CRTR', 'CRTR - crater(s)'), ('CUET', 'CUET - cuesta(s)'), ('CULT', 'CULT - cultivated area'), ('CRNT', 'CRNT - current'), ('CSTM', 'CSTM - customs house'), ('PSTC', 'PSTC - customs post'), ('CUTF', 'CUTF - cutoff'), ('DARY', 'DARY - dairy'), ('DAM', 'DAM - dam'), ('DEPU', 'DEPU - deep'), ('DLTA', 'DLTA - delta'), ('PCLD', 'PCLD - dependent political entity'), ('DPR', 'DPR - depression(s)'), ('DSRT', 'DSRT - desert'), ('PPLW', 'PPLW - destroyed populated place'), ('MNDT', 'MNDT - diatomite mine(s)'), ('DIKE', 'DIKE - dike'), ('DIP', 'DIP - diplomatic facility'), ('HSPD', 'HSPD - dispensary'), ('STMD', 'STMD - distributary(-ies)'), ('DTCH', 'DTCH - ditch'), ('DTCHM', 'DTCHM - ditch mouth(s)'), ('DVD', 'DVD - divide'), ('DCK', 'DCK - dock(s)'), ('DCKB', 'DCKB - docking basin'), ('DCKY', 'DCKY - dockyard'), ('BSND', 'BSND - drainage basin'), ('CNLD', 'CNLD - drainage canal'), ('DTCHD', 'DTCHD - drainage ditch'), ('DCKD', 'DCKD - dry dock'), ('SBED', 'SBED - dry stream bed'), ('DUNE', 'DUNE - dune(s)'), ('RGNE', 'RGNE - economic region'), ('SCRP', 'SCRP - escarpment'), ('EST', 'EST - estate(s)'), ('ESTY', 'ESTY - estuary'), ('STNE', 'STNE - experiment station'), ('FCL', 'FCL - facility'), ('CTRF', 'CTRF - facility center'), ('MFG', 'MFG - factory'), ('FAN', 'FAN - fan(s)'), ('FRM', 'FRM - farm'), ('PPLF', 'PPLF - farm village'), ('FRMS', 'FRMS - farms'), ('FRMT', 'FRMT - farmstead'), ('FY', 'FY - ferry'), ('FYT', 'FYT - ferry terminal'), ('FLD', 'FLD - field(s)'), ('FIRE', 'FIRE - fire station'), ('ADM1', 'ADM1 - first-order administrative division'), ('FISH', 'FISH - fishing area'), ('PNDSF', 'PNDSF - fishponds'), ('FSR', 'FSR - fissure'), ('FJD', 'FJD - fjord'), ('FJDS', 'FJDS - fjords'), ('FORD', 'FORD - ford'), ('RESF', 'RESF - forest reserve'), ('STNF', 'STNF - forest station'), ('FRST', 'FRST - forest(s)'), ('INLTQ', 'INLTQ - former inlet'), ('MLSGQ', 'MLSGQ - former sugar mill'), ('FT', 'FT - fort'), ('FRSTF', 'FRSTF - fossilized forest'), ('FNDY', 'FNDY - foundry'), ('ADM4', 'ADM4 - fourth-order administrative division'), ('ZNF', 'ZNF - free trade zone'), ('PCLF', 'PCLF - freely associated state'), ('DPOF', 'DPOF - fuel depot'), ('GAP', 'GAP - gap'), ('GDN', 'GDN - garden(s)'), ('GOSP', 'GOSP - gas-oil separator plant'), ('GASF', 'GASF - gasfield'), ('GATE', 'GATE - gate'), ('GYSR', 'GYSR - geyser'), ('GHAT', 'GHAT - gh\xc4\x81t'), ('GLCR', 'GLCR - glacier(s)'), ('MNAU', 'MNAU - gold mine(s)'), ('RECG', 'RECG - golf course'), ('GRGE', 'GRGE - gorge(s)'), ('GRSLD', 'GRSLD - grassland'), ('GRVE', 'GRVE - grave'), ('GVL', 'GVL - gravel area'), ('GRAZ', 'GRAZ - grazing area'), ('GHSE', 'GHSE - guest house'), ('GULF', 'GULF - gulf'), ('HLT', 'HLT - halting place'), ('HMCK', 'HMCK - hammock(s)'), ('AIRG', 'AIRG - hangar'), ('VALG', 'VALG - hanging valley'), ('HBR', 'HBR - harbor(s)'), ('HDLD', 'HDLD - headland'), ('STMH', 'STMH - headwaters'), ('HTH', 'HTH - heath'), ('AIRH', 'AIRH - heliport'), ('HERM', 'HERM - hermitage'), ('HLL', 'HLL - hill'), ('HLLS', 'HLLS - hills'), ('ADMDH', 'ADMDH - historical administrative division'), ('ADM1H', 'ADM1H - historical first-order administrative division'), ('ADM4H', 'ADM4H - historical fourth-order administrative division'), ('PCLH', 'PCLH - historical political entity'), ('PPLH', 'PPLH - historical populated place'), ('RRH', 'RRH - historical railroad'), ('RSTNH', 'RSTNH - historical railroad station'), ('RGNH', 'RGNH - historical region'), ('ADM2H', 'ADM2H - historical second-order administrative division'), ('HSTS', 'HSTS - historical site'), ('ADM3H', 'ADM3H - historical third-order administrative division'), ('UFHU', 'UFHU - historical undersea feature'), ('HMSD', 'HMSD - homestead'), ('HSP', 'HSP - hospital'), ('SPNT', 'SPNT - hot spring(s)'), ('HTL', 'HTL - hotel'), ('HSE', 'HSE - house(s)'), ('DEVH', 'DEVH - housing development'), ('RESH', 'RESH - hunting reserve'), ('HUT', 'HUT - hut'), ('HUTS', 'HUTS - huts'), ('PSH', 'PSH - hydroelectric power station'), ('CAPG', 'CAPG - icecap'), ('DPRG', 'DPRG - icecap depression'), ('DOMG', 'DOMG - icecap dome'), ('RDGG', 'RDGG - icecap ridge'), ('PCLI', 'PCLI - independent political entity'), ('INDS', 'INDS - industrial area'), ('INLT', 'INLT - inlet'), ('STNI', 'STNI - inspection station'), ('TRGD', 'TRGD - interdune trough(s)'), ('INTF', 'INTF - interfluve'), ('LKI', 'LKI - intermittent lake'), ('LKSI', 'LKSI - intermittent lakes'), ('LKOI', 'LKOI - intermittent oxbow lake'), ('PNDI', 'PNDI - intermittent pond'), ('PNDSI', 'PNDSI - intermittent ponds'), ('POOLI', 'POOLI - intermittent pool'), ('RSVI', 'RSVI - intermittent reservoir'), ('LKNI', 'LKNI - intermittent salt lake'), ('LKSNI', 'LKSNI - intermittent salt lakes'), ('PNDNI', 'PNDNI - intermittent salt pond(s)'), ('STMI', 'STMI - intermittent stream'), ('WTLDI', 'WTLDI - intermittent wetland'), ('RDIN', 'RDIN - intersection'), ('MNFE', 'MNFE - iron mine(s)'), ('FLDI', 'FLDI - irrigated field(s)'), ('CNLI', 'CNLI - irrigation canal'), ('DTCHI', 'DTCHI - irrigation ditch'), ('SYSI', 'SYSI - irrigation system'), ('ISL', 'ISL - island'), ('ISLS', 'ISLS - islands'), ('STLMT', 'STLMT - Israeli settlement'), ('ISTH', 'ISTH - isthmus'), ('JTY', 'JTY - jetty'), ('KRST', 'KRST - karst area'), ('CMPLA', 'CMPLA - labor camp'), ('LGN', 'LGN - lagoon'), ('LGNS', 'LGNS - lagoons'), ('LK', 'LK - lake'), ('LBED', 'LBED - lake bed(s)'), ('CHNL', 'CHNL - lake channel(s)'), ('RGNL', 'RGNL - lake region'), ('LKS', 'LKS - lakes'), ('ISLT', 'ISLT - land-tied island'), ('LNDF', 'LNDF - landfill'), ('LDNG', 'LDNG - landing'), ('LAVA', 'LAVA - lava area'), ('MNPB', 'MNPB - lead mine(s)'), ('LTER', 'LTER - leased area'), ('LEPC', 'LEPC - leper colony'), ('HSPL', 'HSPL - leprosarium'), ('LEV', 'LEV - levee'), ('LTHSE', 'LTHSE - lighthouse'), ('MFGLM', 'MFGLM - limekiln'), ('GOVL', 'GOVL - local government office'), ('LCTY', 'LCTY - locality'), ('LOCK', 'LOCK - lock(s)'), ('CMPL', 'CMPL - logging camp'), ('STMSB', 'STMSB - lost river'), ('MVA', 'MVA - maneuver area'), ('ISLM', 'ISLM - mangrove island'), ('MGV', 'MGV - mangrove swamp'), ('MAR', 'MAR - marina'), ('CHNM', 'CHNM - marine channel'), ('SCHN', 'SCHN - maritime school'), ('MKT', 'MKT - market'), ('MRSH', 'MRSH - marsh(es)'), ('MDW', 'MDW - meadow'), ('NKM', 'NKM - meander neck'), ('CTRM', 'CTRM - medical center'), ('MESA', 'MESA - mesa(s)'), ('STNM', 'STNM - meteorological station'), ('MILB', 'MILB - military base'), ('INSM', 'INSM - military installation'), ('SCHM', 'SCHM - military school'), ('ML', 'ML - mill(s)'), ('MN', 'MN - mine(s)'), ('MNA', 'MNA - mining area'), ('CMPMN', 'CMPMN - mining camp'), ('MSSN', 'MSSN - mission'), ('MOLE', 'MOLE - mole'), ('MSTY', 'MSTY - monastery'), ('MNMT', 'MNMT - monument'), ('MOOR', 'MOOR - moor(s)'), ('MRN', 'MRN - moraine'), ('MSQE', 'MSQE - mosque'), ('MND', 'MND - mound(s)'), ('MT', 'MT - mountain'), ('MTS', 'MTS - mountains'), ('FLTM', 'FLTM - mud flat(s)'), ('MFGM', 'MFGM - munitions plant'), ('MUS', 'MUS - museum'), ('NRWS', 'NRWS - narrows'), ('TNLN', 'TNLN - natural tunnel'), ('RESN', 'RESN - nature reserve'), ('NVB', 'NVB - naval base'), ('CNLN', 'CNLN - navigation canal(s)'), ('CHNN', 'CHNN - navigation channel'), ('MNNI', 'MNNI - nickel mine(s)'), ('NOV', 'NOV - novitiate'), ('PSN', 'PSN - nuclear power station'), ('NTK', 'NTK - nunatak'), ('NTKS', 'NTKS - nunataks'), ('NSY', 'NSY - nursery(-ies)'), ('OAS', 'OAS - oasis(-es)'), ('OBPT', 'OBPT - observation point'), ('OBS', 'OBS - observatory'), ('OCN', 'OCN - ocean'), ('BLDO', 'BLDO - office building'), ('CMPO', 'CMPO - oil camp'), ('ESTO', 'ESTO - oil palm plantation'), ('OILP', 'OILP - oil pipeline'), ('OILJ', 'OILJ - oil pipeline junction'), ('TRMO', 'TRMO - oil pipeline terminal'), ('PMPO', 'PMPO - oil pumping station'), ('OILR', 'OILR - oil refinery'), ('OILW', 'OILW - oil well'), ('OILF', 'OILF - oilfield'), ('GRVO', 'GRVO - olive grove'), ('MLO', 'MLO - olive oil mill'), ('OCH', 'OCH - orchard(s)'), ('MLM', 'MLM - ore treatment plant'), ('OVF', 'OVF - overfalls'), ('LKO', 'LKO - oxbow lake'), ('PGDA', 'PGDA - pagoda'), ('PAL', 'PAL - palace'), ('GRVP', 'GRVP - palm grove'), ('RESP', 'RESP - palm tree reserve'), ('PAN', 'PAN - pan'), ('PANS', 'PANS - pans'), ('PRSH', 'PRSH - parish'), ('PRK', 'PRK - park'), ('PRKGT', 'PRKGT - park gate'), ('PRKHQ', 'PRKHQ - park headquarters'), ('GARG', 'GARG - parking garage'), ('PKLT', 'PKLT - parking lot'), ('PASS', 'PASS - pass'), ('PSTP', 'PSTP - patrol post'), ('PK', 'PK - peak'), ('PKS', 'PKS - peaks'), ('PEAT', 'PEAT - peat cutting area'), ('PEN', 'PEN - peninsula'), ('BSNP', 'BSNP - petroleum basin'), ('MFGPH', 'MFGPH - phosphate works'), ('PIER', 'PIER - pier'), ('GRVPN', 'GRVPN - pine grove'), ('MNPL', 'MNPL - placer mine(s)'), ('PLN', 'PLN - plain(s)'), ('PLAT', 'PLAT - plateau'), ('PT', 'PT - point'), ('PTS', 'PTS - points'), ('PLDR', 'PLDR - polder'), ('PP', 'PP - police post'), ('PCL', 'PCL - political entity'), ('PND', 'PND - pond'), ('PNDS', 'PNDS - ponds'), ('POOL', 'POOL - pool(s)'), ('PPLL', 'PPLL - populated locality'), ('PPL', 'PPL - populated place'), ('PPLS', 'PPLS - populated places'), ('PRT', 'PRT - port'), ('PTGE', 'PTGE - portage'), ('PO', 'PO - post office'), ('PS', 'PS - power station'), ('PRN', 'PRN - prison'), ('PRMN', 'PRMN - promenade'), ('PROM', 'PROM - promontory(-ies)'), ('PYR', 'PYR - pyramid'), ('PYRS', 'PYRS - pyramids'), ('MNQR', 'MNQR - quarry(-ies)'), ('QUAY', 'QUAY - quay'), ('QCKS', 'QCKS - quicksand'), ('RECR', 'RECR - racetrack'), ('OBSR', 'OBSR - radio observatory'), ('STNR', 'STNR - radio station'), ('RR', 'RR - railroad'), ('RJCT', 'RJCT - railroad junction'), ('RSD', 'RSD - railroad siding'), ('RSGNL', 'RSGNL - railroad signal'), ('RSTN', 'RSTN - railroad station'), ('RSTP', 'RSTP - railroad stop'), ('TNLRR', 'TNLRR - railroad tunnel'), ('RYD', 'RYD - railroad yard'), ('RNCH', 'RNCH - ranch(es)'), ('RPDS', 'RPDS - rapids'), ('RVN', 'RVN - ravine(s)'), ('RCH', 'RCH - reach'), ('RF', 'RF - reef(s)'), ('PRNJ', 'PRNJ - reformatory'), ('CMPRF', 'CMPRF - refugee camp'), ('RGN', 'RGN - region'), ('CTRR', 'CTRR - religious center'), ('PPLR', 'PPLR - religious populated place'), ('RLG', 'RLG - religious site'), ('ITTR', 'ITTR - research institute'), ('RESV', 'RESV - reservation'), ('RES', 'RES - reserve'), ('RSV', 'RSV - reservoir(s)'), ('RSRT', 'RSRT - resort'), ('RHSE', 'RHSE - resthouse'), ('RLGR', 'RLGR - retreat'), ('RDGE', 'RDGE - ridge(s)'), ('RD', 'RD - road'), ('RDB', 'RDB - road bend'), ('RDCUT', 'RDCUT - road cut'), ('RDJCT', 'RDJCT - road junction'), ('TNLRD', 'TNLRD - road tunnel'), ('RDST', 'RDST - roadstead'), ('RK', 'RK - rock'), ('HMDA', 'HMDA - rock desert'), ('RKFL', 'RKFL - rockfall'), ('RKS', 'RKS - rocks'), ('RKRY', 'RKRY - rookery'), ('ESTR', 'ESTR - rubber plantation'), ('RUIN', 'RUIN - ruin(s)'), ('BDGQ', 'BDGQ - ruined bridge'), ('DAMQ', 'DAMQ - ruined dam'), ('SBKH', 'SBKH - sabkha(s)'), ('SDL', 'SDL - saddle'), ('SALT', 'SALT - salt area'), ('MFGN', 'MFGN - salt evaporation ponds'), ('LKN', 'LKN - salt lake'), ('LKSN', 'LKSN - salt lakes'), ('MRSHN', 'MRSHN - salt marsh'), ('MNN', 'MNN - salt mine(s)'), ('PNDN', 'PNDN - salt pond'), ('PNDSN', 'PNDSN - salt ponds'), ('SNTR', 'SNTR - sanatorium'), ('SAND', 'SAND - sand area'), ('ERG', 'ERG - sandy desert'), ('STNS', 'STNS - satellite station'), ('MLSW', 'MLSW - sawmill'), ('SCH', 'SCH - school'), ('ADMS', 'ADMS - school district'), ('STNB', 'STNB - scientific research base'), ('SCRB', 'SCRB - scrubland'), ('SEA', 'SEA - sea'), ('SCNU', 'SCNU - seachannel'), ('SCSU', 'SCSU - seachannels'), ('SMU', 'SMU - seamount'), ('SMSU', 'SMSU - seamounts'), ('AIRS', 'AIRS - seaplane landing area'), ('PPLA', 'PPLA - seat of a first-order administrative division'), ('PPLA4', 'PPLA4 - seat of a fourth-order administrative division'), ('PPLA2', 'PPLA2 - seat of a second-order administrative division'), ('PPLA3', 'PPLA3 - seat of a third-order administrative division'), ('ADM2', 'ADM2 - second-order administrative division'), ('BNKX', 'BNKX - section of bank'), ('CNLX', 'CNLX - section of canal'), ('ESTX', 'ESTX - section of estate'), ('HBRX', 'HBRX - section of harbor'), ('PCLIX', 'PCLIX - section of independent political entity'), ('STMIX', 'STMIX - section of intermittent stream'), ('ISLX', 'ISLX - section of island'), ('LGNX', 'LGNX - section of lagoon'), ('LKX', 'LKX - section of lake'), ('PENX', 'PENX - section of peninsula'), ('PLNX', 'PLNX - section of plain'), ('PLATX', 'PLATX - section of plateau'), ('PPLX', 'PPLX - section of populated place'), ('RFX', 'RFX - section of reef'), ('STMX', 'STMX - section of stream'), ('VALX', 'VALX - section of valley'), ('WADX', 'WADX - section of wadi'), ('FLLSX', 'FLLSX - section of waterfall(s)'), ('PCLS', 'PCLS - semi-independent political entity'), ('SWT', 'SWT - sewage treatment plant'), ('SHPF', 'SHPF - sheepfold'), ('SHOL', 'SHOL - shoal(s)'), ('SHOPC', 'SHOPC - shopping center or mall'), ('SHOR', 'SHOR - shore'), ('SHRN', 'SHRN - shrine'), ('SILL', 'SILL - sill'), ('SINK', 'SINK - sinkhole'), ('ESTSL', 'ESTSL - sisal plantation'), ('SLID', 'SLID - slide'), ('SLP', 'SLP - slope(s)'), ('SLCE', 'SLCE - sluice'), ('SNOW', 'SNOW - snowfield'), ('SD', 'SD - sound'), ('SPA', 'SPA - spa'), ('CTRS', 'CTRS - space center'), ('SPLY', 'SPLY - spillway'), ('SPIT', 'SPIT - spit'), ('SPNG', 'SPNG - spring(s)'), ('SPUR', 'SPUR - spur(s)'), ('SQR', 'SQR - square'), ('STBL', 'STBL - stable'), ('STDM', 'STDM - stadium'), ('STPS', 'STPS - steps'), ('STKR', 'STKR - stock route'), ('REG', 'REG - stony desert'), ('RET', 'RET - store'), ('SHSE', 'SHSE - storehouse'), ('STRT', 'STRT - strait'), ('STM', 'STM - stream'), ('BNKR', 'BNKR - stream bank'), ('STMB', 'STMB - stream bend'), ('STMGS', 'STMGS - stream gauging station'), ('STMM', 'STMM - stream mouth(s)'), ('STMS', 'STMS - streams'), ('ST', 'ST - street'), ('DAMSB', 'DAMSB - sub-surface dam'), ('SUBW', 'SUBW - subway'), ('SUBS', 'SUBS - subway station'), ('MLSG', 'MLSG - sugar mill'), ('ESTSG', 'ESTSG - sugar plantation'), ('MFGSG', 'MFGSG - sugar refinery'), ('SPNS', 'SPNS - sulphur spring(s)'), ('SWMP', 'SWMP - swamp'), ('SYG', 'SYG - synagogue'), ('TMTU', 'TMTU - tablemount (or guyot)'), ('TMSU', 'TMSU - tablemounts (or guyots)'), ('TAL', 'TAL - talus slope'), ('OILT', 'OILT - tank farm'), ('ESTT', 'ESTT - tea plantation'), ('SCHT', 'SCHT - technical school'), ('TMPL', 'TMPL - temple(s)'), ('AIRT', 'AIRT - terminal'), ('TRR', 'TRR - terrace'), ('TERR', 'TERR - territory'), ('ADM3', 'ADM3 - third-order administrative division'), ('CRKT', 'CRKT - tidal creek(s)'), ('FLTT', 'FLTT - tidal flat(s)'), ('MNSN', 'MNSN - tin mine(s)'), ('TOLL', 'TOLL - toll gate/barrier'), ('TMB', 'TMB - tomb(s)'), ('TOWR', 'TOWR - tower'), ('RDCR', 'RDCR - traffic circle'), ('TRL', 'TRL - trail'), ('TRANT', 'TRANT - transit terminal'), ('TREE', 'TREE - tree(s)'), ('TRIG', 'TRIG - triangulation station'), ('TRB', 'TRB - tribal area'), ('TUND', 'TUND - tundra'), ('TNL', 'TNL - tunnel'), ('TNLS', 'TNLS - tunnels'), ('CNLSB', 'CNLSB - underground irrigation canal(s)'), ('LKSB', 'LKSB - underground lake'), ('APNU', 'APNU - undersea apron'), ('ARCU', 'ARCU - undersea arch'), ('ARRU', 'ARRU - undersea arrugado'), ('BNKU', 'BNKU - undersea bank'), ('BKSU', 'BKSU - undersea banks'), ('BSNU', 'BSNU - undersea basin'), ('BNCU', 'BNCU - undersea bench'), ('BDLU', 'BDLU - undersea borderland'), ('CNYU', 'CNYU - undersea canyon'), ('CNSU', 'CNSU - undersea canyons'), ('CDAU', 'CDAU - undersea cordillera'), ('ESCU', 'ESCU - undersea escarpment (or scarp)'), ('FANU', 'FANU - undersea fan'), ('FLTU', 'FLTU - undersea flat'), ('FRKU', 'FRKU - undersea fork'), ('FRSU', 'FRSU - undersea forks'), ('FRZU', 'FRZU - undersea fracture zone'), ('FURU', 'FURU - undersea furrow'), ('GAPU', 'GAPU - undersea gap'), ('GLYU', 'GLYU - undersea gully'), ('HLLU', 'HLLU - undersea hill'), ('HLSU', 'HLSU - undersea hills'), ('HOLU', 'HOLU - undersea hole'), ('KNLU', 'KNLU - undersea knoll'), ('KNSU', 'KNSU - undersea knolls'), ('LDGU', 'LDGU - undersea ledge'), ('LEVU', 'LEVU - undersea levee'), ('MDVU', 'MDVU - undersea median valley'), ('MESU', 'MESU - undersea mesa'), ('MOTU', 'MOTU - undersea moat'), ('MNDU', 'MNDU - undersea mound'), ('MTU', 'MTU - undersea mountain'), ('MTSU', 'MTSU - undersea mountains'), ('PKU', 'PKU - undersea peak'), ('PKSU', 'PKSU - undersea peaks'), ('PNLU', 'PNLU - undersea pinnacle'), ('PLNU', 'PLNU - undersea plain'), ('PLTU', 'PLTU - undersea plateau'), ('PLFU', 'PLFU - undersea platform'), ('PRVU', 'PRVU - undersea province'), ('RMPU', 'RMPU - undersea ramp'), ('RNGU', 'RNGU - undersea range'), ('RAVU', 'RAVU - undersea ravine'), ('RFU', 'RFU - undersea reef'), ('RFSU', 'RFSU - undersea reefs'), ('RDGU', 'RDGU - undersea ridge'), ('RDSU', 'RDSU - undersea ridges'), ('RISU', 'RISU - undersea rise'), ('SDLU', 'SDLU - undersea saddle'), ('SHFU', 'SHFU - undersea shelf'), ('EDGU', 'EDGU - undersea shelf edge'), ('SHVU', 'SHVU - undersea shelf valley'), ('SHLU', 'SHLU - undersea shoal'), ('SHSU', 'SHSU - undersea shoals'), ('SILU', 'SILU - undersea sill'), ('SLPU', 'SLPU - undersea slope'), ('SPRU', 'SPRU - undersea spur'), ('TERU', 'TERU - undersea terrace'), ('TNGU', 'TNGU - undersea tongue'), ('TRNU', 'TRNU - undersea trench'), ('TRGU', 'TRGU - undersea trough'), ('VALU', 'VALU - undersea valley'), ('VLSU', 'VLSU - undersea valleys'), ('USGE', 'USGE - United States Government Establishment'), ('UPLD', 'UPLD - upland'), ('VAL', 'VAL - valley'), ('VALS', 'VALS - valleys'), ('VETF', 'VETF - veterinary facility'), ('VIN', 'VIN - vineyard'), ('VINS', 'VINS - vineyards'), ('VLC', 'VLC - volcano'), ('WAD', 'WAD - wadi'), ('WADB', 'WADB - wadi bend'), ('WADJ', 'WADJ - wadi junction'), ('WADM', 'WADM - wadi mouth'), ('WADS', 'WADS - wadies'), ('WALL', 'WALL - wall'), ('MLWTR', 'MLWTR - water mill'), ('PMPW', 'PMPW - water pumping station'), ('RSVT', 'RSVT - water tank'), ('WTRC', 'WTRC - watercourse'), ('FLLS', 'FLLS - waterfall(s)'), ('WTRH', 'WTRH - waterhole(s)'), ('WTRW', 'WTRW - waterworks'), ('WEIR', 'WEIR - weir(s)'), ('WLL', 'WLL - well'), ('WLLS', 'WLLS - wells'), ('WTLD', 'WTLD - wetland'), ('STNW', 'STNW - whaling station'), ('WHRF', 'WHRF - wharf(-ves)'), ('WHRL', 'WHRL - whirlpool'), ('RESW', 'RESW - wildlife reserve'), ('MLWND', 'MLWND - windmill'), ('WRCK', 'WRCK - wreck'), ('ZN', 'ZN - zone'), ('ZOO', 'ZOO - zoo')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectlocation', + name='location_class', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='class', choices=[('1', '1 - Administrative Region'), ('2', '2 - Populated Place'), ('3', '3 - Structure'), ('4', '4 - Other Topographical Feature')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectlocation', + name='location_reach', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='reach', choices=[('1', '1 - Activity'), ('2', '2 - Intended Beneficiaries')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='projectlocation', + name='vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='vocabulary', choices=[('A1', 'A1 - Global Admininistrative Unit Layers'), ('A2', 'A2 - UN Second Administrative Level Boundary Project'), ('A3', 'A3 - Global Administrative Areas'), ('A4', 'A4 - ISO Country (3166-1 alpha-2)'), ('G1', 'G1 - Geonames'), ('G2', 'G2 - OpenStreetMap')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='recipientcountry', + name='country', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='country', choices=[('AF', 'AF - Afghanistan'), ('AX', 'AX - \xc5land Islands'), ('AL', 'AL - Albania'), ('DZ', 'DZ - Algeria'), ('AS', 'AS - American Samoa'), ('AD', 'AD - Andorra'), ('AO', 'AO - Angola'), ('AI', 'AI - Anguilla'), ('AQ', 'AQ - Antarctica'), ('AG', 'AG - Antigua and Barbuda'), ('AR', 'AR - Argentina'), ('AM', 'AM - Armenia'), ('AW', 'AW - Aruba'), ('AU', 'AU - Australia'), ('AT', 'AT - Austria'), ('AZ', 'AZ - Azerbaijan'), ('BS', 'BS - Bahamas'), ('BH', 'BH - Bahrain'), ('BD', 'BD - Bangladesh'), ('BB', 'BB - Barbados'), ('BY', 'BY - Belarus'), ('BE', 'BE - Belgium'), ('BZ', 'BZ - Belize'), ('BJ', 'BJ - Benin'), ('BM', 'BM - Bermuda'), ('BT', 'BT - Bhutan'), ('BO', 'BO - Bolivia, Plurinational State of'), ('BQ', 'BQ - Bonaire, Saint Eustatius and Saba'), ('BA', 'BA - Bosnia and Herzegovina'), ('BW', 'BW - Botswana'), ('BV', 'BV - Bouvet Island'), ('BR', 'BR - Brazil'), ('IO', 'IO - British Indian Ocean Territory'), ('BN', 'BN - Brunei Darussalam'), ('BG', 'BG - Bulgaria'), ('BF', 'BF - Burkina Faso'), ('BI', 'BI - Burundi'), ('KH', 'KH - Cambodia'), ('CM', 'CM - Cameroon'), ('CA', 'CA - Canada'), ('CV', 'CV - Cape Verde'), ('KY', 'KY - Cayman Islands'), ('CF', 'CF - Central African Republic'), ('TD', 'TD - Chad'), ('CL', 'CL - Chile'), ('CN', 'CN - China'), ('CX', 'CX - Christmas Island'), ('CC', 'CC - Cocos (Keeling) Islands'), ('CO', 'CO - Colombia'), ('KM', 'KM - Comoros'), ('CG', 'CG - Congo'), ('CD', 'CD - Congo, The Democratic Republic of the'), ('CK', 'CK - Cook Islands'), ('CR', 'CR - Costa Rica'), ('CI', 'CI - C\xf4te Divoire'), ('HR', 'HR - Croatia'), ('CU', 'CU - Cuba'), ('CW', 'CW - Cura\xe7ao'), ('CY', 'CY - Cyprus'), ('CZ', 'CZ - Czech Republic'), ('DK', 'DK - Denmark'), ('DJ', 'DJ - Djibouti'), ('DM', 'DM - Dominica'), ('DO', 'DO - Dominican Republic'), ('EC', 'EC - Ecuador'), ('EG', 'EG - Egypt'), ('SV', 'SV - El Salvador'), ('GQ', 'GQ - Equatorial Guinea'), ('ER', 'ER - Eritrea'), ('EE', 'EE - Estonia'), ('ET', 'ET - Ethiopia'), ('FK', 'FK - Falkland Islands (Malvinas)'), ('FO', 'FO - Faroe Islands'), ('FJ', 'FJ - Fiji'), ('FI', 'FI - Finland'), ('FR', 'FR - France'), ('GF', 'GF - French Guiana'), ('PF', 'PF - French Polynesia'), ('TF', 'TF - French Southern Territories'), ('GA', 'GA - Gabon'), ('GM', 'GM - Gambia'), ('GE', 'GE - Georgia'), ('DE', 'DE - Germany'), ('GH', 'GH - Ghana'), ('GI', 'GI - Gibraltar'), ('GR', 'GR - Greece'), ('GL', 'GL - Greenland'), ('GD', 'GD - Grenada'), ('GP', 'GP - Guadeloupe'), ('GU', 'GU - Guam'), ('GT', 'GT - Guatemala'), ('GG', 'GG - Guernsey'), ('GN', 'GN - Guinea'), ('GW', 'GW - Guinea-Bissau'), ('GY', 'GY - Guyana'), ('HT', 'HT - Haiti'), ('HM', 'HM - Heard Island and Mcdonald Islands'), ('VA', 'VA - Holy See (Vatican City State)'), ('HN', 'HN - Honduras'), ('HK', 'HK - Hong Kong'), ('HU', 'HU - Hungary'), ('IS', 'IS - Iceland'), ('IN', 'IN - India'), ('ID', 'ID - Indonesia'), ('IR', 'IR - Iran, Islamic Republic of'), ('IQ', 'IQ - Iraq'), ('IE', 'IE - Ireland'), ('IM', 'IM - Isle of Man'), ('IL', 'IL - Israel'), ('IT', 'IT - Italy'), ('JM', 'JM - Jamaica'), ('JP', 'JP - Japan'), ('JE', 'JE - Jersey'), ('JO', 'JO - Jordan'), ('KZ', 'KZ - Kazakhstan'), ('KE', 'KE - Kenya'), ('KI', 'KI - Kiribati'), ('KP', 'KP - Korea, Democratic Peoples Republic of'), ('KR', 'KR - Korea, Republic of'), ('XK', 'XK - Kosovo'), ('KW', 'KW - Kuwait'), ('KG', 'KG - Kyrgyzstan'), ('LA', 'LA - Lao Peoples Democratic Republic'), ('LV', 'LV - Latvia'), ('LB', 'LB - Lebanon'), ('LS', 'LS - Lesotho'), ('LR', 'LR - Liberia'), ('LY', 'LY - Libyan Arab Jamahiriya'), ('LI', 'LI - Liechtenstein'), ('LT', 'LT - Lithuania'), ('LU', 'LU - Luxembourg'), ('MO', 'MO - Macao'), ('MK', 'MK - Macedonia, The Former Yugoslav Republic of'), ('MG', 'MG - Madagascar'), ('MW', 'MW - Malawi'), ('MY', 'MY - Malaysia'), ('MV', 'MV - Maldives'), ('ML', 'ML - Mali'), ('MT', 'MT - Malta'), ('MH', 'MH - Marshall Islands'), ('MQ', 'MQ - Martinique'), ('MR', 'MR - Mauritania'), ('MU', 'MU - Mauritius'), ('YT', 'YT - Mayotte'), ('MX', 'MX - Mexico'), ('FM', 'FM - Micronesia, Federated States of'), ('MD', 'MD - Moldova, Republic of'), ('MC', 'MC - Monaco'), ('MN', 'MN - Mongolia'), ('ME', 'ME - Montenegro'), ('MS', 'MS - Montserrat'), ('MA', 'MA - Morocco'), ('MZ', 'MZ - Mozambique'), ('MM', 'MM - Myanmar'), ('NA', 'NA - Namibia'), ('NR', 'NR - Nauru'), ('NP', 'NP - Nepal'), ('NL', 'NL - Netherlands'), ('AN', 'AN - Netherland Antilles'), ('NC', 'NC - New Caledonia'), ('NZ', 'NZ - New Zealand'), ('NI', 'NI - Nicaragua'), ('NE', 'NE - Niger'), ('NG', 'NG - Nigeria'), ('NU', 'NU - Niue'), ('NF', 'NF - Norfolk Island'), ('MP', 'MP - Northern Mariana Islands'), ('NO', 'NO - Norway'), ('OM', 'OM - Oman'), ('PK', 'PK - Pakistan'), ('PW', 'PW - Palau'), ('PS', 'PS - Palestinian Territory, Occupied'), ('PA', 'PA - Panama'), ('PG', 'PG - Papua New Guinea'), ('PY', 'PY - Paraguay'), ('PE', 'PE - Peru'), ('PH', 'PH - Philippines'), ('PN', 'PN - Pitcairn'), ('PL', 'PL - Poland'), ('PT', 'PT - Portugal'), ('PR', 'PR - Puerto Rico'), ('QA', 'QA - Qatar'), ('RE', 'RE - Reunion'), ('RO', 'RO - Romania'), ('RU', 'RU - Russian Federation'), ('RW', 'RW - Rwanda'), ('BL', 'BL - Saint Barth\xe9lemy'), ('SH', 'SH - Saint Helena, Ascension and Tristan da Cunha'), ('KN', 'KN - Saint Kitts and Nevis'), ('LC', 'LC - Saint Lucia'), ('MF', 'MF - Saint Martin (French Part)'), ('PM', 'PM - Saint Pierre and Miquelon'), ('VC', 'VC - Saint Vincent and the Grenadines'), ('WS', 'WS - Samoa'), ('SM', 'SM - San Marino'), ('ST', 'ST - Sao Tome and Principe'), ('SA', 'SA - Saudi Arabia'), ('SN', 'SN - Senegal'), ('RS', 'RS - Serbia'), ('SC', 'SC - Seychelles'), ('SL', 'SL - Sierra Leone'), ('SG', 'SG - Singapore'), ('SX', 'SX - Sint Maarten (Dutch Part)'), ('SK', 'SK - Slovakia'), ('SI', 'SI - Slovenia'), ('SB', 'SB - Solomon Islands'), ('SO', 'SO - Somalia'), ('ZA', 'ZA - South Africa'), ('GS', 'GS - South Georgia and the South Sandwich Islands'), ('SS', 'SS - South Sudan'), ('ES', 'ES - Spain'), ('LK', 'LK - Sri Lanka'), ('SD', 'SD - Sudan'), ('SR', 'SR - Suriname'), ('SJ', 'SJ - Svalbard and Jan Mayen'), ('SZ', 'SZ - Swaziland'), ('SE', 'SE - Sweden'), ('CH', 'CH - Switzerland'), ('SY', 'SY - Syrian Arab Republic'), ('TW', 'TW - Taiwan, Province of China'), ('TJ', 'TJ - Tajikistan'), ('TZ', 'TZ - Tanzania, United Republic of'), ('TH', 'TH - Thailand'), ('TL', 'TL - Timor-Leste'), ('TG', 'TG - Togo'), ('TK', 'TK - Tokelau'), ('TO', 'TO - Tonga'), ('TT', 'TT - Trinidad and Tobago'), ('TN', 'TN - Tunisia'), ('TR', 'TR - Turkey'), ('TM', 'TM - Turkmenistan'), ('TC', 'TC - Turks and Caicos Islands'), ('TV', 'TV - Tuvalu'), ('UG', 'UG - Uganda'), ('UA', 'UA - Ukraine'), ('AE', 'AE - United Arab Emirates'), ('GB', 'GB - United Kingdom'), ('US', 'US - United States'), ('UM', 'UM - United States Minor Outlying Islands'), ('UY', 'UY - Uruguay'), ('UZ', 'UZ - Uzbekistan'), ('VU', 'VU - Vanuatu'), ('VE', 'VE - Venezuela, Bolivarian Republic of'), ('VN', 'VN - Viet Nam'), ('VG', 'VG - Virgin Islands, British'), ('VI', 'VI - Virgin Islands, U.S.'), ('WF', 'WF - Wallis and Futuna'), ('EH', 'EH - Western Sahara'), ('YE', 'YE - Yemen'), ('ZM', 'ZM - Zambia'), ('ZW', 'ZW - Zimbabwe')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='recipientregion', + name='region', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='region', choices=[('88', '88 - States Ex-Yugoslavia unspecified'), ('89', '89 - Europe, regional'), ('189', '189 - North of Sahara, regional'), ('289', '289 - South of Sahara, regional'), ('298', '298 - Africa, regional'), ('380', '380 - West Indies, regional'), ('389', '389 - North and Central America, regional'), ('489', '489 - South America, regional'), ('498', '498 - America, regional'), ('589', '589 - Middle East, regional'), ('619', '619 - Central Asia, regional'), ('679', '679 - South Asia, regional'), ('689', '689 - South and Central Asia, regional'), ('789', '789 - Far East Asia, regional'), ('798', '798 - Asia, regional'), ('889', '889 - Oceania, regional'), ('998', '998 - Developing countries, unspecified')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='recipientregion', + name='region_vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='region vocabulary', choices=[('1', '1 - OECD DAC'), ('2', '2 - UN')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='relatedproject', + name='related_project', + field=models.ForeignKey(related_name='related_to_projects', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='rsr.Project', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='relatedproject', + name='relation', + field=akvo.rsr.fields.ValidXMLCharField(help_text="The relation between a project and related project. (E.g. select the 'Parent' relation when the selected project here is the parent of this project).", max_length=1, verbose_name='relation', choices=[('1', '1 - Parent'), ('2', '2 - Child'), ('3', '3 - Sibling'), ('4', '4 - Co-funded'), ('5', '5 - Third Party')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='result', + name='type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select whether the result is an output, outcome or impact.
Further explanation on result types', max_length=1, verbose_name='type', choices=[('1', '1 - Output'), ('2', '2 - Outcome'), ('3', '3 - Impact'), ('9', '9 - Other')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='sector', + name='vocabulary', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=5, verbose_name='vocabulary', choices=[('1', '1 - OECD DAC CRS Purpose Codes (5 digit)'), ('2', '2 - OECD DAC CRS Purpose Codes (3 digit)'), ('3', '3 - Classification of the Functions of Government (UN)'), ('4', '4 - Statistical classification of economic activities in the European Community'), ('5', '5 - National Taxonomy for Exempt Entities (USA)'), ('6', '6 - AidData'), ('99', '99 - Reporting Organisation'), ('98', '98 - Reporting Organisation 2')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='aid_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='aid type', choices=[('A01', 'A01 - General budget support'), ('A02', 'A02 - Sector budget support'), ('B01', 'B01 - Core support to NGOs, other private bodies, PPPs and research institutes'), ('B02', 'B02 - Core contributions to multilateral institutions'), ('B03', 'B03 - Contributions to specific-purpose programmes and funds managed by international organisations (multilateral, INGO)'), ('B04', 'B04 - Basket funds/pooled funding'), ('C01', 'C01 - Project-type interventions'), ('D01', 'D01 - Donor country personnel'), ('D02', 'D02 - Other technical assistance'), ('E01', 'E01 - Scholarships/training in donor country'), ('E02', 'E02 - Imputed student costs'), ('F01', 'F01 - Debt relief'), ('G01', 'G01 - Administrative costs not included elsewhere'), ('H01', 'H01 - Development awareness'), ('H02', 'H02 - Refugees in donor countries')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='currency', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='currency', choices=[('AED', 'AED - UAE Dirham'), ('AFN', 'AFN - Afghani'), ('ALL', 'ALL - Lek'), ('AMD', 'AMD - Armenian Dram'), ('ANG', 'ANG - Netherlands Antillian Guilder'), ('AOA', 'AOA - Kwanza'), ('ARS', 'ARS - Argentine Peso'), ('AUD', 'AUD - Australian Dollar'), ('AWG', 'AWG - Aruban Guilder'), ('AZN', 'AZN - Azerbaijanian Manat'), ('BAM', 'BAM - Convertible Marks'), ('BBD', 'BBD - Barbados Dollar'), ('BDT', 'BDT - Taka'), ('BGN', 'BGN - Bulgarian Lev'), ('BHD', 'BHD - Bahraini Dinar'), ('BIF', 'BIF - Burundi Franc'), ('BMD', 'BMD - Bermudian Dollar'), ('BND', 'BND - Brunei Dollar'), ('BOB', 'BOB - Boliviano'), ('BOV', 'BOV - Mvdol'), ('BRL', 'BRL - Brazilian Real'), ('BSD', 'BSD - Bahamian Dollar'), ('BTN', 'BTN - Ngultrum'), ('BWP', 'BWP - Pula'), ('BYR', 'BYR - Belarussian Ruble'), ('BZD', 'BZD - Belize Dollar'), ('CAD', 'CAD - Canadian Dollar'), ('CDF', 'CDF - Congolese Franc'), ('CHF', 'CHF - Swiss Franc'), ('CLF', 'CLF - Unidades de fomento'), ('CLP', 'CLP - Chilean Peso'), ('CNY', 'CNY - Yuan Renminbi'), ('COP', 'COP - Colombian Peso'), ('COU', 'COU - Unidad de Valor Real'), ('CRC', 'CRC - Costa Rican Colon'), ('CUC', 'CUC - Peso Convertible'), ('CUP', 'CUP - Cuban Peso'), ('CVE', 'CVE - Cape Verde Escudo'), ('CZK', 'CZK - Czech Koruna'), ('DJF', 'DJF - Djibouti Franc'), ('DKK', 'DKK - Danish Krone'), ('DOP', 'DOP - Dominican Peso'), ('DZD', 'DZD - Algerian Dinar'), ('EEK', 'EEK - Kroon'), ('EGP', 'EGP - Egyptian Pound'), ('ERN', 'ERN - Nakfa'), ('ETB', 'ETB - Ethiopian Birr'), ('EUR', 'EUR - Euro'), ('FJD', 'FJD - Fiji Dollar'), ('FKP', 'FKP - Falkland Islands Pound'), ('GBP', 'GBP - Pound Sterling'), ('GEL', 'GEL - Lari'), ('GHS', 'GHS - Cedi'), ('GIP', 'GIP - Gibraltar Pound'), ('GMD', 'GMD - Dalasi'), ('GNF', 'GNF - Guinea Franc'), ('GTQ', 'GTQ - Quetzal'), ('GYD', 'GYD - Guyana Dollar'), ('HKD', 'HKD - Hong Kong Dollar'), ('HNL', 'HNL - Lempira'), ('HRK', 'HRK - Croatian Kuna'), ('HTG', 'HTG - Gourde'), ('HUF', 'HUF - Forint'), ('IDR', 'IDR - Rupiah'), ('ILS', 'ILS - New Israeli Sheqel'), ('INR', 'INR - Indian Rupee'), ('IQD', 'IQD - Iraqi Dinar'), ('IRR', 'IRR - Iranian Rial'), ('ISK', 'ISK - Iceland Krona'), ('JMD', 'JMD - Jamaican Dollar'), ('JOD', 'JOD - Jordanian Dinar'), ('JPY', 'JPY - Yen'), ('KES', 'KES - Kenyan Shilling'), ('KGS', 'KGS - Som'), ('KHR', 'KHR - Riel'), ('KMF', 'KMF - Comoro Franc'), ('KPW', 'KPW - North Korean Won'), ('KRW', 'KRW - Won'), ('KWD', 'KWD - Kuwaiti Dinar'), ('KYD', 'KYD - Cayman Islands Dollar'), ('KZT', 'KZT - Tenge'), ('LAK', 'LAK - Kip'), ('LBP', 'LBP - Lebanese Pound'), ('LKR', 'LKR - Sri Lanka Rupee'), ('LRD', 'LRD - Liberian Dollar'), ('LSL', 'LSL - Loti'), ('LTL', 'LTL - Lithuanian Litas'), ('LVL', 'LVL - Latvian Lats'), ('LYD', 'LYD - Libyan Dinar'), ('MAD', 'MAD - Moroccan Dirham'), ('MDL', 'MDL - Moldovan Leu'), ('MGA', 'MGA - Malagasy Ariary'), ('MKD', 'MKD - Denar'), ('MMK', 'MMK - Kyat'), ('MNT', 'MNT - Tugrik'), ('MOP', 'MOP - Pataca'), ('MRO', 'MRO - Ouguiya'), ('MUR', 'MUR - Mauritius Rupee'), ('MVR', 'MVR - Rufiyaa'), ('MWK', 'MWK - Malawi Kwacha'), ('MXN', 'MXN - Mexican Peso'), ('MXV', 'MXV - Mexican Unidad de Inversion (UDI)'), ('MYR', 'MYR - Malaysian Ringgit'), ('MZN', 'MZN - Metical'), ('NAD', 'NAD - Namibia Dollar'), ('NGN', 'NGN - Naira'), ('NIO', 'NIO - Cordoba Oro'), ('NOK', 'NOK - Norwegian Krone'), ('NPR', 'NPR - Nepalese Rupee'), ('NZD', 'NZD - New Zealand Dollar'), ('OMR', 'OMR - Rial Omani'), ('PAB', 'PAB - Balboa'), ('PEN', 'PEN - Nuevo Sol'), ('PGK', 'PGK - Kina'), ('PHP', 'PHP - Philippine Peso'), ('PKR', 'PKR - Pakistan Rupee'), ('PLN', 'PLN - Zloty'), ('PYG', 'PYG - Guarani'), ('QAR', 'QAR - Qatari Rial'), ('RON', 'RON - New Leu'), ('RSD', 'RSD - Serbian Dinar'), ('RUB', 'RUB - Russian Ruble'), ('RWF', 'RWF - Rwanda Franc'), ('SAR', 'SAR - Saudi Riyal'), ('SBD', 'SBD - Solomon Islands Dollar'), ('SCR', 'SCR - Seychelles Rupee'), ('SDG', 'SDG - Sudanese Pound'), ('SEK', 'SEK - Swedish Krona'), ('SGD', 'SGD - Singapore Dollar'), ('SHP', 'SHP - Saint Helena Pound'), ('SLL', 'SLL - Leone'), ('SOS', 'SOS - Somali Shilling'), ('SSP', 'SSP - South Sudanese Pound'), ('SRD', 'SRD - Surinam Dollar'), ('STD', 'STD - Dobra'), ('SVC', 'SVC - El Salvador Colon'), ('SYP', 'SYP - Syrian Pound'), ('SZL', 'SZL - Lilangeni'), ('THB', 'THB - Baht'), ('TJS', 'TJS - Somoni'), ('TMT', 'TMT - Manat'), ('TND', 'TND - Tunisian Dinar'), ('TOP', 'TOP - Paanga'), ('TRY', 'TRY - Turkish Lira'), ('TTD', 'TTD - Trinidad and Tobago Dollar'), ('TWD', 'TWD - New Taiwan Dollar'), ('TZS', 'TZS - Tanzanian Shilling'), ('UAH', 'UAH - Hryvnia'), ('UGX', 'UGX - Uganda Shilling'), ('USD', 'USD - US Dollar'), ('USN', 'USN - US Dollar (Next day)'), ('USS', 'USS - US Dollar (Same day)'), ('UYI', 'UYI - Uruguay Peso en Unidades Indexadas'), ('UYU', 'UYU - Peso Uruguayo'), ('UZS', 'UZS - Uzbekistan Sum'), ('VEF', 'VEF - Bolivar'), ('VND', 'VND - Dong'), ('VUV', 'VUV - Vatu'), ('WST', 'WST - Tala'), ('XAF', 'XAF - CFA Franc BEAC'), ('XCD', 'XCD - East Caribbean Dollar'), ('XOF', 'XOF - CFA Franc BCEAO'), ('XPF', 'XPF - CFP Franc'), ('YER', 'YER - Yemeni Rial'), ('ZAR', 'ZAR - Rand'), ('ZMK', 'ZMK - Zambian Kwacha'), ('ZWL', 'ZWL - Zimbabwe Dollar')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='disbursement_channel', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='disbursement channel', choices=[('1', '1 - Money is disbursed through central Ministry of Finance or Treasury'), ('2', '2 - Money is disbursed directly to the implementing institution and managed through a separate bank account'), ('3', '3 - Aid in kind: Donors utilise third party agencies, e.g. NGOs or management companies'), ('4', '4 - Aid in kind: Donors manage funds themselves')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='finance_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=3, verbose_name='finance type', choices=[('110', '110 - Aid grant excluding debt reorganisation'), ('111', '111 - Subsidies to national private investors'), ('210', '210 - Interest subsidy grant in AF'), ('211', '211 - Interest subsidy to national private exporters'), ('310', '310 - Deposit basis'), ('311', '311 - Encashment basis'), ('410', '410 - Aid loan excluding debt reorganisation'), ('411', '411 - Investment-related loan to developing countries'), ('412', '412 - Loan in a joint venture with the recipient'), ('413', '413 - Loan to national private investor'), ('414', '414 - Loan to national private exporter'), ('451', '451 - Non-banks guaranteed export credits'), ('452', '452 - Non-banks non-guaranteed portions of guaranteed export credits'), ('453', '453 - Bank export credits'), ('510', '510 - Acquisition of equity as part of a joint venture with the recipient'), ('511', '511 - Acquisition of equity not part of joint venture in developing countries'), ('512', '512 - Other acquisition of equity. Investment in a country on the DAC List of ODA Recipients that is not made to acquire a lasting interest in an enterprise.'), ('610', '610 - Debt forgiveness: ODA claims (P)'), ('611', '611 - Debt forgiveness: ODA claims (I)'), ('612', '612 - Debt forgiveness: OOF claims (P)'), ('613', '613 - Debt forgiveness: OOF claims (I)'), ('614', '614 - Debt forgiveness: Private claims (P)'), ('615', '615 - Debt forgiveness: Private claims (I)'), ('616', '616 - Debt forgiveness: OOF claims (DSR)'), ('617', '617 - Debt forgiveness: Private claims (DSR)'), ('618', '618 - Debt forgiveness: Other'), ('620', '620 - Debt rescheduling: ODA claims (P)'), ('621', '621 - Debt rescheduling: ODA claims (I)'), ('622', '622 - Debt rescheduling: OOF claims (P)'), ('623', '623 - Debt rescheduling: OOF claims (I)'), ('624', '624 - Debt rescheduling: Private claims (P)'), ('625', '625 - Debt rescheduling: Private claims (I)'), ('626', '626 - Debt rescheduling: OOF claims (DSR)'), ('627', '627 - Debt rescheduling: Private claims (DSR)'), ('630', '630 - Debt rescheduling: OOF claim (DSR - original loan principal)'), ('631', '631 - Debt rescheduling: OOF claim (DSR - original loan interest)'), ('632', '632 - Debt rescheduling: Private claim (DSR - original loan principal)'), ('710', '710 - Foreign direct investment'), ('711', '711 - Other foreign direct investment, including reinvested earnings'), ('810', '810 - Bank bonds'), ('811', '811 - Non-bank bonds'), ('910', '910 - Other bank securities/claims'), ('911', '911 - Other non-bank securities/claims'), ('912', '912 - Securities and other instruments issued by multilateral agencies')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='flow_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=2, verbose_name='flow type', choices=[('10', '10 - ODA'), ('20', '20 - OOF'), ('30', '30 - Private NGO and other private sources'), ('35', '35 - Private Market'), ('40', '40 - Non flow'), ('50', '50 - Other flows')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='provider_organisation', + field=models.ForeignKey(related_name='providing_transactions', on_delete=django.db.models.deletion.SET_NULL, verbose_name='provider organisation', blank=True, to='rsr.Organisation', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='receiver_organisation', + field=models.ForeignKey(related_name='receiving_transactions', on_delete=django.db.models.deletion.SET_NULL, verbose_name='receiver organisation', blank=True, to='rsr.Organisation', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='tied_status', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, max_length=1, verbose_name='tied status', choices=[('3', '3 - Partially tied'), ('4', '4 - Tied'), ('5', '5 - Untied')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transaction', + name='transaction_type', + field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select the type of transaction from the list.', max_length=2, verbose_name='transaction type', choices=[('1', '1 - Incoming Funds'), ('2', '2 - Commitment'), ('3', '3 - Disbursement'), ('4', '4 - Expenditure'), ('5', '5 - Interest Repayment'), ('6', '6 - Loan Repayment'), ('7', '7 - Reimbursement'), ('8', '8 - Purchase of Equity'), ('9', '9 - Sale of Equity'), ('10', '10 - Credit Guarantee')]), + preserve_default=True, + ), + ] diff --git a/akvo/rsr/models/budget_item.py b/akvo/rsr/models/budget_item.py index 3a51f93f87..157f11c99d 100644 --- a/akvo/rsr/models/budget_item.py +++ b/akvo/rsr/models/budget_item.py @@ -11,7 +11,8 @@ from ..fields import ValidXMLCharField -from akvo.codelists.models import BudgetIdentifier, BudgetIdentifierVocabulary, BudgetType, Currency +from akvo.codelists.models import BudgetIdentifier, BudgetType, Currency +from akvo.codelists.store.codelists_v201 import BUDGET_IDENTIFIER,BUDGET_TYPE, CURRENCY from akvo.utils import codelist_choices, codelist_value @@ -47,14 +48,14 @@ class BudgetItem(models.Model): # Extra IATI fields type = ValidXMLCharField( - _(u'budget type'), blank=True, max_length=1, choices=codelist_choices(BudgetType), + _(u'budget type'), blank=True, max_length=1, choices=codelist_choices(BUDGET_TYPE), help_text=u'Select whether this is a planned or actual budget of the project.' ) period_start = models.DateField(_(u'period start'), null=True, blank=True) period_end = models.DateField(_(u'period end'), null=True, blank=True) value_date = models.DateField(_(u'value date'), null=True, blank=True) currency = ValidXMLCharField(_(u'currency'), max_length=3, blank=True, - choices=codelist_choices(Currency)) + choices=codelist_choices(CURRENCY)) def __unicode__(self): return self.label.__unicode__() @@ -84,7 +85,9 @@ class Meta: class CountryBudgetItem(models.Model): project = models.ForeignKey('Project', verbose_name=_(u'project'), related_name='country_budget_items') - code = ValidXMLCharField(_(u'budget item'), max_length=6, blank=True, choices=codelist_choices(BudgetIdentifier)) + code = ValidXMLCharField( + _(u'budget item'), max_length=6, blank=True, choices=codelist_choices(BUDGET_IDENTIFIER) + ) description = ValidXMLCharField( _(u'description'), max_length=100, blank=True, help_text=_(u'(max 100 characters)') ) @@ -96,9 +99,6 @@ class CountryBudgetItem(models.Model): def iati_code(self): return codelist_value(BudgetIdentifier, self, 'code') - def iati_vocabulary(self): - return codelist_value(BudgetIdentifierVocabulary, self, 'vocabulary') - class Meta: app_label = 'rsr' verbose_name = _(u'country budget item') diff --git a/akvo/rsr/models/country.py b/akvo/rsr/models/country.py index 2e94b0f89f..ed1283e64a 100644 --- a/akvo/rsr/models/country.py +++ b/akvo/rsr/models/country.py @@ -13,6 +13,7 @@ from ..iso3166 import ISO_3166_COUNTRIES, CONTINENTS, COUNTRY_CONTINENTS from akvo.codelists import models as codelist_models +from akvo.codelists.store.codelists_v201 import COUNTRY from akvo.utils import codelist_choices, codelist_value @@ -44,7 +45,7 @@ class Meta: class RecipientCountry(models.Model): project = models.ForeignKey('Project', verbose_name=u'project', related_name='recipient_countries') country = ValidXMLCharField(_(u'country'), blank=True, max_length=2, - choices=codelist_choices(codelist_models.Country)) + choices=codelist_choices(COUNTRY)) percentage = models.DecimalField( _(u'percentage'), blank=True, null=True, max_digits=4, decimal_places=1, validators=[MaxValueValidator(100), MinValueValidator(0)] diff --git a/akvo/rsr/models/crs_add.py b/akvo/rsr/models/crs_add.py index 811fbb34a2..0423d98670 100644 --- a/akvo/rsr/models/crs_add.py +++ b/akvo/rsr/models/crs_add.py @@ -12,6 +12,8 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import CRSAddOtherFlags, LoanRepaymentType, LoanRepaymentPeriod, Currency +from akvo.codelists.store.codelists_v201 import (C_R_S_ADD_OTHER_FLAGS, LOAN_REPAYMENT_TYPE, + LOAN_REPAYMENT_PERIOD, CURRENCY) from akvo.utils import codelist_choices, codelist_value @@ -28,16 +30,20 @@ class CrsAdd(models.Model): _(u'rate 2'), blank=True, null=True, max_digits=5, decimal_places=2, validators=[MaxValueValidator(100), MinValueValidator(0)] ) - repayment_type = ValidXMLCharField(_(u'repayment type'), max_length=1, choices=codelist_choices(LoanRepaymentType)) + repayment_type = ValidXMLCharField( + _(u'repayment type'), max_length=1, choices=codelist_choices(LOAN_REPAYMENT_TYPE) + ) repayment_plan = ValidXMLCharField( - _(u'repayment plan'), max_length=2, choices=codelist_choices(LoanRepaymentPeriod) + _(u'repayment plan'), max_length=2, choices=codelist_choices(LOAN_REPAYMENT_PERIOD) ) commitment_date = models.DateField(_(u'commitment date'), null=True, blank=True) repayment_first_date = models.DateField(_(u'first repayment date'), null=True, blank=True) repayment_final_date = models.DateField(_(u'final repayment date'), null=True, blank=True) - loan_status_year = models.PositiveIntegerField(_(u'loan status year'), blank=True, null=True, max_length=4) + loan_status_year = models.PositiveIntegerField( + _(u'loan status year'), blank=True, null=True, max_length=4 + ) loan_status_currency = ValidXMLCharField( - _(u'currency'), blank=True, max_length=3, choices=codelist_choices(Currency) + _(u'currency'), blank=True, max_length=3, choices=codelist_choices(CURRENCY) ) loan_status_value_date = models.DateField(_(u'loan status value date'), blank=True, null=True) interest_received = models.DecimalField( @@ -73,7 +79,9 @@ class CrsAddOtherFlag(models.Model): Other flag of CRS++ reporting. """ crs = models.ForeignKey('CrsAdd', verbose_name=u'crs', related_name='other_flags') - code = ValidXMLCharField(_(u'code'), max_length=1, choices=codelist_choices(CRSAddOtherFlags)) + code = ValidXMLCharField( + _(u'code'), max_length=1, choices=codelist_choices(C_R_S_ADD_OTHER_FLAGS) + ) significance = models.NullBooleanField(_(u'significance'), blank=True) def iati_code(self): diff --git a/akvo/rsr/models/fss.py b/akvo/rsr/models/fss.py index e9c3a7f9a8..95c4d02a53 100644 --- a/akvo/rsr/models/fss.py +++ b/akvo/rsr/models/fss.py @@ -5,13 +5,13 @@ # For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. -from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.utils.translation import ugettext_lazy as _ from ..fields import ValidXMLCharField from akvo.codelists.models import Currency +from akvo.codelists.store.codelists_v201 import CURRENCY from akvo.utils import codelist_choices, codelist_value @@ -22,7 +22,8 @@ class Fss(models.Model): project = models.OneToOneField('Project', primary_key=True) extraction_date = models.DateField(_(u'extraction date'), null=True, blank=True) priority = models.NullBooleanField(_(u'priority'), blank=True) - phaseout_year = models.PositiveIntegerField(_(u'phaseout year'), blank=True, null=True, max_length=4) + phaseout_year = models.PositiveIntegerField(_(u'phaseout year'), blank=True, null=True, + max_length=4) class Meta: app_label = 'rsr' @@ -37,8 +38,10 @@ class FssForecast(models.Model): fss = models.ForeignKey('Fss', verbose_name=u'fss', related_name='forecasts') year = models.PositiveIntegerField(_(u'year'), blank=True, null=True, max_length=4) value_date = models.DateField(_(u'value date'), blank=True, null=True) - currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, choices=codelist_choices(Currency)) - value = models.DecimalField(_(u'interest received'), max_digits=10, decimal_places=2, blank=True, null=True) + currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, + choices=codelist_choices(CURRENCY)) + value = models.DecimalField(_(u'interest received'), max_digits=10, decimal_places=2, + blank=True, null=True) def iati_currency(self): return codelist_value(Currency, self, 'loan_status_currency') diff --git a/akvo/rsr/models/indicator.py b/akvo/rsr/models/indicator.py index d4e8a62647..5683ce4c76 100644 --- a/akvo/rsr/models/indicator.py +++ b/akvo/rsr/models/indicator.py @@ -9,7 +9,8 @@ from django.utils.translation import ugettext_lazy as _ from ..fields import ValidXMLCharField -from akvo.codelists.models import DescriptionType, IndicatorMeasure +from akvo.codelists.models import IndicatorMeasure +from akvo.codelists.store.codelists_v201 import INDICATOR_MEASURE from akvo.utils import codelist_choices, codelist_value @@ -20,12 +21,13 @@ class Indicator(models.Model): help_text=_(u'Enter the title for the indicator from the project result. (255 characters)') ) measure = ValidXMLCharField( - _(u'measure'), blank=True, max_length=1, choices=codelist_choices(IndicatorMeasure), + _(u'measure'), blank=True, max_length=1, choices=codelist_choices(INDICATOR_MEASURE), help_text=_(u'Select whether the indicator counts units or evaluates a percentage.') ) ascending = models.NullBooleanField( _(u'ascending'), blank=True, - help_text=_(u'Is the aim of the project to increase or decrease the value of the indicator?')) + help_text=_(u'Is the aim of the project to increase or decrease the value of the ' + u'indicator?')) description = ValidXMLCharField( _(u'description'), blank=True, max_length=255, help_text=_(u'You can further define the indicator here. (255 characters)') @@ -67,7 +69,8 @@ class IndicatorPeriod(models.Model): ) target_value = ValidXMLCharField( _(u'target value'), blank=True, max_length=50, - help_text=_(u'Enter the value of the indicator that the project is intending to reach. (50 characters)') + help_text=_(u'Enter the value of the indicator that the project is intending to reach. ' + u'(50 characters)') ) target_comment = ValidXMLCharField( _(u'target comment'), blank=True, max_length=255, @@ -75,7 +78,8 @@ class IndicatorPeriod(models.Model): ) actual_value = ValidXMLCharField( _(u'actual value'), blank=True, max_length=50, - help_text=_(u'Enter the value of the indicator that the project has reached. (50 characters)') + help_text=_(u'Enter the value of the indicator that the project has reached. ' + u'(50 characters)') ) actual_comment = ValidXMLCharField( _(u'actual comment'), blank=True, max_length=255, diff --git a/akvo/rsr/models/location.py b/akvo/rsr/models/location.py index 07eca3f2d6..f80705cfdb 100644 --- a/akvo/rsr/models/location.py +++ b/akvo/rsr/models/location.py @@ -9,8 +9,11 @@ from django.utils.translation import ugettext_lazy as _ from ..fields import LatitudeField, LongitudeField, ValidXMLCharField -from akvo.codelists.models import (GeographicExactness, GeographicLocationClass, GeographicLocationReach, - GeographicVocabulary, LocationType) +from akvo.codelists.models import (GeographicExactness, GeographicLocationClass, + GeographicLocationReach, GeographicVocabulary, LocationType) +from akvo.codelists.store.codelists_v201 import (GEOGRAPHIC_EXACTNESS, GEOGRAPHIC_LOCATION_CLASS, + GEOGRAPHIC_LOCATION_REACH, GEOGRAPHIC_VOCABULARY, + LOCATION_TYPE) from akvo.utils import codelist_choices, codelist_value @@ -83,20 +86,20 @@ class ProjectLocation(BaseLocation): reference = ValidXMLCharField(_(u'reference'), blank=True, max_length=50) location_code = ValidXMLCharField(_(u'code'), blank=True, max_length=25) vocabulary = ValidXMLCharField(_(u'vocabulary'), blank=True, max_length=2, - choices=codelist_choices(GeographicVocabulary)) + choices=codelist_choices(GEOGRAPHIC_VOCABULARY)) name = ValidXMLCharField(_(u'name'), blank=True, max_length=100) description = ValidXMLCharField(_(u'description'), blank=True, max_length=255, help_text=_(u'(max 255 characters)')) activity_description = ValidXMLCharField( _(u'activity description'), blank=True, max_length=255, help_text=_(u'(max 255 characters)') ) exactness = ValidXMLCharField(_(u'exactness'), blank=True, max_length=1, - choices=codelist_choices(GeographicExactness)) + choices=codelist_choices(GEOGRAPHIC_EXACTNESS)) location_reach = ValidXMLCharField(_(u'reach'), blank=True, max_length=1, - choices=codelist_choices(GeographicLocationReach)) + choices=codelist_choices(GEOGRAPHIC_LOCATION_REACH)) location_class = ValidXMLCharField(_(u'class'), blank=True, max_length=1, - choices=codelist_choices(GeographicLocationClass)) + choices=codelist_choices(GEOGRAPHIC_LOCATION_CLASS)) feature_designation = ValidXMLCharField(_(u'feature designation'), blank=True, max_length=5, - choices=codelist_choices(LocationType)) + choices=codelist_choices(LOCATION_TYPE)) def iati_vocabulary(self): return codelist_value(GeographicVocabulary, self, 'vocabulary') @@ -121,7 +124,7 @@ class AdministrativeLocation(models.Model): code = ValidXMLCharField(_(u'administrative code'), blank=True, max_length=25) vocabulary = ValidXMLCharField( _(u'administrative vocabulary'), blank=True, max_length=2, - choices=codelist_choices(GeographicVocabulary) + choices=codelist_choices(GEOGRAPHIC_VOCABULARY) ) level = models.PositiveSmallIntegerField( _(u'administrative level'), blank=True, null=True, max_length=1 diff --git a/akvo/rsr/models/planned_disbursement.py b/akvo/rsr/models/planned_disbursement.py index 60f0bed2e0..484ab03106 100644 --- a/akvo/rsr/models/planned_disbursement.py +++ b/akvo/rsr/models/planned_disbursement.py @@ -10,6 +10,7 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import BudgetType, Currency +from akvo.codelists.store.codelists_v201 import BUDGET_TYPE, CURRENCY from akvo.utils import codelist_choices, codelist_value @@ -17,11 +18,13 @@ class PlannedDisbursement(models.Model): project = models.ForeignKey('Project', verbose_name=_(u'project'), related_name='planned_disbursements') value = models.DecimalField(_(u'value'), blank=True, max_digits=10, decimal_places=2) value_date = models.DateField(_(u'value date'), null=True, blank=True) - currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, choices=codelist_choices(Currency)) + currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, + choices=codelist_choices(CURRENCY)) updated = models.DateField(_(u'updated'), null=True, blank=True) period_start = models.DateField(_(u'period start'), null=True, blank=True) period_end = models.DateField(_(u'period end'), null=True, blank=True) - type = ValidXMLCharField(_(u'type'), blank=True, max_length=1, choices=codelist_choices(BudgetType)) + type = ValidXMLCharField(_(u'type'), blank=True, max_length=1, + choices=codelist_choices(BUDGET_TYPE)) def __unicode__(self): return self.value diff --git a/akvo/rsr/models/policy_marker.py b/akvo/rsr/models/policy_marker.py index 71e75f19ab..9e23808fc5 100644 --- a/akvo/rsr/models/policy_marker.py +++ b/akvo/rsr/models/policy_marker.py @@ -11,17 +11,19 @@ from ..fields import ValidXMLCharField from akvo.codelists import models as codelist_models +from akvo.codelists.store.codelists_v201 import (POLICY_MARKER, POLICY_SIGNIFICANCE, + POLICY_MARKER_VOCABULARY) from akvo.utils import codelist_choices, codelist_value class PolicyMarker(models.Model): project = models.ForeignKey('Project', verbose_name=_(u'project'), related_name='policy_markers') policy_marker = ValidXMLCharField(_(u'policy marker'), blank=True, max_length=2, - choices=codelist_choices(codelist_models.PolicyMarker)) + choices=codelist_choices(POLICY_MARKER)) significance = ValidXMLCharField(_(u'significance'), max_length=2, blank=True, - choices=codelist_choices(codelist_models.PolicySignificance)) + choices=codelist_choices(POLICY_SIGNIFICANCE)) vocabulary = ValidXMLCharField(_(u'vocabulary'), blank=True, max_length=5, - choices=codelist_choices(codelist_models.PolicyMarkerVocabulary)) + choices=codelist_choices(POLICY_MARKER_VOCABULARY)) description = ValidXMLCharField( _(u'description'), max_length=255, blank=True, help_text=_(u'(max 255 characters)') ) diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py index 237fb9d0fe..086a031282 100644 --- a/akvo/rsr/models/project.py +++ b/akvo/rsr/models/project.py @@ -23,6 +23,9 @@ from akvo.codelists.models import (AidType, ActivityScope, CollaborationType, FinanceType, FlowType, TiedStatus, BudgetIdentifierVocabulary) +from akvo.codelists.store.codelists_v201 import (AID_TYPE, ACTIVITY_SCOPE, COLLABORATION_TYPE, + FINANCE_TYPE, FLOW_TYPE, TIED_STATUS, + BUDGET_IDENTIFIER_VOCABULARY) from akvo.utils import codelist_choices, codelist_value, rsr_image_path, rsr_show_keywords from ...iati.mandatory_fields import check_export_fields @@ -227,7 +230,7 @@ class Project(TimestampsMixin, models.Model): u'So for example: is this project part of a larger project or programme.') ) project_scope = ValidXMLCharField( - _(u'project scope'), blank=True, max_length=2, choices=codelist_choices(ActivityScope), + _(u'project scope'), blank=True, max_length=2, choices=codelist_choices(ACTIVITY_SCOPE), help_text=_(u'Select the geographical scope of the project.') ) capital_spend_percentage = models.DecimalField( @@ -235,18 +238,18 @@ class Project(TimestampsMixin, models.Model): validators=[MaxValueValidator(100), MinValueValidator(0)] ) collaboration_type = ValidXMLCharField(_(u'collaboration type'), blank=True, max_length=1, - choices=codelist_choices(CollaborationType)) + choices=codelist_choices(COLLABORATION_TYPE)) default_aid_type = ValidXMLCharField(_(u'default aid type'), blank=True, max_length=3, - choices=codelist_choices(AidType)) + choices=codelist_choices(AID_TYPE)) default_finance_type = ValidXMLCharField(_(u'default finance type'), blank=True, max_length=3, - choices=codelist_choices(FinanceType)) + choices=codelist_choices(FINANCE_TYPE)) default_flow_type = ValidXMLCharField(_(u'default flow type'), blank=True, max_length=2, - choices=codelist_choices(FlowType)) + choices=codelist_choices(FLOW_TYPE)) default_tied_status = ValidXMLCharField(_(u'default tied status'), blank=True, max_length=1, - choices=codelist_choices(TiedStatus)) + choices=codelist_choices(TIED_STATUS)) country_budget_vocabulary = ValidXMLCharField( _(u'country budget vocabulary'), blank=True, max_length=1, - choices=codelist_choices(BudgetIdentifierVocabulary) + choices=codelist_choices(BUDGET_IDENTIFIER_VOCABULARY) ) # denormalized data diff --git a/akvo/rsr/models/project_condition.py b/akvo/rsr/models/project_condition.py index 53939ffc1d..69ed48e1cb 100644 --- a/akvo/rsr/models/project_condition.py +++ b/akvo/rsr/models/project_condition.py @@ -11,13 +11,16 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import ConditionType +from akvo.codelists.store.codelists_v201 import CONDITION_TYPE from akvo.utils import codelist_choices, codelist_value class ProjectCondition(models.Model): project = models.ForeignKey('Project', verbose_name=u'project', related_name='conditions') - text = ValidXMLCharField(_(u'condition'), blank=True, max_length=100, help_text=_(u'(100 characters)')) - type = ValidXMLCharField(_(u'condition type'), blank=True, max_length=1, choices=codelist_choices(ConditionType)) + text = ValidXMLCharField(_(u'condition'), blank=True, max_length=100, + help_text=_(u'(100 characters)')) + type = ValidXMLCharField(_(u'condition type'), blank=True, max_length=1, + choices=codelist_choices(CONDITION_TYPE)) def iati_type(self): return codelist_value(ConditionType, self, 'type') diff --git a/akvo/rsr/models/project_contact.py b/akvo/rsr/models/project_contact.py index 3440d3a8f5..fc3e67bfe9 100644 --- a/akvo/rsr/models/project_contact.py +++ b/akvo/rsr/models/project_contact.py @@ -11,12 +11,14 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import ContactType +from akvo.codelists.store.codelists_v201 import CONTACT_TYPE from akvo.utils import codelist_choices, codelist_value class ProjectContact(models.Model): project = models.ForeignKey('Project', verbose_name=u'project', related_name='contacts') - type = ValidXMLCharField(_(u'type'), blank=True, max_length=1, choices=codelist_choices(ContactType)) + type = ValidXMLCharField(_(u'type'), blank=True, max_length=1, + choices=codelist_choices(CONTACT_TYPE)) person_name = ValidXMLCharField( _(u'name'), blank=True, max_length=100, help_text=_(u'This should be a contact person for the project. (100 characters)') @@ -26,22 +28,27 @@ class ProjectContact(models.Model): help_text=_(u'This should be the email address for the contact person of the project.') ) job_title = ValidXMLCharField( - _(u'job title'), max_length=100, blank=True, help_text=_(u'Job title of the contact. (100 characters)') + _(u'job title'), max_length=100, blank=True, help_text=_(u'Job title of the contact. ' + u'(100 characters)') ) organisation = ValidXMLCharField( _(u'organisation'), blank=True, max_length=100, - help_text=_(u'The organisation that the contact person works for - this may differ from the ' - u'reporting organisation of the project. (100 characters)') + help_text=_(u'The organisation that the contact person works for - this may differ from ' + u'the reporting organisation of the project. (100 characters)') ) telephone = ValidXMLCharField( _(u'telephone'), blank=True, max_length=30, help_text=_(u'Contact number for the contact. (30 characters)')) mailing_address = ValidXMLCharField( - _(u'address'), max_length=255, blank=True, help_text=_(u'Address of the contact. (255 characters)') + _(u'address'), max_length=255, blank=True, help_text=_(u'Address of the contact. ' + u'(255 characters)') ) - state = ValidXMLCharField(_(u'state'), blank=True, max_length=100, help_text=_(u'(100 characters)')) - country = models.ForeignKey('Country', blank=True, null=True, verbose_name=u'country', related_name='contacts') - department = ValidXMLCharField(_(u'department'), blank=True, max_length=100, help_text=_(u'(100 characters)')) + state = ValidXMLCharField(_(u'state'), blank=True, max_length=100, + help_text=_(u'(100 characters)')) + country = models.ForeignKey('Country', blank=True, null=True, verbose_name=u'country', + related_name='contacts') + department = ValidXMLCharField(_(u'department'), blank=True, max_length=100, + help_text=_(u'(100 characters)')) website = models.URLField(_(u'website'), blank=True) def iati_type(self): diff --git a/akvo/rsr/models/project_document.py b/akvo/rsr/models/project_document.py index ee238f984d..3fb01e99cd 100644 --- a/akvo/rsr/models/project_document.py +++ b/akvo/rsr/models/project_document.py @@ -12,6 +12,7 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import DocumentCategory, Language +from akvo.codelists.store.codelists_v201 import DOCUMENT_CATEGORY, LANGUAGE from akvo.utils import codelist_choices, codelist_value @@ -23,37 +24,39 @@ class ProjectDocument(models.Model): project = models.ForeignKey('Project', related_name='documents', verbose_name=_(u'project')) url = models.URLField( _(u'url'), blank=True, - help_text=_(u'You can indicate an URL of a document of the project. These documents will allow users to ' - u'download and view to gain further insight in the project activities.') + help_text=_(u'You can indicate an URL of a document of the project. These documents will ' + u'allow users to download and view to gain further insight in the project ' + u'activities.') ) document = models.FileField( _(u'document'), blank=True, upload_to=document_path, - help_text=_(u'You can upload a document to your project. To upload multiple documents, press the \'Add ' - u'another Project Document\' link.
' + help_text=_(u'You can upload a document to your project. To upload multiple documents, ' + u'press the \'Add another Project Document\' link.
' u'These documents will be stored on the RSR server and will be ' - u'publicly available for users to download and view to gain further insight in the project ' - u'activities.') + u'publicly available for users to download and view to gain further insight in ' + u'the project activities.') ) format = ValidXMLCharField( _(u'format'), max_length=75, blank=True, help_text=_(u'Indicate the IATI format code of the document. Full list of IATI ' - u'format codes') + u'href="http://iatistandard.org/codelists/FileFormat/" target="_blank">Full ' + u'list of IATI format codes') ) title = ValidXMLCharField( - _(u'title'), max_length=100, blank=True, help_text=_(u'Indicate the document title. (100 characters)') + _(u'title'), max_length=100, blank=True, + help_text=_(u'Indicate the document title. (100 characters)') ) title_language = ValidXMLCharField( - _(u'title language'), max_length=2, blank=True, choices=codelist_choices(Language), + _(u'title language'), max_length=2, blank=True, choices=codelist_choices(LANGUAGE), help_text=_(u'Select the language of the document title.') ) category = ValidXMLCharField( _(u'category'), max_length=3, blank=True, - choices=codelist_choices(DocumentCategory), + choices=codelist_choices(DOCUMENT_CATEGORY), help_text=_(u'Select a document category.') ) language = ValidXMLCharField( - _(u'language'), max_length=2, blank=True, choices=codelist_choices(Language), + _(u'language'), max_length=2, blank=True, choices=codelist_choices(LANGUAGE), help_text=_(u'Select the language that the document is written in.') ) diff --git a/akvo/rsr/models/region.py b/akvo/rsr/models/region.py index 4075db57fd..a5dd8bc847 100644 --- a/akvo/rsr/models/region.py +++ b/akvo/rsr/models/region.py @@ -12,14 +12,15 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import Region, RegionVocabulary +from akvo.codelists.store.codelists_v201 import REGION, REGION_VOCABULARY from akvo.utils import codelist_choices, codelist_value class RecipientRegion(models.Model): project = models.ForeignKey('Project', verbose_name=u'project', related_name='recipient_regions') - region = ValidXMLCharField(_(u'region'), blank=True, max_length=3, choices=codelist_choices(Region)) + region = ValidXMLCharField(_(u'region'), blank=True, max_length=3, choices=codelist_choices(REGION)) region_vocabulary = ValidXMLCharField(_(u'region vocabulary'), blank=True, max_length=1, - choices=codelist_choices(RegionVocabulary)) + choices=codelist_choices(REGION_VOCABULARY)) percentage = models.DecimalField(_(u'percentage'), blank=True, null=True, max_digits=4, decimal_places=1, validators=[MaxValueValidator(100), MinValueValidator(0)]) text = ValidXMLCharField(_(u'region description'), blank=True, max_length=50, help_text=_(u'(max 50 characters)')) diff --git a/akvo/rsr/models/related_project.py b/akvo/rsr/models/related_project.py index 89f9e4d6e9..c6072246e0 100644 --- a/akvo/rsr/models/related_project.py +++ b/akvo/rsr/models/related_project.py @@ -10,6 +10,7 @@ from ..fields import ValidXMLCharField from akvo.codelists.models import RelatedActivityType +from akvo.codelists.store.codelists_v201 import RELATED_ACTIVITY_TYPE from akvo.utils import codelist_choices, codelist_value @@ -24,7 +25,7 @@ class RelatedProject(models.Model): u'Fill this in if the related project does not exist in RSR') ) relation = ValidXMLCharField( - _(u'relation'), max_length=1, choices=codelist_choices(RelatedActivityType), + _(u'relation'), max_length=1, choices=codelist_choices(RELATED_ACTIVITY_TYPE), help_text=_(u'The relation between a project and related project. ' u'(E.g. select the \'Parent\' relation when the selected project here is the parent of this project).') ) diff --git a/akvo/rsr/models/result.py b/akvo/rsr/models/result.py index bdd60daed4..e6e8cb9bb7 100644 --- a/akvo/rsr/models/result.py +++ b/akvo/rsr/models/result.py @@ -10,7 +10,8 @@ from ..fields import ValidXMLCharField -from akvo.codelists.models import DescriptionType, ResultType +from akvo.codelists.models import ResultType +from akvo.codelists.store.codelists_v201 import RESULT_TYPE from akvo.utils import codelist_choices, codelist_value @@ -21,7 +22,7 @@ class Result(models.Model): help_text=_(u'Enter the title of the result for this project. (255 characters)') ) type = ValidXMLCharField( - _(u'type'), blank=True, max_length=1, choices=codelist_choices(ResultType), + _(u'type'), blank=True, max_length=1, choices=codelist_choices(RESULT_TYPE), help_text=_(u'Select whether the result is an output, outcome or impact. ' u'Further explanation on result types') diff --git a/akvo/rsr/models/sector.py b/akvo/rsr/models/sector.py index 0d54640861..f428c72343 100644 --- a/akvo/rsr/models/sector.py +++ b/akvo/rsr/models/sector.py @@ -14,6 +14,7 @@ from ..fields import ValidXMLCharField from akvo.codelists import models as codelist_models +from akvo.codelists.store.codelists_v201 import SECTOR_VOCABULARY from akvo.utils import codelist_choices, codelist_value @@ -30,7 +31,7 @@ class Sector(models.Model): ) text = ValidXMLCharField(_(u'description'), blank=True, max_length=100, help_text=_(u'(max 100 characters)')) vocabulary = ValidXMLCharField( - _(u'vocabulary'), blank=True, max_length=5, choices=codelist_choices(codelist_models.SectorVocabulary) + _(u'vocabulary'), blank=True, max_length=5, choices=codelist_choices(SECTOR_VOCABULARY) ) percentage = models.DecimalField( _(u'sector percentage'), blank=True, null=True, max_digits=4, decimal_places=1, @@ -39,7 +40,7 @@ class Sector(models.Model): ) def __unicode__(self): - return self.sector_code + return self.iati_sector() def iati_sector_codes(self): if self.sector_code and (self.vocabulary == '1' or self.vocabulary == 'DAC'): diff --git a/akvo/rsr/models/transaction.py b/akvo/rsr/models/transaction.py index a8809fbd55..22a3f07e68 100644 --- a/akvo/rsr/models/transaction.py +++ b/akvo/rsr/models/transaction.py @@ -10,9 +10,12 @@ from ..fields import ValidXMLCharField -from akvo.codelists.models import (AidType, Currency, DisbursementChannel, FinanceType, FlowType, - TiedStatus, TransactionType, Country, Region, RegionVocabulary, - Sector, SectorCategory, SectorVocabulary) +from akvo.codelists.models import (Currency, DisbursementChannel,TransactionType, Country, Region, + RegionVocabulary, Sector, SectorCategory, SectorVocabulary) +from akvo.codelists.store.codelists_v201 import (AID_TYPE, CURRENCY, DISBURSEMENT_CHANNEL, + FINANCE_TYPE, FLOW_TYPE, TIED_STATUS, + TRANSACTION_TYPE, COUNTRY, REGION, + REGION_VOCABULARY, SECTOR_VOCABULARY) from akvo.utils import codelist_choices, codelist_value @@ -23,26 +26,26 @@ class Transaction(models.Model): help_text=_(u'Enter a reference for the transaction. (25 characters)') ) aid_type = ValidXMLCharField( - _(u'aid type'), blank=True, max_length=3, choices=codelist_choices(AidType) + _(u'aid type'), blank=True, max_length=3, choices=codelist_choices(AID_TYPE) ) description = ValidXMLCharField( _(u'description'), max_length=255, blank=True, help_text=_(u'Enter a description for the transaction. (255 characters)') ) disbursement_channel = ValidXMLCharField( - _(u'disbursement channel'), blank=True, max_length=1, choices=codelist_choices(DisbursementChannel) + _(u'disbursement channel'), blank=True, max_length=1, choices=codelist_choices(DISBURSEMENT_CHANNEL) ) finance_type = ValidXMLCharField( - _(u'finance type'), max_length=3, blank=True, choices=codelist_choices(FinanceType) + _(u'finance type'), max_length=3, blank=True, choices=codelist_choices(FINANCE_TYPE) ) - flow_type = ValidXMLCharField(_(u'flow type'), max_length=2, blank=True, choices=codelist_choices(FlowType)) - tied_status = ValidXMLCharField(_(u'tied status'), blank=True, max_length=1, choices=codelist_choices(TiedStatus)) + flow_type = ValidXMLCharField(_(u'flow type'), max_length=2, blank=True, choices=codelist_choices(FLOW_TYPE)) + tied_status = ValidXMLCharField(_(u'tied status'), blank=True, max_length=1, choices=codelist_choices(TIED_STATUS)) transaction_date = models.DateField( _(u'transaction date'), blank=True, null=True, help_text=u'Enter the financial reporting date that the transaction was/will be undertaken.' ) transaction_type = ValidXMLCharField( - _(u'transaction type'), blank=True, max_length=2, choices=codelist_choices(TransactionType), + _(u'transaction type'), blank=True, max_length=2, choices=codelist_choices(TRANSACTION_TYPE), help_text=_(u'Select the type of transaction from the list.') ) value = models.DecimalField( @@ -50,7 +53,7 @@ class Transaction(models.Model): help_text=u'Enter the transaction amount.' ) value_date = models.DateField(_(u'value date'), blank=True, null=True) - currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, choices=codelist_choices(Currency)) + currency = ValidXMLCharField(_(u'currency'), blank=True, max_length=3, choices=codelist_choices(CURRENCY)) provider_organisation = models.ForeignKey( 'Organisation', verbose_name=_(u'provider organisation'), related_name='providing_transactions', blank=True, null=True, on_delete=models.SET_NULL @@ -66,12 +69,12 @@ class Transaction(models.Model): _(u'receiver organisation activity id'), blank=True, max_length=50 ) recipient_country = ValidXMLCharField(_(u'recipient country'), blank=True, max_length=2, - choices=codelist_choices(Country)) + choices=codelist_choices(COUNTRY)) recipient_region = ValidXMLCharField( - _(u'recipient region'), blank=True, max_length=3, choices=codelist_choices(Region) + _(u'recipient region'), blank=True, max_length=3, choices=codelist_choices(REGION) ) recipient_region_vocabulary = ValidXMLCharField(_(u'recipient region vocabulary'), blank=True, max_length=1, - choices=codelist_choices(RegionVocabulary)) + choices=codelist_choices(REGION_VOCABULARY)) def __unicode__(self): return self.value @@ -109,11 +112,16 @@ class TransactionSector(models.Model): _(u'description'), blank=True, max_length=100, help_text=_(u'(max 100 characters)') ) vocabulary = ValidXMLCharField( - _(u'vocabulary'), blank=True, max_length=5, choices=codelist_choices(SectorVocabulary) + _(u'vocabulary'), blank=True, max_length=5, choices=codelist_choices(SECTOR_VOCABULARY) ) def iati_sector(self): - return codelist_value(Sector, self, 'code') + if self.code and (self.vocabulary == '1' or self.vocabulary == 'DAC'): + return codelist_value(Sector, self, 'code') + elif self.code and (self.vocabulary == '2' or self.vocabulary == 'DAC-3'): + return codelist_value(SectorCategory, self, 'code') + else: + return self.code def iati_vocabulary(self): return codelist_value(SectorVocabulary, self, 'vocabulary') diff --git a/akvo/utils.py b/akvo/utils.py index 4f75c49c4a..c927b69b5a 100644 --- a/akvo/utils.py +++ b/akvo/utils.py @@ -434,17 +434,23 @@ def filter_query_string(qs): '&'.join(['{}={}'.format(k, ''.join(v)) for (k, v) in q.items()])) -def codelist_choices(model, version=settings.IATI_VERSION): +def codelist_choices(codelist): """ - Based on a model from the codelists app and a version, returns a list of tuples with the available choices. - :param model: Model from codelists app - :param version: String of version (optional) + Based on a model from the codelists app, returns a list of tuples with the available choices. + + :param codelist: Codelist from codelists store :return: List of tuples with available choices, tuples in the form of (code, name) """ - try: - return [(cl.code, cl) for cl in model.objects.filter(version__code=version)] - except: - return [] + name_index = 0 + for index, header in enumerate(codelist[0]): + if header == 'name': + name_index = index + break + + if name_index > 0: + return [(cl[0], '%s - %s' % (cl[0], cl[name_index])) for cl in codelist[1:]] + else: + return [(cl[0], cl[name_index]) for cl in codelist[1:]] def codelist_value(model, instance, field, version=settings.IATI_VERSION): From a5ed2bb1b5124517c3226f631e295b1280bc61f2 Mon Sep 17 00:00:00 2001 From: gabemart Date: Tue, 31 Mar 2015 09:59:06 +0100 Subject: [PATCH 08/22] [#1380] correct scope issues in list view css --- akvo/rsr/static/rsr/v3/css/src/main.css | 44 +++---- akvo/rsr/static/rsr/v3/css/src/main.scss | 158 +++++++++++------------ 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/akvo/rsr/static/rsr/v3/css/src/main.css b/akvo/rsr/static/rsr/v3/css/src/main.css index 0504aefc18..dcaacb08c5 100755 --- a/akvo/rsr/static/rsr/v3/css/src/main.css +++ b/akvo/rsr/static/rsr/v3/css/src/main.css @@ -891,67 +891,67 @@ h4.detailedInfo { margin-top: 1em; } } .main-list.projects ul li .donateButton .totalBudgetLabel { width: initial; } -.main-list.projects.updates ul li { +.main-list.updates ul li { border: thin solid rgba(0, 167, 157, 0); -moz-transition: all 0.2s ease-in; -o-transition: all 0.2s ease-in; -webkit-transition: all 0.2s ease-in; transition: all 0.2s ease-in; } - .main-list.projects.updates ul li .projectTitle { + .main-list.updates ul li .projectTitle { color: #00aaff; } - .main-list.projects.updates ul li .projectTitle i { + .main-list.updates ul li .projectTitle i { font-size: 1.1em; color: #00aaff; } - .main-list.projects.updates ul li .projectTitle:hover { + .main-list.updates ul li .projectTitle:hover { color: #ff5500; } - .main-list.projects.updates ul li h1 a { + .main-list.updates ul li h1 a { color: #00a79d; } - .main-list.projects.updates ul li h1 a:hover { + .main-list.updates ul li h1 a:hover { color: #ff5500; } - .main-list.projects.updates ul li:nth-child(2n+1) { + .main-list.updates ul li:nth-child(2n+1) { background: rgba(0, 116, 109, 0.05); border: thin solid rgba(0, 167, 157, 0.1); } - .main-list.projects.updates ul li .projectLocation { + .main-list.updates ul li .projectLocation { color: rgba(32, 32, 36, 0.5); } - .main-list.projects.updates ul li:hover { + .main-list.updates ul li:hover { background: rgba(0, 167, 157, 0.1); border: thin solid rgba(0, 167, 157, 0.35); } -.main-list.projects.organisations ul li { +.main-list.organisations ul li { border: thin solid rgba(238, 49, 36, 0); -moz-transition: all 0.2s ease-in; -o-transition: all 0.2s ease-in; -webkit-transition: all 0.2s ease-in; transition: all 0.2s ease-in; } - .main-list.projects.organisations ul li i { + .main-list.organisations ul li i { font-size: 1.1em; } - .main-list.projects.organisations ul li .projectTitle { + .main-list.organisations ul li .projectTitle { display: block; margin: 0 0 3px 0; } - .main-list.projects.organisations ul li span.userFullName { + .main-list.organisations ul li span.userFullName { margin: 0 0 0px 0; } - .main-list.projects.organisations ul li .upDateTime { + .main-list.organisations ul li .upDateTime { margin-top: 10px; } - .main-list.projects.organisations ul li .additionalInfo div { + .main-list.organisations ul li .additionalInfo div { color: rgba(32, 32, 36, 0.5); } - .main-list.projects.organisations ul li .additionalInfo div span { + .main-list.organisations ul li .additionalInfo div span { margin-left: 5px; } - .main-list.projects.organisations ul li h1 a { + .main-list.organisations ul li h1 a { color: #ee3124; } - .main-list.projects.organisations ul li h1 a:hover { + .main-list.organisations ul li h1 a:hover { color: #ff5500; } - .main-list.projects.organisations ul li:nth-child(2n+1) { + .main-list.organisations ul li:nth-child(2n+1) { background: rgba(238, 49, 36, 0.05); border: thin solid rgba(238, 49, 36, 0.05); } - .main-list.projects.organisations ul li:hover { + .main-list.organisations ul li:hover { background: rgba(238, 49, 36, 0.1); border: thin solid rgba(238, 49, 36, 0.35); } - .main-list.projects.organisations ul li img { + .main-list.organisations ul li img { filter: gray; -webkit-filter: grayscale(100%); filter: url("data:image/svg+xml;utf8,#grayscale"); filter: grayscale(100%); transition: all 0.2s ease-in; } - .main-list.projects.organisations ul li:hover img { + .main-list.organisations ul li:hover img { filter: 0; -webkit-filter: grayscale(0%); filter: url(); diff --git a/akvo/rsr/static/rsr/v3/css/src/main.scss b/akvo/rsr/static/rsr/v3/css/src/main.scss index 1121f3c209..7b234c3822 100755 --- a/akvo/rsr/static/rsr/v3/css/src/main.scss +++ b/akvo/rsr/static/rsr/v3/css/src/main.scss @@ -1039,98 +1039,98 @@ h4.detailedInfo { } } } - &.updates { - ul { - li { - border: thin solid rgba($rsrGreen, 0); - @include transition(all 0.2s ease-in); - .orgName {} - .projectTitle { + } + &.updates { + ul { + li { + border: thin solid rgba($rsrGreen, 0); + @include transition(all 0.2s ease-in); + .orgName {} + .projectTitle { + color: rgba($anchorLink, 1); + i { + font-size: 1.1em; color: rgba($anchorLink, 1); - i { - font-size: 1.1em; - color: rgba($anchorLink, 1); - } + } + &:hover { + color: $anchorLinkHover; + } + } + h1 { + a { + color: $rsrGreen; &:hover { color: $anchorLinkHover; } } - h1 { - a { - color: $rsrGreen; - &:hover { - color: $anchorLinkHover; - } - } - } - &:nth-child(2n+1) { - background: darken(rgba($rsrGreen, 0.05), 10%); - border: thin solid rgba($rsrGreen, 0.1); - } - .projectLocation { - color: rgba($akvoBlack, 0.5); - } - &:hover { - background: darken(rgba($rsrGreen, 0.1), 0%); - border: thin solid rgba($rsrGreen, 0.35); - } - .excerpt {} - .excerpt {} } + &:nth-child(2n+1) { + background: darken(rgba($rsrGreen, 0.05), 10%); + border: thin solid rgba($rsrGreen, 0.1); + } + .projectLocation { + color: rgba($akvoBlack, 0.5); + } + &:hover { + background: darken(rgba($rsrGreen, 0.1), 0%); + border: thin solid rgba($rsrGreen, 0.35); + } + .excerpt {} + .excerpt {} } } - &.organisations { - ul { - li { - border: thin solid rgba($akvoTvRed, 0); - @include transition(all 0.2s ease-in); - i { - font-size: 1.1em; - } - .projectLocation {} - .projectTitle { - display: block; - margin: 0 0 3px 0; - } - span.userFullName { - margin: 0 0 0px 0; - } - .upDateTime { - margin-top: 10px; - } - .orgType {} - .additionalInfo { - div { - color: rgba($akvoBlack, 0.5); - span { - margin-left: 5px; - } + } + &.organisations { + ul { + li { + border: thin solid rgba($akvoTvRed, 0); + @include transition(all 0.2s ease-in); + i { + font-size: 1.1em; + } + .projectLocation {} + .projectTitle { + display: block; + margin: 0 0 3px 0; + } + span.userFullName { + margin: 0 0 0px 0; + } + .upDateTime { + margin-top: 10px; + } + .orgType {} + .additionalInfo { + div { + color: rgba($akvoBlack, 0.5); + span { + margin-left: 5px; } } - h1 { - a { - color: $akvoTvRed; - &:hover { - color: $anchorLinkHover; - } + } + h1 { + a { + color: $akvoTvRed; + &:hover { + color: $anchorLinkHover; } } - &:nth-child(2n+1) { - background: darken(rgba($akvoTvRed, 0.05), 0); - border: thin solid rgba($akvoTvRed, 0.05); - } - &:hover { - background: darken(rgba($akvoTvRed, 0.1), 0%); - border: thin solid rgba($akvoTvRed, 0.35); - } + } + &:nth-child(2n+1) { + background: darken(rgba($akvoTvRed, 0.05), 0); + border: thin solid rgba($akvoTvRed, 0.05); + } + &:hover { + background: darken(rgba($akvoTvRed, 0.1), 0%); + border: thin solid rgba($akvoTvRed, 0.35); + } + img { + @include bw; + transition: all 0.2s ease-in; + } + &:hover { img { - @include bw; - transition: all 0.2s ease-in; - } - &:hover { - img { - @include colour; - } + @include colour; } } } From 6aa5459076f9a38211f51d4c5f277f41880a6f51 Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Tue, 31 Mar 2015 11:42:55 +0200 Subject: [PATCH 09/22] [#1351] Add 'My IATI' section --- akvo/iati/elements/crs_add.py | 4 +- akvo/iati/elements/fss.py | 4 +- akvo/iati/iati_export.py | 18 ++-- akvo/rsr/admin.py | 8 +- akvo/rsr/forms.py | 67 ++++++++++++++- ...328_0054.py => 0002_auto_20150331_1006.py} | 38 +++++++++ akvo/rsr/models/__init__.py | 8 +- akvo/rsr/models/iati_export.py | 49 +++++++++++ akvo/rsr/models/organisation.py | 14 ++++ akvo/rsr/models/project.py | 4 +- akvo/rsr/models/sector.py | 2 +- akvo/rsr/models/transaction.py | 1 + akvo/rsr/signals.py | 27 ++++++ akvo/rsr/views/my_rsr.py | 58 ++++++++++++- akvo/templates/myrsr/my_iati.html | 84 +++++++++++++++++++ akvo/templates/myrsr/myrsr_base.html | 4 + akvo/templates/organisation_main.html | 15 +++- akvo/urls.py | 3 + 18 files changed, 383 insertions(+), 25 deletions(-) rename akvo/rsr/migrations/{0002_auto_20150328_0054.py => 0002_auto_20150331_1006.py} (98%) create mode 100644 akvo/rsr/models/iati_export.py create mode 100644 akvo/templates/myrsr/my_iati.html diff --git a/akvo/iati/elements/crs_add.py b/akvo/iati/elements/crs_add.py index 16820d2f78..f676ce1413 100644 --- a/akvo/iati/elements/crs_add.py +++ b/akvo/iati/elements/crs_add.py @@ -6,8 +6,6 @@ from lxml import etree -from akvo.rsr.models import CrsAdd - def crs_add(project): """ @@ -18,7 +16,7 @@ def crs_add(project): """ try: crs = project.crsadd - except CrsAdd.DoesNotExist: + except: return [] element = etree.Element("crs-add") diff --git a/akvo/iati/elements/fss.py b/akvo/iati/elements/fss.py index 1a86b4719c..4645e5cb71 100644 --- a/akvo/iati/elements/fss.py +++ b/akvo/iati/elements/fss.py @@ -6,8 +6,6 @@ from lxml import etree -from akvo.rsr.models import Fss - def fss(project): """ @@ -18,7 +16,7 @@ def fss(project): """ try: fss_object = project.fss - except Fss.DoesNotExist: + except: return [] element = etree.Element("fss") diff --git a/akvo/iati/iati_export.py b/akvo/iati/iati_export.py index e6178132fe..d8bece4c18 100644 --- a/akvo/iati/iati_export.py +++ b/akvo/iati/iati_export.py @@ -5,8 +5,10 @@ # For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. import elements +import os from datetime import datetime +from io import BytesIO from lxml import etree ELEMENTS = [ @@ -53,18 +55,24 @@ class IatiXML(object): - def print_file(self, file_path): + def save_file(self, org_id, filename): """ Export the etree to a file. - :param file_path: String of the file location + :param org: String of Organisation id + :param filename: String of the file name :return: File object """ - f = open(file_path, 'w') + media_root = '/var/akvo/rsr/mediaroot/' + directory = 'db/org/%s/iati/' % org_id + if not os.path.exists(media_root + directory): + os.makedirs(media_root + directory) + + f = open(media_root + directory + filename, 'w') f.write(etree.tostring(self.iati_activities, pretty_print=True)) f.close() - print "Done." - return f + + return directory + filename def add_project(self, project): """ diff --git a/akvo/rsr/admin.py b/akvo/rsr/admin.py index bd7b8adfce..1b60cb1b5c 100644 --- a/akvo/rsr/admin.py +++ b/akvo/rsr/admin.py @@ -69,10 +69,10 @@ class OrganisationAdmin(TimestampsAdminDisplayMixin, ObjectPermissionsModelAdmin # NOTE: The change_form.html template relies on the fieldsets to put the inline forms correctly. # If the fieldsets are changed, the template may need fixing too fieldsets = ( - (_(u'General information'), {'fields': ('name', 'long_name', 'partner_types', 'organisation_type', - 'new_organisation_type', 'logo', 'url', 'facebook', 'twitter', - 'linkedin', 'iati_org_id', 'language', 'content_owner', - 'allow_edit',)}), + (_(u'General information'), {'fields': ( + 'name', 'long_name', 'partner_types', 'organisation_type', 'new_organisation_type', + 'logo', 'url', 'facebook', 'twitter', 'linkedin', 'iati_org_id', 'public_iati_file', + 'language', 'content_owner', 'allow_edit',)}), (_(u'Contact information'), {'fields': ('phone', 'mobile', 'fax', 'contact_person', 'contact_email', ), }), (_(u'About the organisation'), {'fields': ('description', 'notes',)}), ) diff --git a/akvo/rsr/forms.py b/akvo/rsr/forms.py index 7efd14079c..8aff6deb0f 100644 --- a/akvo/rsr/forms.py +++ b/akvo/rsr/forms.py @@ -14,6 +14,7 @@ from django.contrib.sites.models import get_current_site from django.db.models import get_model from django.utils.translation import ugettext_lazy as _ +from django.utils.safestring import mark_safe from mollie.ideal.utils import get_mollie_banklist @@ -21,7 +22,7 @@ from urlparse import urlsplit, urlunsplit -from .models import Country, Invoice, Organisation, ProjectUpdate, ProjectUpdateLocation +from .models import Country, Invoice, Organisation, Project, ProjectUpdate, ProjectUpdateLocation from akvo import settings @@ -368,3 +369,67 @@ def clean(self): if cd['email'] != cd['email2']: raise forms.ValidationError(_('You must type the same email address each time!')) return cd + + +class SelectOrgForm(forms.Form): + """Form for selecting an organisation.""" + + def __init__(self, user, *args, **kwargs): + super(SelectOrgForm, self).__init__(*args, **kwargs) + + if user.is_superuser or user.is_admin: + organisations = Organisation.objects.all() + else: + organisations = user.employers.approved().organisations() + + self.fields['org'] = forms.ModelChoiceField( + queryset=organisations, + label='Select your organisation', + ) + + +class CustomLabelModelChoiceField(forms.ModelMultipleChoiceField): + def label_from_instance(self, obj): + checks = obj.check_mandatory_fields() + if checks[0]: + return mark_safe(u'%s' % obj.__unicode__()) + else: + label = obj.__unicode__() + " (edit project)" % str(obj.pk) + for check in checks[1]: + if check[0] == u'error': + label += u'
- %s' % check[1] + return mark_safe(u'%s' % label) + + + +class IatiExportForm(forms.ModelForm): + """Form for adding an entry to the IATI export model.""" + is_public = forms.BooleanField(required=False, label="Show IATI file on organisation page") + projects = CustomLabelModelChoiceField( + widget=forms.CheckboxSelectMultiple, + queryset=Project.objects.all(), + label="Select the projects included in the export:" + ) + + class Meta: + model = get_model('rsr', 'IatiExport') + fields = ('projects', 'is_public', ) + + def __init__(self, org=None, *args, **kwargs): + super(IatiExportForm, self).__init__(*args, **kwargs) + if org: + self.fields['projects'].queryset = org.reporting_projects.all() + + def save(self, reporting_organisation=None, user=None): + if reporting_organisation and user: + iati_export = super(IatiExportForm, self).save(commit=False) + iati_export.reporting_organisation = reporting_organisation + iati_export.user = user + iati_export.save() + self.save_m2m() + iati_export.save() + + return iati_export + else: + raise forms.ValidationError('Reporting organisation or user not found.') diff --git a/akvo/rsr/migrations/0002_auto_20150328_0054.py b/akvo/rsr/migrations/0002_auto_20150331_1006.py similarity index 98% rename from akvo/rsr/migrations/0002_auto_20150328_0054.py rename to akvo/rsr/migrations/0002_auto_20150331_1006.py index e72dd7ed91..5ca32f5b1a 100644 --- a/akvo/rsr/migrations/0002_auto_20150328_0054.py +++ b/akvo/rsr/migrations/0002_auto_20150331_1006.py @@ -2,7 +2,9 @@ from __future__ import unicode_literals from django.db import models, migrations +import akvo.rsr.models.iati_export import django.db.models.deletion +from django.conf import settings import akvo.rsr.fields import django.core.validators @@ -98,6 +100,26 @@ class Migration(migrations.Migration): }, bases=(models.Model,), ), + migrations.CreateModel( + name='IatiExport', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('created_at', models.DateTimeField(db_index=True, auto_now_add=True, null=True)), + ('last_modified_at', models.DateTimeField(db_index=True, auto_now=True, null=True)), + ('version', akvo.rsr.fields.ValidXMLCharField(default=b'2.01', max_length=4, verbose_name='version')), + ('status', models.PositiveSmallIntegerField(default=1, verbose_name='status')), + ('iati_file', models.FileField(upload_to=akvo.rsr.models.iati_export.file_path, verbose_name='IATI file', blank=True)), + ('is_public', models.BooleanField(default=True, verbose_name='public')), + ('projects', models.ManyToManyField(to='rsr.Project', verbose_name='projects')), + ('reporting_organisation', models.ForeignKey(related_name='iati_exports', verbose_name='reporting organisation', to='rsr.Organisation')), + ('user', models.ForeignKey(related_name='iati_exports', verbose_name='user', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'IATI export', + 'verbose_name_plural': 'IATI exports', + }, + bases=(models.Model,), + ), migrations.CreateModel( name='TransactionSector', fields=[ @@ -113,6 +135,10 @@ class Migration(migrations.Migration): }, bases=(models.Model,), ), + migrations.AlterUniqueTogether( + name='transactionsector', + unique_together=set([('project', 'vocabulary')]), + ), migrations.RemoveField( model_name='budgetitem', name='period_end_text', @@ -173,6 +199,12 @@ class Migration(migrations.Migration): model_name='transaction', name='transaction_type_text', ), + migrations.AddField( + model_name='organisation', + name='public_iati_file', + field=models.BooleanField(default=True, verbose_name='Show latest exported IATI file on organisation page.'), + preserve_default=True, + ), migrations.AddField( model_name='project', name='country_budget_vocabulary', @@ -293,6 +325,12 @@ class Migration(migrations.Migration): field=akvo.rsr.fields.ValidXMLCharField(blank=True, help_text='Select the geographical scope of the project.', max_length=2, verbose_name='project scope', choices=[('1', '1 - Global'), ('2', '2 - Regional'), ('3', '3 - Multi-national'), ('4', '4 - National'), ('5', '5 - Sub-national: Multi-first-level administrative areas'), ('6', '6 - Sub-national: Single first-level administrative area'), ('7', '7 - Sub-national: Single second-level administrative area'), ('8', '8 - Single location')]), preserve_default=True, ), + migrations.AlterField( + model_name='project', + name='sync_owner', + field=models.ForeignKey(related_name='reporting_projects', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='rsr.Organisation', help_text='Select the reporting organisation of the project.', null=True, verbose_name='reporting organisation'), + preserve_default=True, + ), migrations.AlterField( model_name='projectcondition', name='type', diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py index ae6ae0149a..1843d660e5 100644 --- a/akvo/rsr/models/__init__.py +++ b/akvo/rsr/models/__init__.py @@ -19,7 +19,7 @@ create_publishing_status, create_organisation_account, create_payment_gateway_selector, donation_completed, act_on_log_entry, employment_post_save, employment_pre_save, update_project_budget, - update_project_funding) + update_project_funding, create_iati_file) from .benchmark import Benchmark, Benchmarkname from .budget_item import BudgetItem, BudgetItemLabel, CountryBudgetItem @@ -30,6 +30,7 @@ from .focus_area import FocusArea from .fss import Fss, FssForecast from .goal import Goal +from .iati_export import IatiExport from .indicator import Indicator, IndicatorPeriod from .invoice import Invoice from .internal_organisation_id import InternalOrganisationID @@ -76,6 +77,7 @@ 'Fss', 'FssForecast', 'Goal', + 'IatiExport', 'Indicator', 'IndicatorPeriod', 'Invoice', @@ -255,6 +257,8 @@ rules.add_perm('rsr.add_employment', is_rsr_admin) rules.add_perm('rsr.change_employment', is_rsr_admin | is_org_admin | is_org_user_manager) +rules.add_perm('rsr.iati_management', is_rsr_admin | is_org_admin | is_org_project_editor) + rules.add_perm('rsr.user_management', is_rsr_admin | is_org_admin | is_org_user_manager) rules.add_perm('rsr.post_updates', is_rsr_admin | is_org_admin | is_org_user_manager | is_org_project_editor | is_org_user) @@ -290,3 +294,5 @@ post_delete.connect(update_project_funding, sender=Partnership) post_save.connect(create_api_key, sender=User) + +post_save.connect(create_iati_file, sender=IatiExport) diff --git a/akvo/rsr/models/iati_export.py b/akvo/rsr/models/iati_export.py new file mode 100644 index 0000000000..03bd00491d --- /dev/null +++ b/akvo/rsr/models/iati_export.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# Akvo RSR is covered by the GNU Affero General Public License. +# See more details in the license.txt file located at the root folder of the Akvo RSR module. +# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + + +from django.db import models +from django.conf import settings +from django.utils.translation import ugettext_lazy as _ + +from ..fields import ValidXMLCharField +from ..mixins import TimestampsMixin + + +def file_path(self, filename): + return 'db/organisation/%s/iati/%s' % (str(self.reporting_organisation.pk), filename) + + +STATUS_CODE = { + 1: u'pending', + 2: u'in progress', + 3: u'completed', + 4: u'cancelled' +} + +class IatiExport(TimestampsMixin, models.Model): + reporting_organisation = models.ForeignKey( + 'Organisation', verbose_name=u'reporting organisation', related_name='iati_exports' + ) + user = models.ForeignKey( + settings.AUTH_USER_MODEL, verbose_name=u'user', related_name='iati_exports' + ) + projects = models.ManyToManyField('Project', verbose_name=u'projects') + version = ValidXMLCharField(_(u'version'), max_length=4, default='2.01') + status = models.PositiveSmallIntegerField(_(u'status'), default=1) + iati_file = models.FileField(_(u'IATI file'), blank=True, upload_to=file_path) + is_public = models.BooleanField(_(u'public'), default=True) + + class Meta: + app_label = 'rsr' + verbose_name = _(u'IATI export') + verbose_name_plural = _(u'IATI exports') + + def show_status(self): + if not self.status in STATUS_CODE.keys(): + return u'unknown status' + else: + return STATUS_CODE[int(self.status)] diff --git a/akvo/rsr/models/organisation.py b/akvo/rsr/models/organisation.py index 5815dc6ed0..14d385adf5 100644 --- a/akvo/rsr/models/organisation.py +++ b/akvo/rsr/models/organisation.py @@ -133,6 +133,9 @@ def org_type_from_iati_type(cls, iati_type): ), default=True ) + public_iati_file = models.BooleanField( + _(u'Show latest exported IATI file on organisation page.'), default=True + ) objects = QuerySetManager() @@ -276,6 +279,17 @@ def countries_where_active(self): projectlocation__project__publishingstatus__status=PublishingStatus.STATUS_PUBLISHED ).distinct() + def iati_file(self): + """ + Looks up the latest public IATI file of this organisation. + + :return: String of IATI file or None + """ + for export in self.iati_exports.all().order_by('-last_modified_at'): + if export.is_public and export.status == 3 and export.iati_file: + return export.iati_file + return None + # New API def euros_pledged(self): diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py index 086a031282..0e64e2b67f 100644 --- a/akvo/rsr/models/project.py +++ b/akvo/rsr/models/project.py @@ -204,8 +204,8 @@ class Project(TimestampsMixin, models.Model): # synced projects sync_owner = models.ForeignKey( - 'Organisation', verbose_name=_(u'reporting organisation'), null=True, blank=True, on_delete=models.SET_NULL, - help_text=_(u'Select the reporting organisation of the project.') + 'Organisation', verbose_name=_(u'reporting organisation'), related_name='reporting_projects', + null=True, blank=True, on_delete=models.SET_NULL, help_text=_(u'Select the reporting organisation of the project.') ) sync_owner_secondary_reporter = models.NullBooleanField( _(u'secondary reporter'), diff --git a/akvo/rsr/models/sector.py b/akvo/rsr/models/sector.py index f428c72343..abb5f489aa 100644 --- a/akvo/rsr/models/sector.py +++ b/akvo/rsr/models/sector.py @@ -40,7 +40,7 @@ class Sector(models.Model): ) def __unicode__(self): - return self.iati_sector() + return self.sector_code def iati_sector_codes(self): if self.sector_code and (self.vocabulary == '1' or self.vocabulary == 'DAC'): diff --git a/akvo/rsr/models/transaction.py b/akvo/rsr/models/transaction.py index 22a3f07e68..40de39c0aa 100644 --- a/akvo/rsr/models/transaction.py +++ b/akvo/rsr/models/transaction.py @@ -130,3 +130,4 @@ class Meta: app_label = 'rsr' verbose_name = _(u'transaction sector') verbose_name_plural = _(u'transaction sectors') + unique_together = ('project', 'vocabulary') diff --git a/akvo/rsr/signals.py b/akvo/rsr/signals.py index 28579af6e9..9136f7c218 100644 --- a/akvo/rsr/signals.py +++ b/akvo/rsr/signals.py @@ -18,10 +18,12 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.files.uploadedfile import InMemoryUploadedFile from django.db.models import get_model, ImageField +from django.db.models.signals import post_save from sorl.thumbnail import ImageField from akvo.utils import send_donation_confirmation_emails, rsr_send_mail, rsr_send_mail_to_users +from akvo.iati.iati_export import IatiXML def create_publishing_status(sender, **kwargs): @@ -281,3 +283,28 @@ def update_project_funding(sender, **kwargs): except ObjectDoesNotExist: # this happens when a project is deleted, and thus any invoices linked to it go the same way. pass + + +def create_iati_file(sender, **kwargs): + """ + Create an IATI XML file when an entry in the iati_export table is saved, with projects. + + :param sender: IatiExport model + """ + iati_export = kwargs.get("instance", None) + projects = iati_export.projects.all() + if iati_export and projects: + post_save.disconnect(create_iati_file, sender=sender) + try: + iati_export.status = 2 + iati_export.save() + iati_xml = IatiXML(projects) + iati_file = iati_xml.save_file(str(iati_export.reporting_organisation.pk), + datetime.utcnow().strftime("%Y%m%d-%H%M%S") + '.xml') + iati_export.iati_file = iati_file + iati_export.status = 3 + iati_export.save() + except: + iati_export.status = 4 + iati_export.save() + post_save.connect(create_iati_file, sender=sender) diff --git a/akvo/rsr/views/my_rsr.py b/akvo/rsr/views/my_rsr.py index 2cbf9a50f8..d6397a2c7b 100644 --- a/akvo/rsr/views/my_rsr.py +++ b/akvo/rsr/views/my_rsr.py @@ -8,9 +8,10 @@ import json -from ..forms import PasswordForm, ProfileForm, UserOrganisationForm, UserAvatarForm +from ..forms import (PasswordForm, ProfileForm, UserOrganisationForm, UserAvatarForm, + SelectOrgForm, IatiExportForm) from ...utils import pagination -from ..models import Country, Organisation +from ..models import Country, Organisation, Project from django.contrib.auth import get_user_model from django.contrib.auth.decorators import login_required @@ -97,6 +98,59 @@ def my_projects(request): return render(request, 'myrsr/my_projects.html', context) + +@login_required +def my_iati(request): + user = request.user + + if not user.has_perm('rsr.iati_management'): + raise PermissionDenied + + org = request.GET.get('org') + selected_org, iati_exports, export_added, project_count = None, None, False, 0 + + select_org_form = SelectOrgForm(user) + iati_export_form = None + + if not org and not (user.is_superuser or user.is_admin) \ + and user.approved_organisations().count() == 1: + selected_org = user.approved_organisations()[0] + + elif org: + try: + selected_org = Organisation.objects.get(pk=int(org)) + except Organisation.DoesNotExist: + raise PermissionDenied + if not (user.is_superuser or user.is_admin) \ + and not user.has_perm('rsr.change_organisation', selected_org): + raise PermissionDenied + + if selected_org: + iati_exports = selected_org.iati_exports.all().order_by('-last_modified_at') + project_count = selected_org.reporting_projects.all().count() + initial = { + 'is_public': True, + 'projects': [p.pk for p in selected_org.reporting_projects.all()] + } + iati_export_form = IatiExportForm(initial=initial, org=selected_org) + + if request.method == 'POST': + iati_export_form = IatiExportForm(selected_org, request.POST) + if iati_export_form.is_valid(): + iati_export_form.save(reporting_organisation=selected_org, user=user) + export_added = True + + context = { + 'select_org_form': select_org_form, + 'iati_export_form': iati_export_form, + 'selected_org': selected_org, + 'exports': iati_exports, + 'export_added': export_added, + 'project_count': project_count, + } + + return render(request, 'myrsr/my_iati.html', context) + @login_required def user_management(request): user = request.user diff --git a/akvo/templates/myrsr/my_iati.html b/akvo/templates/myrsr/my_iati.html new file mode 100644 index 0000000000..b1b81f0d64 --- /dev/null +++ b/akvo/templates/myrsr/my_iati.html @@ -0,0 +1,84 @@ +{% extends "myrsr/myrsr_base.html" %} + +{% load bootstrap3 compressed i18n rules %} + +{% block title %}{% trans 'MyRSR - My IATI' %}{% endblock %} + +{% block head %} +{{block.super}} + +{% endblock head %} + +{% block myrsr_main %} +

{% trans "My IATI" %}{% if selected_org %} {% trans "for" %} {{selected_org.long_name}}{% endif %}

+
+ {% if export_added %} + + {% endif %} + {% trans 'On this page it is possible to export an IATI file of the projects of your organisation or view previously exported files. ' %} + {% if not selected_org %} + {% trans 'Since your account is connected to multiple organisations, please select an organisation first.' %} +

+

+ {% for field in select_org_form %} + {% bootstrap_field field %} + {% endfor %} + {% buttons %} + + {% endbuttons %} +
+

+ {% elif project_count > 0 %} +

+

+ {% csrf_token %} + {% for field in iati_export_form %} + {% bootstrap_field field %} + {% endfor %} + {% buttons %} + + {% endbuttons %} +
+

+ {% else %} +

+

+ {% trans "Your organisation does not report any projects yet. " %} + {% trans "Set your organisation to reporting organisation of a project to create an IATI file for the project." %}
+ {% trans "Go to the projects admin" %} {% trans "here" %}. +

+ {% endif %} +
+ {% if exports %} +
+

{% trans 'Existing IATI export' %}{{exports.count|pluralize}}

+
    + {% for export in exports %} +
  • + {{export.last_modified_at|date:"d-M-Y"}}: + {% if export.iati_file %} + {% trans 'View IATI file' %} + ({{export.projects.count}} project{{export.projects.count|pluralize}}) + {% else %} + {% trans 'No IATI file' %} ({{export.show_status}}) + {% endif %} +
  • + {% endfor %} +
+
+ {% endif %} +{% endblock %} diff --git a/akvo/templates/myrsr/myrsr_base.html b/akvo/templates/myrsr/myrsr_base.html index c0ac4b886f..1d8f5f2735 100644 --- a/akvo/templates/myrsr/myrsr_base.html +++ b/akvo/templates/myrsr/myrsr_base.html @@ -14,6 +14,10 @@
  • My details
  • My updates
  • My projects
  • + {% has_perm 'rsr.iati_management' user as can_manage_iati %} + {% if can_manage_iati %} +
  • {% trans "My IATI" %}
  • + {% endif %} {% has_perm 'rsr.change_employment' user as can_change_employments %} {% if can_change_employments %}
  • User management
  • diff --git a/akvo/templates/organisation_main.html b/akvo/templates/organisation_main.html index 9da7caee74..c9a7bcaf66 100644 --- a/akvo/templates/organisation_main.html +++ b/akvo/templates/organisation_main.html @@ -56,7 +56,7 @@

    Details

    -

    Contact information

    +

    {% trans 'Contact information' %}

    • @@ -69,9 +69,18 @@

      Contact information

      {{organisation.phone}}

      {% endif %}
    • - {% endif %} -
    + {% endif %} + + {% if organisation.iati_file and organisation.public_iati_file %} +

    {% trans 'IATI file' %}

    + + + {% endif %} diff --git a/akvo/urls.py b/akvo/urls.py index a524ecf994..46ab097842 100644 --- a/akvo/urls.py +++ b/akvo/urls.py @@ -107,6 +107,9 @@ url(r'^myrsr/projects/$', 'akvo.rsr.views.my_rsr.my_projects', name='my_projects'), + url(r'^myrsr/iati/$', + 'akvo.rsr.views.my_rsr.my_iati', name='my_iati'), + url(r'^myrsr/user_management/$', 'akvo.rsr.views.my_rsr.user_management', name='user_management'), From cfc5eed0ddec0b5d5bed7e965d6c1402dbad70ae Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Tue, 31 Mar 2015 13:10:07 +0200 Subject: [PATCH 10/22] [#809] Seperated tests in different files --- akvo/rsr/middleware2.py | 34 ++++++++++++++++++ akvo/rsr/tests/__init__.py | 0 akvo/rsr/tests/models/__init__.py | 0 akvo/rsr/tests/models/test_benchmark.py | 35 +++++++++++++++++++ akvo/rsr/tests/pages/__init__.py | 0 .../pages/test_homepage.py} | 31 +++++----------- akvo/rsr/tests/test_middleware.py | 35 +++++++++++++++++++ akvo/rsr/views/project.py | 2 ++ 8 files changed, 114 insertions(+), 23 deletions(-) create mode 100644 akvo/rsr/middleware2.py create mode 100644 akvo/rsr/tests/__init__.py create mode 100644 akvo/rsr/tests/models/__init__.py create mode 100644 akvo/rsr/tests/models/test_benchmark.py create mode 100644 akvo/rsr/tests/pages/__init__.py rename akvo/rsr/{tests.py => tests/pages/test_homepage.py} (61%) create mode 100644 akvo/rsr/tests/test_middleware.py diff --git a/akvo/rsr/middleware2.py b/akvo/rsr/middleware2.py new file mode 100644 index 0000000000..04a048cd4a --- /dev/null +++ b/akvo/rsr/middleware2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +""" +Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the +Akvo RSR module. For additional details on the GNU license please see +< http://www.gnu.org/licenses/agpl.html >. +""" + + +def get_domain(request): + """Get domain from request.""" + original_domain = request.get_host().split(":")[0] + if original_domain == "rsr.akvo.org": + domain = original_domain + else: + domain_parts = original_domain.split(".")[-4:] + domain = ".".join(domain_parts) + return domain + + +class ReallySimpleRouterMiddleware(object): + + """Simple test for middleware testing.""" + + def process_request(self, request, cname_domain=False, rsr_page=None): + """Route on request.""" + domain = get_domain(request) + print "Domain: {}".format(domain) + return None + + def process_response(self, request, response): + """Route on response.""" + return None diff --git a/akvo/rsr/tests/__init__.py b/akvo/rsr/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/akvo/rsr/tests/models/__init__.py b/akvo/rsr/tests/models/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/akvo/rsr/tests/models/test_benchmark.py b/akvo/rsr/tests/models/test_benchmark.py new file mode 100644 index 0000000000..c779af9a01 --- /dev/null +++ b/akvo/rsr/tests/models/test_benchmark.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +""" +Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.test import TestCase +from akvo.rsr.models import Benchmarkname + + +class BenchmarknameTestCase(TestCase): + + """Tests the Benchmarkname model.""" + + def setUp(self): + """Create two benchmarkname objects.""" + # Create test objects + Benchmarkname.objects.create(name="Benchmarkname1") + Benchmarkname.objects.create(name="Benchmarkname2", order=2) + # Store for later use + self.bn1 = Benchmarkname.objects.get(name="Benchmarkname1") + self.bn2 = Benchmarkname.objects.get(name="Benchmarkname2") + + def test_name(self): + """Test the name & the unicode method.""" + self.assertEqual(self.bn1.name, "Benchmarkname1") + self.assertEqual("{}".format(self.bn2), "Benchmarkname2") + + def test_order(self): + """Test the order field.""" + self.assertEqual(self.bn1.order, 0) + self.assertEqual(self.bn2.order, 2) diff --git a/akvo/rsr/tests/pages/__init__.py b/akvo/rsr/tests/pages/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/akvo/rsr/tests.py b/akvo/rsr/tests/pages/test_homepage.py similarity index 61% rename from akvo/rsr/tests.py rename to akvo/rsr/tests/pages/test_homepage.py index 2316e53e05..dec1f3776d 100644 --- a/akvo/rsr/tests.py +++ b/akvo/rsr/tests/pages/test_homepage.py @@ -2,32 +2,12 @@ """Akvo RSR is covered by the GNU Affero General Public License. -See more details in the license.txt file located at the root folder of the -Akvo RSR module. For additional details on the GNU license please -see < http://www.gnu.org/licenses/agpl.html >. +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ from django.contrib.sites.models import Site from django.test import Client, TestCase -from akvo.rsr.models import Benchmarkname - - -class BenchmarknameTestCase(TestCase): - def setUp(self): - # Create test objects - Benchmarkname.objects.create(name="Benchmarkname1") - Benchmarkname.objects.create(name="Benchmarkname2", order=2) - # Store for later use - self.bn1 = Benchmarkname.objects.get(name="Benchmarkname1") - self.bn2 = Benchmarkname.objects.get(name="Benchmarkname2") - - def test_name(self): - self.assertEqual(self.bn1.name, "Benchmarkname1") - self.assertEqual("{}".format(self.bn2), "Benchmarkname2") - - def test_order(self): - self.assertEqual(self.bn1.order, 0) - self.assertEqual(self.bn2.order, 2) # class notFoundPageTestCase(TestCase): @@ -43,14 +23,19 @@ def test_order(self): class homePageTestCase(TestCase): + + """Make sure requests to the home page returns as expected.""" + def setUp(self): + """Make sure we have a site object and config settings.""" site, created = Site.objects.get_or_create(domain="localdev.akvo.org", - name="localdev") + name="localdev") with self.settings(SITE_ID=site.id): c = Client() self.resp = c.get('/') def test_redirect(self): + """Test that we get a redirect (http 302) on the home page.""" self.assertEqual(self.resp.status_code, 302) diff --git a/akvo/rsr/tests/test_middleware.py b/akvo/rsr/tests/test_middleware.py new file mode 100644 index 0000000000..2cdfa62258 --- /dev/null +++ b/akvo/rsr/tests/test_middleware.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the +Akvo RSR module. For additional details on the GNU license please +see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.test import TestCase +from django.test.client import RequestFactory +from akvo.rsr.middleware2 import get_domain, ReallySimpleRouterMiddleware + + +class PagesRouterMiddlewareTestCase(TestCase): + + """Testing the routing mechanism.""" + + def setUp(self): + """Setup.""" + self.factory = RequestFactory() + self.mw = ReallySimpleRouterMiddleware() + self.req0 = self.factory.get('/') + self.req1 = self.factory.get('/', {}, HTTP_HOST='rsr.akvo.org') + self.req2 = self.factory.get('/', {}, HTTP_HOST='rsr.localdev.akvo.org') + + def test_get_domain(self): + """.""" + self.assertEqual(get_domain(self.req0), "rsr.akvo.org") + self.assertEqual(get_domain(self.req1), "rsr.akvo.org") + self.assertEqual(get_domain(self.req2), "rsr.localdev.akvo.org") + + def test_process_request(self): + """Test inbound.""" + self.assertEqual(None, None) diff --git a/akvo/rsr/views/project.py b/akvo/rsr/views/project.py index caa2b7d982..718266bab8 100644 --- a/akvo/rsr/views/project.py +++ b/akvo/rsr/views/project.py @@ -32,8 +32,10 @@ def _all_projects(): return Project.objects.published().select_related().prefetch_related( 'partners').order_by('-id') + def _page_projects(page): """Dig out the list of projects to use. + First get a list based on page settings (orgs or all projects). Then apply keywords filtering / exclusion. """ From e79bfcfa513db6eb2580b4c9bfdbc4ab35f0b5ac Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Wed, 1 Apr 2015 14:44:27 +0200 Subject: [PATCH 11/22] [#809] Rewrote the routing middleware + tests Tests needs to be cleaned up, probably to different test cases per accessed host. Updated Piwik template tag to reflect changes. --- akvo/rsr/context_processors.py | 4 +- akvo/rsr/middleware.py | 252 ++++---------------------- akvo/rsr/middleware2.py | 34 ---- akvo/rsr/middleware_old.py | 269 ++++++++++++++++++++++++++++ akvo/rsr/models/partner_site.py | 136 ++++++++------ akvo/rsr/templatetags/piwik_tags.py | 40 +++-- akvo/rsr/tests/test_middleware.py | 148 +++++++++++++-- akvo/settings/10-base.conf | 4 +- akvo/settings/66_local.template | 2 +- akvo/templates/base.html | 3 +- 10 files changed, 549 insertions(+), 343 deletions(-) delete mode 100644 akvo/rsr/middleware2.py create mode 100644 akvo/rsr/middleware_old.py diff --git a/akvo/rsr/context_processors.py b/akvo/rsr/context_processors.py index 819d2a5f54..943807e49c 100644 --- a/akvo/rsr/context_processors.py +++ b/akvo/rsr/context_processors.py @@ -53,8 +53,8 @@ def extra_pages_context(request): 'return_url': page.return_url, 'return_url_text': page.custom_return_url_text, 'stylesheet': page.stylesheet, - 'akvoapp_root_url': request.akvoapp_root_url, - 'domain_url': request.domain_url, + 'akvoapp_root_url': '//{}'.format(settings.AKVOAPP_DOMAIN), + 'domain_url': '//{}'.format(settings.RSR_DOMAIN), 'no_facebook': not page.facebook_button, 'facebook_app_id': page.facebook_app_id, 'no_twitter': not page.twitter_button, diff --git a/akvo/rsr/middleware.py b/akvo/rsr/middleware.py index 8440d5cc52..72c510a9a4 100644 --- a/akvo/rsr/middleware.py +++ b/akvo/rsr/middleware.py @@ -7,251 +7,62 @@ < http://www.gnu.org/licenses/agpl.html >. """ +import logging from django.conf import settings -from django.contrib.sites.models import Site -from django.core.urlresolvers import (LocaleRegexURLResolver, is_valid_path, - get_resolver) -from django.http import HttpResponseRedirect -from django.middleware.locale import LocaleMiddleware +from django.db.models import Q from django.shortcuts import redirect -from django.utils import translation -from django.utils.cache import patch_vary_headers from akvo.rsr.context_processors import extra_context - from akvo.rsr.models import PartnerSite -import logging -import re - - -__all__ = ["PagesLocaleMiddleware", - "PagesRouterMiddleware", - "get_domain", - "get_or_create_site", - "is_rsr_instance", - "make_tls_property"] - - -def make_tls_property(default=None): - """Create a class-wide instance property with a thread-specific value.""" - class TLSProperty(object): - def __init__(self): - from threading import local - self.local = local() - def __get__(self, instance, cls): - if not instance: - return self - return self.value +def _is_rsr_host(hostname): + """Predicate function that checks if request is made to the RSR_DOMAIN.""" + rsr_hosts = ['127.0.0.1', 'localhost', settings.RSR_DOMAIN] + return True if hostname in rsr_hosts else False - def __set__(self, instance, value): - self.value = value - def _get_value(self): - return getattr(self.local, 'value', default) +def _partner_site(netloc): + """From a netloc return PartnerSite or raise a DoesNotExist.""" + return PartnerSite.objects.get( + Q(hostname=PartnerSite.yank_hostname(netloc)) | Q(cname=netloc) + ) - def _set_value(self, value): - self.local.value = value - value = property(_get_value, _set_value) - return TLSProperty() +class HostDispatchMiddleware(object): + """Simple test for middleware testing.""" -def _patch_setattr(obj): - """Allow changes to tls property objects. - - Without this patch the following is not possible:: + # def process_request(self, request, cname_domain=False, rsr_page=None): + def process_request(self, request): + """Route on request.""" + request.rsr_page = None + host = request.get_host() - settings.SITE_ID = 1 - settings.SITE_ID = 42 - assert settings.SITE_ID == 42 # this fails without this patch - """ - old_setattr = obj.__setattr__ + # Do nothing if called on "normal" RSR host + if _is_rsr_host(host): + return None - def wrap_setattr(self, name, value): + # Check if site exists try: - getattr(self.__class__, name).value = value - except AttributeError: - old_setattr(name, value) - obj.__class__.__setattr__ = wrap_setattr - - -_patch_setattr(settings) - -DEFAULT_SITE_ID = getattr(settings, "SITE_ID", None) -DEFAULT_PARTNER_SITE = getattr(settings, "PARTNER_SITE", None) - -settings.__class__.SITE_ID = make_tls_property(DEFAULT_SITE_ID) -settings.__class__.PARTNER_SITE = make_tls_property(DEFAULT_PARTNER_SITE) - -RSR_SITE_REGEXPS = map(re.compile, settings.RSR_SITE_REGEXPS) -PARTNER_SITE_REGEXPS = map(re.compile, settings.PARTNER_SITE_REGEXPS) - - -def get_domain(request): - """Get domain from request.""" - original_domain = request.get_host().split(":")[0] - if original_domain == "rsr.akvo.org": - domain = original_domain - else: - domain_parts = original_domain.split(".")[-4:] - domain = ".".join(domain_parts) - return domain - - -def is_rsr_instance(hostname): - """.""" - return any([site.search(hostname) for site in RSR_SITE_REGEXPS]) - - -def is_rsr_page_instance(hostname): - """.""" - return any([site.search(hostname) for site in PARTNER_SITE_REGEXPS]) - - -def get_or_create_site(domain): - """Make sure we have a matching SITE object. - - As a result of an issue(1) we need to ensure that we don't - delete the fixture should we find duplicates - There is no guaranteed ordering(2) we should explicitly order them in such - a way that the fixture would appear first, i.e. by ensuring 'ORDER BY id - ASC'. - - (1) https://github.com/akvo/akvo-provisioning/issues/29 - (2) http://stackoverflow.com/questions/7163640/ - what-is-the-default-order-of-a-list-returned-from-a-django-filter-call - """ - if domain.startswith('www.'): - domain = domain[4:] - - sites = Site.objects.filter(domain=domain).order_by('id') - if sites.count() >= 1: - site, duplicates = sites[0], sites[1:] - if duplicates.count(): - for duplicate in duplicates: - duplicate.delete() - else: - site = Site(domain=domain, name=domain) - site.save() - return site - + site = _partner_site(host) + except PartnerSite.DoesNotExist: + return redirect(settings.RSR_DOMAIN) -class PagesRouterMiddleware(object): + # Check if site is enabled + if not site.enabled: + return redirect(settings.RSR_DOMAIN) - """Dispatch to normal or RSR page based on request domain.""" - - def process_request(self, request, cname_domain=False, rsr_page=None): - """.""" - domain = get_domain(request) - - if is_rsr_instance(domain): - request.rsr_page = None - - elif is_rsr_page_instance(domain): - try: - domain_parts = domain.split(".") - hostname = domain_parts[0] - if hostname == 'www': - hostname = domain_parts[1] - - rsr_page = PartnerSite.objects.get(hostname=hostname) - except: - pass - if rsr_page is None or not rsr_page.enabled: - return redirect("http://rsr.akvo.org") - - else: # Probably an RSR Page instance on partner-nominated domain - cname_domain = True - try: - rsr_page = PartnerSite.objects.get(cname=domain) - except: - return redirect("http://rsr.akvo.org") - - if rsr_page is not None and rsr_page.enabled: - if cname_domain: - rsr_page_domain = getattr( - settings, 'AKVOAPP_DOMAIN', 'akvoapp.org') - else: - rsr_page_domain = ".".join(domain.split(".")[1:]) - request.rsr_page = settings.RSR_PAGE = rsr_page - request.app_domain = ".".join( - (rsr_page.hostname, rsr_page_domain) - ) - request.akvoapp_root_url = "http://%s" % request.app_domain - request.organisation_id = rsr_page.organisation.id - request.rsr_page = rsr_page - request.default_language = rsr_page.default_language - - request.domain_url = "http://%s" % settings.RSR_DOMAIN - site = get_or_create_site(domain) - settings.SITE_ID = site.id + # Set site to request object + request.rsr_page = site return None -class PagesLocaleMiddleware(LocaleMiddleware): - - """ - Partner sites aware version of Django's LocaleMiddleware. - - Since we swap out the root urlconf for a partner sites specific one, and - the original Django LocaleMiddleware didn't like that. - """ - - def process_request(self, request): - """.""" - check_path = self.is_language_prefix_patterns_used(request) - language = translation.get_language_from_request( - request, check_path=check_path) - translation.activate(language) - request.LANGUAGE_CODE = translation.get_language() - - def process_response(self, request, response): - """.""" - # First set the default language, this will be used if there is none - # in the path - default_language = getattr(request, 'default_language', '') - if default_language: - translation.activate(default_language) - - language = translation.get_language() - if (response.status_code == 404 and - not translation.get_language_from_path(request.path_info) and - self.is_language_prefix_patterns_used(request)): - language_path = '/%s%s' % (language, request.path_info) - if settings.APPEND_SLASH and not language_path.endswith('/'): - language_path += '/' - - if is_valid_path(language_path, settings.ROOT_URLCONF): - language_url = "%s://%s/%s%s" % ( - request.is_secure() and 'https' or 'http', - request.get_host(), language, request.get_full_path()) - return HttpResponseRedirect(language_url) - translation.deactivate() - - patch_vary_headers(response, ('Accept-Language',)) - if 'Content-Language' not in response: - response['Content-Language'] = language - return response - - def is_language_prefix_patterns_used(self, request): - """Return True if languge prefix is used. - - Return `True` if the `LocaleRegexURLResolver` is used - at root level of the urlpatterns, else it returns `False`. - """ - urlconf = getattr(request, 'urlconf', None) - for url_pattern in get_resolver(urlconf).url_patterns: - if isinstance(url_pattern, LocaleRegexURLResolver): - return True - return False - - class ExceptionLoggingMiddleware(object): """Used to log exceptions on production systems.""" def process_exception(self, request, exception): + """.""" logging.exception('Exception handling request for ' + request.path) @@ -260,6 +71,7 @@ class RSRVersionHeaderMiddleware(object): """Add a response header with RSR version info.""" def process_response(self, request, response): + """.""" context = extra_context(request) response['X-RSR-Version'] = "tag={}, commit={}, branch={}".format( diff --git a/akvo/rsr/middleware2.py b/akvo/rsr/middleware2.py deleted file mode 100644 index 04a048cd4a..0000000000 --- a/akvo/rsr/middleware2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Akvo RSR is covered by the GNU Affero General Public License. - -See more details in the license.txt file located at the root folder of the -Akvo RSR module. For additional details on the GNU license please see -< http://www.gnu.org/licenses/agpl.html >. -""" - - -def get_domain(request): - """Get domain from request.""" - original_domain = request.get_host().split(":")[0] - if original_domain == "rsr.akvo.org": - domain = original_domain - else: - domain_parts = original_domain.split(".")[-4:] - domain = ".".join(domain_parts) - return domain - - -class ReallySimpleRouterMiddleware(object): - - """Simple test for middleware testing.""" - - def process_request(self, request, cname_domain=False, rsr_page=None): - """Route on request.""" - domain = get_domain(request) - print "Domain: {}".format(domain) - return None - - def process_response(self, request, response): - """Route on response.""" - return None diff --git a/akvo/rsr/middleware_old.py b/akvo/rsr/middleware_old.py new file mode 100644 index 0000000000..8440d5cc52 --- /dev/null +++ b/akvo/rsr/middleware_old.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +""" +Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the +Akvo RSR module. For additional details on the GNU license please see +< http://www.gnu.org/licenses/agpl.html >. +""" + +from django.conf import settings +from django.contrib.sites.models import Site +from django.core.urlresolvers import (LocaleRegexURLResolver, is_valid_path, + get_resolver) +from django.http import HttpResponseRedirect +from django.middleware.locale import LocaleMiddleware +from django.shortcuts import redirect +from django.utils import translation +from django.utils.cache import patch_vary_headers +from akvo.rsr.context_processors import extra_context + +from akvo.rsr.models import PartnerSite + +import logging +import re + + +__all__ = ["PagesLocaleMiddleware", + "PagesRouterMiddleware", + "get_domain", + "get_or_create_site", + "is_rsr_instance", + "make_tls_property"] + + +def make_tls_property(default=None): + """Create a class-wide instance property with a thread-specific value.""" + class TLSProperty(object): + def __init__(self): + from threading import local + self.local = local() + + def __get__(self, instance, cls): + if not instance: + return self + return self.value + + def __set__(self, instance, value): + self.value = value + + def _get_value(self): + return getattr(self.local, 'value', default) + + def _set_value(self, value): + self.local.value = value + value = property(_get_value, _set_value) + + return TLSProperty() + + +def _patch_setattr(obj): + """Allow changes to tls property objects. + + Without this patch the following is not possible:: + + settings.SITE_ID = 1 + settings.SITE_ID = 42 + assert settings.SITE_ID == 42 # this fails without this patch + """ + old_setattr = obj.__setattr__ + + def wrap_setattr(self, name, value): + try: + getattr(self.__class__, name).value = value + except AttributeError: + old_setattr(name, value) + obj.__class__.__setattr__ = wrap_setattr + + +_patch_setattr(settings) + +DEFAULT_SITE_ID = getattr(settings, "SITE_ID", None) +DEFAULT_PARTNER_SITE = getattr(settings, "PARTNER_SITE", None) + +settings.__class__.SITE_ID = make_tls_property(DEFAULT_SITE_ID) +settings.__class__.PARTNER_SITE = make_tls_property(DEFAULT_PARTNER_SITE) + +RSR_SITE_REGEXPS = map(re.compile, settings.RSR_SITE_REGEXPS) +PARTNER_SITE_REGEXPS = map(re.compile, settings.PARTNER_SITE_REGEXPS) + + +def get_domain(request): + """Get domain from request.""" + original_domain = request.get_host().split(":")[0] + if original_domain == "rsr.akvo.org": + domain = original_domain + else: + domain_parts = original_domain.split(".")[-4:] + domain = ".".join(domain_parts) + return domain + + +def is_rsr_instance(hostname): + """.""" + return any([site.search(hostname) for site in RSR_SITE_REGEXPS]) + + +def is_rsr_page_instance(hostname): + """.""" + return any([site.search(hostname) for site in PARTNER_SITE_REGEXPS]) + + +def get_or_create_site(domain): + """Make sure we have a matching SITE object. + + As a result of an issue(1) we need to ensure that we don't + delete the fixture should we find duplicates + There is no guaranteed ordering(2) we should explicitly order them in such + a way that the fixture would appear first, i.e. by ensuring 'ORDER BY id + ASC'. + + (1) https://github.com/akvo/akvo-provisioning/issues/29 + (2) http://stackoverflow.com/questions/7163640/ + what-is-the-default-order-of-a-list-returned-from-a-django-filter-call + """ + if domain.startswith('www.'): + domain = domain[4:] + + sites = Site.objects.filter(domain=domain).order_by('id') + if sites.count() >= 1: + site, duplicates = sites[0], sites[1:] + if duplicates.count(): + for duplicate in duplicates: + duplicate.delete() + else: + site = Site(domain=domain, name=domain) + site.save() + return site + + +class PagesRouterMiddleware(object): + + """Dispatch to normal or RSR page based on request domain.""" + + def process_request(self, request, cname_domain=False, rsr_page=None): + """.""" + domain = get_domain(request) + + if is_rsr_instance(domain): + request.rsr_page = None + + elif is_rsr_page_instance(domain): + try: + domain_parts = domain.split(".") + hostname = domain_parts[0] + if hostname == 'www': + hostname = domain_parts[1] + + rsr_page = PartnerSite.objects.get(hostname=hostname) + except: + pass + if rsr_page is None or not rsr_page.enabled: + return redirect("http://rsr.akvo.org") + + else: # Probably an RSR Page instance on partner-nominated domain + cname_domain = True + try: + rsr_page = PartnerSite.objects.get(cname=domain) + except: + return redirect("http://rsr.akvo.org") + + if rsr_page is not None and rsr_page.enabled: + if cname_domain: + rsr_page_domain = getattr( + settings, 'AKVOAPP_DOMAIN', 'akvoapp.org') + else: + rsr_page_domain = ".".join(domain.split(".")[1:]) + request.rsr_page = settings.RSR_PAGE = rsr_page + request.app_domain = ".".join( + (rsr_page.hostname, rsr_page_domain) + ) + request.akvoapp_root_url = "http://%s" % request.app_domain + request.organisation_id = rsr_page.organisation.id + request.rsr_page = rsr_page + request.default_language = rsr_page.default_language + + request.domain_url = "http://%s" % settings.RSR_DOMAIN + site = get_or_create_site(domain) + settings.SITE_ID = site.id + return None + + +class PagesLocaleMiddleware(LocaleMiddleware): + + """ + Partner sites aware version of Django's LocaleMiddleware. + + Since we swap out the root urlconf for a partner sites specific one, and + the original Django LocaleMiddleware didn't like that. + """ + + def process_request(self, request): + """.""" + check_path = self.is_language_prefix_patterns_used(request) + language = translation.get_language_from_request( + request, check_path=check_path) + translation.activate(language) + request.LANGUAGE_CODE = translation.get_language() + + def process_response(self, request, response): + """.""" + # First set the default language, this will be used if there is none + # in the path + default_language = getattr(request, 'default_language', '') + if default_language: + translation.activate(default_language) + + language = translation.get_language() + if (response.status_code == 404 and + not translation.get_language_from_path(request.path_info) and + self.is_language_prefix_patterns_used(request)): + language_path = '/%s%s' % (language, request.path_info) + if settings.APPEND_SLASH and not language_path.endswith('/'): + language_path += '/' + + if is_valid_path(language_path, settings.ROOT_URLCONF): + language_url = "%s://%s/%s%s" % ( + request.is_secure() and 'https' or 'http', + request.get_host(), language, request.get_full_path()) + return HttpResponseRedirect(language_url) + translation.deactivate() + + patch_vary_headers(response, ('Accept-Language',)) + if 'Content-Language' not in response: + response['Content-Language'] = language + return response + + def is_language_prefix_patterns_used(self, request): + """Return True if languge prefix is used. + + Return `True` if the `LocaleRegexURLResolver` is used + at root level of the urlpatterns, else it returns `False`. + """ + urlconf = getattr(request, 'urlconf', None) + for url_pattern in get_resolver(urlconf).url_patterns: + if isinstance(url_pattern, LocaleRegexURLResolver): + return True + return False + + +class ExceptionLoggingMiddleware(object): + + """Used to log exceptions on production systems.""" + + def process_exception(self, request, exception): + logging.exception('Exception handling request for ' + request.path) + + +class RSRVersionHeaderMiddleware(object): + + """Add a response header with RSR version info.""" + + def process_response(self, request, response): + context = extra_context(request) + + response['X-RSR-Version'] = "tag={}, commit={}, branch={}".format( + context['deploy_tag'], + context['deploy_commit_id'], + context['deploy_branch']) + return response diff --git a/akvo/rsr/models/partner_site.py b/akvo/rsr/models/partner_site.py index 4ec9ba0462..0b0fbc2421 100644 --- a/akvo/rsr/models/partner_site.py +++ b/akvo/rsr/models/partner_site.py @@ -1,11 +1,10 @@ # -*- coding: utf-8 -*- -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +"""Akvo RSR is covered by the GNU Affero General Public License. - -from textwrap import dedent +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" from django.conf import settings from django.db import models @@ -18,100 +17,110 @@ def about_image_path(instance, file_name): + """Return absolute image path.""" return 'db/partner_sites/%s/image/%s' % (instance.hostname, file_name) def custom_css_path(instance, filename): + """Return custom css path.""" return 'db/partner_sites/%s/custom.css' % instance.hostname def custom_favicon_path(instance, filename): + """Return custom favicon path.""" return 'db/partner_sites/%s/favicon.ico' % instance.hostname def custom_logo_path(instance, filename): + """Return custom logo path.""" return 'db/partner_sites/%s/logo/%s' % (instance.hostname, filename) class PartnerSite(TimestampsMixin, models.Model): + + """Model makes it possible to cater different data sets based on request's hostname.""" + def show_keywords(self): + """Return keywords for PartnerSite.""" return rsr_show_keywords(self) show_keywords.short_description = 'Keywords' show_keywords.allow_tags = True show_keywords.admin_order_field = 'keywords' - organisation = models.ForeignKey('Organisation', verbose_name=_(u'organisation'), - help_text=_('Select your organisation from the drop-down list.') - ) + organisation = models.ForeignKey( + 'Organisation', verbose_name=_(u'organisation'), + help_text=_('Select your organisation from the drop-down list.')) notes = ValidXMLTextField(verbose_name=u'Akvo partner site notes', blank=True, default='') - hostname = ValidXMLCharField(_(u'hostname'), max_length=50, unique=True, - help_text=_( + hostname = ValidXMLCharField( + _(u'hostname'), max_length=50, unique=True, help_text=_( u'

    Your hostname is used in the default web address of your partner site. ' u'The web address created from the hostname myorganisation would be ' u'http://myorganisation.akvoapp.org/.

    ' ) ) - cname = NullCharField(_(u'CNAME'), max_length=100, unique=True, blank=True, null=True, - help_text=_( - u'

    Enter a custom domain name for accessing the partner site, ' - u'for example projects.mydomain.org. Optional. Requires additional DNS setup.

    ' + cname = NullCharField( + _(u'CNAME'), max_length=100, unique=True, blank=True, null=True, help_text=_( + u'

    Enter a custom domain name for accessing the partner site, for example ' + u'projects.mydomain.org. Optional. Requires additional DNS setup.

    ' ) ) - custom_return_url = models.URLField(_(u'Return URL'), blank=True, - help_text=_( + custom_return_url = models.URLField( + _(u'Return URL'), blank=True, help_text=_( u'

    Enter the full URL (including http://) for the page to which users ' u'should be returned when leaving the partner site.

    ' ) ) - custom_return_url_text = ValidXMLCharField(_(u'Return URL text'), blank=True, max_length=50, default='', - help_text=_( + custom_return_url_text = ValidXMLCharField( + _(u'Return URL text'), blank=True, max_length=50, default='', help_text=_( u'

    Enter a text for the back button and return URL. ' u'Leave empty to display "Back to myorganisation".

    ' ) ) piwik_id = models.PositiveIntegerField(_('Piwik analytics ID'), blank=True, null=True) custom_css = models.FileField(_(u'stylesheet'), blank=True, upload_to=custom_css_path) - custom_logo = models.FileField(_(u'organisation banner logo'), blank=True, upload_to=custom_logo_path, - help_text=_( - u'

    Upload a logo file for the logo at the top of the partner site page. ' - u'By default logo of the organisation belonging to the Akvo Page will be displayed.

    ' + custom_logo = models.FileField( + _(u'organisation banner logo'), blank=True, upload_to=custom_logo_path, help_text=_( + u'

    Upload a logo file for the logo at the top of the partner site page. By default ' + u'logo of the organisation belonging to the Akvo Page will be displayed.

    ' ) ) - custom_favicon = models.FileField(_(u'favicon'), blank=True, upload_to=custom_favicon_path, - help_text=_( - u"

    A favicon (.ico file) is the 16x16 pixel image shown inside the browser's location bar, " - u'on tabs and in the bookmark menu.

    ' + custom_favicon = models.FileField( + _(u'favicon'), blank=True, upload_to=custom_favicon_path, help_text=_( + u'

    A favicon (.ico file) is the 16x16 pixel image shown inside the browser\'s ' + u'location bar, on tabs and in the bookmark menu.

    ' ) ) - about_box = ValidXMLTextField(_(u'about box text'), max_length=500, blank=True, - help_text=_( + about_box = ValidXMLTextField( + _(u'about box text'), max_length=500, blank=True, help_text=_( u'Enter HTML that will make up the top left box of the home page. (500 characters)' u'

    ' - u' Any text added should be wrapped in 2 <div> tags, an outer one specifying position and width' - u' of the text, and an inner for formatting of the text .' + u' Any text added should be wrapped in 2 <div> tags, an outer one specifying ' + u' position and width of the text, and an inner for formatting of the text .' u'

    ' u'

    ' - u' The Outer <div> tag can use the classes quarter, half, three_quarters and full to' - u' specify the' - u' width of the text. It can use the classes bottom and right to specify a ' - u' position other than top left.' + u' The Outer <div> tag can use the classes quarter, half, ' + u' three_quarters and full to specify the' + u' width of the text. It can use the classes bottom and ' + u' right to specify a position other than top left.' u'

    ' u'

    ' - u' The Inner <div> tag can use the class text_bg to create a semi-transparent text' - u' background if a background image will be uploaded. Any other inline styles can also be used within ' - u' the inner <div>. The tags <h1>, <h3>, <h5> and <a> are blue, while' - u' <p> tags are black by default. Use the classes first and last with ' - u' <p> tags to reduce the margins above or below respectively.' + u' The Inner <div> tag can use the class text_bg to create a ' + u' semi-transparent text background if a background image will be uploaded. ' + u' Any other inline styles can also be used within the inner <div>. The ' + u' tags <h1>, <h3>, <h5> and <a> are blue, while ' + u' <p> tags are black by default. Use the classes first and ' + u' last with <p> tags to reduce the margins above or below ' + u' respectively.' u'

    ' u'

    ' - u' Add additional styling inline, or upload a .css stylesheet in the Stylesheet setting above.' - u' Tip: When using a .css file, use the #about_box ID selector to apply a style only to' - u' the About box.' + u' Add additional styling inline, or upload a .css stylesheet in the Stylesheet ' + u' setting above. Tip: When using a .css file, use the #about_box ID ' + u' selector to apply a style only to the About box.' u'

    ' ) ) - about_image = models.ImageField(_(u'about box image'), blank=True, upload_to=about_image_path, - help_text=_( + about_image = models.ImageField( + _(u'about box image'), blank=True, upload_to=about_image_path, help_text=_( u'

    The optional background image for the About box ' u'must be 470 pixels wide and 250 pixels tall.

    ' ) @@ -119,52 +128,61 @@ def show_keywords(self): enabled = models.BooleanField(_(u'enabled'), default=True) default_language = ValidXMLCharField( - _(u'Site UI default language'), max_length=5, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE - ) + _(u'Site UI default language'), max_length=5, choices=settings.LANGUAGES, + default=settings.LANGUAGE_CODE) ui_translation = models.BooleanField(_(u'Translate user interface'), default=False) google_translation = models.BooleanField(_(u'Google translation widget'), default=False) facebook_button = models.BooleanField(_(u'Facebook share button'), default=False) twitter_button = models.BooleanField(_(u'Twitter share button'), default=False) - facebook_app_id = ValidXMLCharField(_(u'Facebook App Id'), max_length=40, blank=True, null=True, - help_text=_( + facebook_app_id = ValidXMLCharField( + _(u'Facebook App Id'), max_length=40, blank=True, null=True, help_text=_( u'

    Your FaceBook app id is used when sharing pages from your partner site. ' - u'It can be obtained by creating a Facebook app, which will let you monitor when your pages are referenced. ' - u'Follow the instructions ' - u'here' + u'It can be obtained by creating a Facebook app, which will let you monitor when your ' + u'pages are referenced. Follow the instructions ' + u'here' ) ) partner_projects = models.BooleanField( _(u'Show only projects of partner'), default=True, help_text=_(u'Uncheck to list all projects on this partnersite.') ) - keywords = models.ManyToManyField('Keyword', verbose_name=_(u'keywords'), related_name='partnersites', blank=True) - exclude_keywords = models.BooleanField(_(u'Exclude projects with selected keyword(s)'), default=False) - + keywords = models.ManyToManyField( + 'Keyword', verbose_name=_(u'keywords'), related_name='partnersites', blank=True) + exclude_keywords = models.BooleanField( + _(u'Exclude projects with selected keyword(s)'), default=False) def __unicode__(self): - return u'Partner site for %(organisation_name)s' % {'organisation_name': self.organisation.name} + """Unicode representation.""" + return u'Partner site for {}'.format(self.organisation.name) @property def logo(self): + """Return logo.""" return self.custom_logo or None @property def return_url(self): + """Return custom url or /.""" return self.custom_return_url or "/" @property def stylesheet(self): + """Return stylesheet.""" return self.custom_css or None @property def favicon(self): + """Return favicon.""" return self.custom_favicon or None @property def full_domain(self): + """Return full domain.""" return '%s.%s' % (self.hostname, getattr(settings, 'AKVOAPP_DOMAIN', 'akvoapp.org')) def get_absolute_url(self): + """Return absolute url.""" url = '' # TODO: consider the ramifications of get_absolute_url using CNAME if available if self.cname: @@ -177,6 +195,14 @@ def get_absolute_url(self): url = '%s://%s/' % (protocol, self.full_domain) return url + @classmethod + def yank_hostname(cls, netloc): + """Get from . + + From a netloc return what is stored as "hostname" on the PartnerSite model. + """ + return netloc.replace('.{}'.format(settings.AKVOAPP_DOMAIN), '') + class Meta: app_label = 'rsr' verbose_name = u'partner site' diff --git a/akvo/rsr/templatetags/piwik_tags.py b/akvo/rsr/templatetags/piwik_tags.py index df091fd865..cfda464256 100644 --- a/akvo/rsr/templatetags/piwik_tags.py +++ b/akvo/rsr/templatetags/piwik_tags.py @@ -1,10 +1,13 @@ # -*- coding: utf-8 -*- -# Akvo RSR is covered by the GNU Affero General Public License. -# See more details in the license.txt file located at the root folder of the Akvo RSR module. -# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. -# code based on django-piwik, https://github.com/raphaa/django-piwik +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. + +Code based on django-piwik, https://github.com/raphaa/django-piwik +""" from django import template from django.conf import settings @@ -14,17 +17,24 @@ register = template.Library() -@register.inclusion_tag('piwik/tracking_code.html') -def tracking_code(): - if settings.PARTNER_SITE and settings.PARTNER_SITE.piwik_id: - id = settings.PARTNER_SITE.piwik_id - else: - try: - id = settings.PIWIK_SITE_ID - except AttributeError: - raise ImproperlyConfigured('PIWIK_SITE_ID does not exist.') +@register.inclusion_tag('piwik/tracking_code.html', takes_context=True) +def piwik_tracking_code(context): + """Try and use configured partner site Piwik values otherwise pull from settings.""" + try: + piwik_id = settings.PIWIK_SITE_ID, + except AttributeError: + raise ImproperlyConfigured('PIWIK_SITE_ID does not exist.') + try: - url = settings.PIWIK_URL + piwik_url = settings.PIWIK_URL except AttributeError: raise ImproperlyConfigured('PIWIK_URL does not exist.') - return {'id': id, 'url': url} + + try: + return { + 'id': context['request'].rsr_page.piwik_id, + 'url': piwik_url} + except AttributeError: + pass + + return {'id': piwik_id, 'url': piwik_url} diff --git a/akvo/rsr/tests/test_middleware.py b/akvo/rsr/tests/test_middleware.py index 2cdfa62258..2e2c1114de 100644 --- a/akvo/rsr/tests/test_middleware.py +++ b/akvo/rsr/tests/test_middleware.py @@ -7,9 +7,11 @@ see < http://www.gnu.org/licenses/agpl.html >. """ +from django.conf import settings from django.test import TestCase from django.test.client import RequestFactory -from akvo.rsr.middleware2 import get_domain, ReallySimpleRouterMiddleware +from akvo.rsr.middleware import (_is_rsr_host, _partner_site, HostDispatchMiddleware) +from akvo.rsr.models import PartnerSite, Organisation class PagesRouterMiddlewareTestCase(TestCase): @@ -19,17 +21,139 @@ class PagesRouterMiddlewareTestCase(TestCase): def setUp(self): """Setup.""" self.factory = RequestFactory() - self.mw = ReallySimpleRouterMiddleware() - self.req0 = self.factory.get('/') - self.req1 = self.factory.get('/', {}, HTTP_HOST='rsr.akvo.org') - self.req2 = self.factory.get('/', {}, HTTP_HOST='rsr.localdev.akvo.org') + self.mw = HostDispatchMiddleware() + self.RSR_DOMAIN = settings.RSR_DOMAIN + self.AKVOAPP_DOMAIN = settings.AKVOAPP_DOMAIN + o1 = Organisation(name='p1', long_name='Partner1') + o1.save() + ps1 = PartnerSite(organisation=o1, hostname='partner1', cname='projects.partner1.org') + ps1.save() - def test_get_domain(self): + # Valid RSR hosts + self.rsr_req0 = self.factory.get('/', {}, HTTP_HOST=self.RSR_DOMAIN) + self.rsr_req1 = self.factory.get('/', {}, HTTP_HOST='127.0.0.1') + self.rsr_req2 = self.factory.get('/', {}, HTTP_HOST='localhost') + # Invalid but on the correct domain + self.invalid_rsr_req0 = self.factory.get('/', {}, + HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) + # Valid request to the app domain (used by third parties) + self.naked_app_req0 = self.factory.get('/', {}, HTTP_HOST=self.AKVOAPP_DOMAIN) + # self.valid_app_req0 = ... + self.app_req0_hostname = 'partner1' + self.app_req0 = self.factory.get('/', {}, + HTTP_HOST='{}.{}'.format(self.app_req0_hostname, + self.AKVOAPP_DOMAIN)) + # Invalid request to the app domain (used by third parties) + self.invalid_app_req0 = self.factory.get('/', {}, + HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) + # Valid request with other host configured in a partner page + self.valid_app_req0 = self.factory.get('/', {}, HTTP_HOST=ps1.cname) + # Invalid request with other host + self.invalid_req0 = self.factory.get('/', {}, HTTP_HOST='notfound.example.com') + + def test_is_rsr_host(self): + """.""" + self.assertEqual(_is_rsr_host(self.rsr_req0.get_host()), True) + self.assertEqual(_is_rsr_host(self.rsr_req1.get_host()), True) + self.assertEqual(_is_rsr_host(self.rsr_req2.get_host()), True) + self.assertEqual(_is_rsr_host(self.invalid_rsr_req0.get_host()), False) + self.assertEqual(_is_rsr_host(self.naked_app_req0.get_host()), False) + self.assertEqual(_is_rsr_host(self.app_req0.get_host()), False) + self.assertEqual(_is_rsr_host(self.invalid_app_req0.get_host()), False) + self.assertEqual(_is_rsr_host(self.invalid_req0.get_host()), False) + + def test_partner_site(self): """.""" - self.assertEqual(get_domain(self.req0), "rsr.akvo.org") - self.assertEqual(get_domain(self.req1), "rsr.akvo.org") - self.assertEqual(get_domain(self.req2), "rsr.localdev.akvo.org") + with self.assertRaises(PartnerSite.DoesNotExist): + _partner_site(self.invalid_app_req0.get_host()) + + # with self.assertRaises(PartnerSite.DoesNotExist): + # partner_site(self.app_req0.get_host()) + # self.assertEqual(partner_site(self.app_req0.get_host()).hostname, 'partner1') + self.assertEqual(_partner_site(self.app_req0.get_host()).hostname, self.app_req0_hostname) + self.assertEqual(_partner_site(self.valid_app_req0.get_host()).cname, + 'projects.partner1.org') + + # print PartnerSite.objects.all() + + # + # try: + # site = partner_site(self.invalid_app_req0.get_host()) + # except PartnerSite.DoesNotExist: + # + # with self.assertRaises(ObjectDoesNotExist) as cm: + # site = partner_site(self.invalid_app_req0.get_host()) + # + # # self.assertEqual(cm, True) + # the_exception = cm.exception + # self.assertEqual(the_exception, PartnerSite.DoesNotExist) + # self.assertEqual(the_exception.error_code, 3) + + # self.assertRaises(partner_site('partner.{}'.format(self.AKVOAPP_DOMAIN))) + # self.assertEqual(True, True) + # self.assertEqual(partner_site('partner.{}'.format(self.AKVOAPP_DOMAIN)), False) + # + # self.req0 = self.factory.get('/', {}, HTTP_HOST=self.RSR_DOMAIN) + # self.req1 = self.factory.get('/', {}, HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) + # self.req2 = self.factory.get('/', {}, HTTP_HOST=self.AKVOAPP_DOMAIN) + # self.req3 = self.factory.get('/', {}, HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) + # # self.req4 = self.factory.get('/', {}, HTTP_HOST='valid.{}'.format(self.AKVOAPP_DOMAIN)) + # self.req5 = self.factory.get('/', {}, + # HTTP_HOST='notfound.{}'.format(self.AKVOAPP_DOMAIN)) + # + # def test_is_rsr_instance(self): + # """.""" + # self.assertEqual(is_rsr_instance(self.req0.get_host()), True) + # self.assertEqual(is_rsr_instance(self.req1.get_host()), True) + # self.assertEqual(is_rsr_instance(self.req2.get_host()), False) + # self.assertEqual(is_rsr_instance(self.req3.get_host()), False) + # self.assertEqual(is_rsr_instance(self.req5.get_host()), False) + # + # def test_is_rsr_domain(self): + # """.""" + # self.assertEqual(is_rsr_domain(self.req0), True) + # self.assertEqual(is_rsr_domain(self.req1), False) + # self.assertEqual(is_rsr_domain(self.req2), False) + # self.assertEqual(is_rsr_domain(self.req3), False) + # self.assertEqual(is_rsr_domain(self.req5), False) + # + # def test_is_akvoapp_domain(self): + # """.""" + # self.assertEqual(is_akvoapp_domain(self.req1), False) + # self.assertEqual(is_akvoapp_domain(self.req2), True) + # self.assertEqual(is_akvoapp_domain(self.req3), False) + # self.assertEqual(is_akvoapp_domain(self.req5), False) - def test_process_request(self): - """Test inbound.""" - self.assertEqual(None, None) +# class PagesRouterMiddlewareTestCase(TestCase): +# +# """Testing the routing mechanism.""" +# +# def setUp(self): +# """Setup.""" +# self.factory = RequestFactory() +# self.mw = ReallySimpleRouterMiddleware() +# +# self.req1 = self.factory.get('/', {}, HTTP_HOST='rsr.akvo.org') +# self.req2 = self.factory.get('/', {}, HTTP_HOST='rsr.test.akvo.org') +# self.req3 = self.factory.get('/', {}, HTTP_HOST='rsr.uat.akvo.org') +# self.req4 = self.factory.get('/', {}, HTTP_HOST='rsr.localdev.akvo.org') +# self.req5 = self.factory.get('/', {}, HTTP_HOST='notfound.akvo.org') +# +# self.req5 = self.factory.get('/', {}, HTTP_HOST='akvoapp.org') +# self.req6 = self.factory.get('/', {}, HTTP_HOST='test.akvoapp.org') +# self.req7 = self.factory.get('/', {}, HTTP_HOST='uat.akvoapp.org') +# self.req8 = self.factory.get('/', {}, HTTP_HOST='localdev.akvoapp.org') +# self.req5 = self.factory.get('/', {}, HTTP_HOST='notfound.akvoapp.org') +# +# # RSR_DOMAIN = 'rsr.localdev.akvo.org' +# # AKVOAPP_DOMAIN = 'localakvoapp.org' +# +# def test_get_domain(self): +# """.""" +# self.assertEqual(get_domain(self.req0), "rsr.akvo.org") +# self.assertEqual(get_domain(self.req1), "rsr.akvo.org") +# self.assertEqual(get_domain(self.req2), "rsr.localdev.akvo.org") +# +# def test_process_request(self): +# """Test inbound.""" +# self.assertEqual(None, None) diff --git a/akvo/settings/10-base.conf b/akvo/settings/10-base.conf index b3bdcbc704..31732cd0f7 100644 --- a/akvo/settings/10-base.conf +++ b/akvo/settings/10-base.conf @@ -61,8 +61,8 @@ AUTHENTICATION_BACKENDS = ( AUTH_USER_MODEL = 'rsr.User' MIDDLEWARE_CLASSES = ( - 'akvo.rsr.middleware.PagesRouterMiddleware', - # 'akvo.rsr.middleware.PagesLocaleMiddleware', + 'akvo.rsr.middleware.HostDispatchMiddleware', + # 'akvo.rsr.middleware_old.PagesLocaleMiddleware', # 'django.middleware.gzip.GZipMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', diff --git a/akvo/settings/66_local.template b/akvo/settings/66_local.template index d5f834d49a..2f65265493 100644 --- a/akvo/settings/66_local.template +++ b/akvo/settings/66_local.template @@ -5,7 +5,7 @@ Akvo RSR module. For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ - +SITE_ID = 1 DEBUG = TEMPLATE_DEBUG = True PIPELINE_ENABLED = False diff --git a/akvo/templates/base.html b/akvo/templates/base.html index 8c7d71db74..d24e7a4895 100644 --- a/akvo/templates/base.html +++ b/akvo/templates/base.html @@ -102,7 +102,6 @@ } - {# Piwik #} - {% tracking_code %} + {% piwik_tracking_code %} From dd253a7821d586cf7a9609f96f482c27d6560257 Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Wed, 1 Apr 2015 16:23:15 +0200 Subject: [PATCH 12/22] [#809] Small change after feedback --- akvo/rsr/middleware.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akvo/rsr/middleware.py b/akvo/rsr/middleware.py index 72c510a9a4..98dd194a39 100644 --- a/akvo/rsr/middleware.py +++ b/akvo/rsr/middleware.py @@ -18,7 +18,7 @@ def _is_rsr_host(hostname): """Predicate function that checks if request is made to the RSR_DOMAIN.""" rsr_hosts = ['127.0.0.1', 'localhost', settings.RSR_DOMAIN] - return True if hostname in rsr_hosts else False + return hostname in rsr_hosts def _partner_site(netloc): From 57920a22aece794805450597b93d60537b2872c9 Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Wed, 1 Apr 2015 16:39:08 +0200 Subject: [PATCH 13/22] [#1281] Last update in project list --- akvo/templates/project_directory.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/akvo/templates/project_directory.html b/akvo/templates/project_directory.html index 5f709b364d..b87451f493 100644 --- a/akvo/templates/project_directory.html +++ b/akvo/templates/project_directory.html @@ -105,6 +105,9 @@

    {{p.t {% trans "Sectors" %} {% for sector in p.sector_categories_codes %}{% if not forloop.first %}, {% endif %}{{sector.1}}{% endfor %}
    {% endif %} {% trans "Status" %} {{p.get_status_display}}
    + {% if p.last_update %} + {% trans "Latest update" %} {{p.last_update.created_at|date:"d-M-Y"}}
    + {% endif %} {% trans "Finance" %} {% widthratio p.funds p.budget 100 %}% {% trans "of" %} {{p.get_currency_display}}{{p.budget|floatformat|intcomma}} {% if p.accepts_donations %} @@ -122,6 +125,9 @@

    {{p.t {% trans "Sectors" %} {% for sector in p.sector_categories_codes %}{% if not forloop.first %}, {% endif %}{{sector.1}}{% endfor %}
    {% endif %} {% trans "Status" %} {{p.get_status_display}}
    + {% if p.last_update %} + {% trans "Latest update" %} {{p.last_update.created_at|date:"d-M-Y"}}
    + {% endif %} {% trans "Finance" %} {% widthratio p.funds p.budget 100 %}% {% trans "of" %} {{p.get_currency_display}}{{p.budget|floatformat|intcomma}} {% if p.accepts_donations %} @@ -139,6 +145,12 @@

    {% trans "Sectors" %}

    {% endif %}

    {% trans "Status" %}

    {{p.get_status_display}}

    +

    {% trans "Latest update" %}

    + {% if p.last_update %} +

    {{p.last_update.created_at|date:"d-M-Y"}}

    + {% else %} +

    {% trans 'No updates' %}

    + {% endif %} From 2c50e57fe288382383414c4521bae494adc5a483 Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Thu, 9 Apr 2015 15:14:25 +0200 Subject: [PATCH 19/22] [#809] Updated Middleware after some testing. - Removed sites framework --- akvo/rsr/middleware.py | 26 +- akvo/rsr/tests/pages/test_homepage.py | 45 +-- akvo/rsr/tests/pages/test_not_found.py | 24 ++ .../rsr/tests/pages/test_organisations_dir.py | 24 ++ akvo/rsr/tests/pages/test_project_dir.py | 24 ++ akvo/rsr/tests/pages/test_updates_dir.py | 24 ++ akvo/rsr/tests/test_middleware.py | 273 +++++++++--------- akvo/rsr/views/__init__.py | 8 +- akvo/settings/10-base.conf | 2 - 9 files changed, 273 insertions(+), 177 deletions(-) create mode 100644 akvo/rsr/tests/pages/test_not_found.py create mode 100644 akvo/rsr/tests/pages/test_organisations_dir.py create mode 100644 akvo/rsr/tests/pages/test_project_dir.py create mode 100644 akvo/rsr/tests/pages/test_updates_dir.py diff --git a/akvo/rsr/middleware.py b/akvo/rsr/middleware.py index 98dd194a39..697c124d1e 100644 --- a/akvo/rsr/middleware.py +++ b/akvo/rsr/middleware.py @@ -9,6 +9,7 @@ import logging from django.conf import settings +from django.core.exceptions import DisallowedHost from django.db.models import Q from django.shortcuts import redirect from akvo.rsr.context_processors import extra_context @@ -21,6 +22,13 @@ def _is_rsr_host(hostname): return hostname in rsr_hosts +def _is_naked_app_host(hostname): + """Predicate function that checks if request is made to the RSR_DOMAIN.""" + if hostname == settings.AKVOAPP_DOMAIN: + return True + return False + + def _partner_site(netloc): """From a netloc return PartnerSite or raise a DoesNotExist.""" return PartnerSite.objects.get( @@ -38,19 +46,27 @@ def process_request(self, request): request.rsr_page = None host = request.get_host() - # Do nothing if called on "normal" RSR host - if _is_rsr_host(host): - return None + # Make sure host is valid - otherwise redirect to RSR_DOMAIN. + # Do nothing if called on "normal" RSR host. + try: + if _is_rsr_host(host): + return None + except DisallowedHost: + return redirect("http://{}".format(settings.RSR_DOMAIN)) + + # Check if called on naked app domain - if so redirect + if _is_naked_app_host(host): + return redirect("http://{}".format(settings.RSR_DOMAIN)) # Check if site exists try: site = _partner_site(host) except PartnerSite.DoesNotExist: - return redirect(settings.RSR_DOMAIN) + return redirect("http://{}".format(settings.RSR_DOMAIN)) # Check if site is enabled if not site.enabled: - return redirect(settings.RSR_DOMAIN) + return redirect("http://{}".format(settings.RSR_DOMAIN)) # Set site to request object request.rsr_page = site diff --git a/akvo/rsr/tests/pages/test_homepage.py b/akvo/rsr/tests/pages/test_homepage.py index dec1f3776d..e590c18542 100644 --- a/akvo/rsr/tests/pages/test_homepage.py +++ b/akvo/rsr/tests/pages/test_homepage.py @@ -6,46 +6,21 @@ For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ -from django.contrib.sites.models import Site +from django.conf import settings from django.test import Client, TestCase -# class notFoundPageTestCase(TestCase): -# def setUp(self): -# site, created = Site.objects.get_or_create(domain="localdev.akvo.org", -# name="localdev") -# with self.settings(SITE_ID=site.id): -# c = Client() -# self.resp = c.get('/does-not-exist') -# -# def test_access(self): -# self.assertEqual(self.resp.status_code, 404) +class PingTest(TestCase): - -class homePageTestCase(TestCase): - - """Make sure requests to the home page returns as expected.""" + """Simple ping test.""" def setUp(self): - """Make sure we have a site object and config settings.""" - site, created = Site.objects.get_or_create(domain="localdev.akvo.org", - name="localdev") - with self.settings(SITE_ID=site.id): - c = Client() - self.resp = c.get('/') + """Setup.""" + self.c = Client(HTTP_HOST=settings.RSR_DOMAIN) def test_redirect(self): - """Test that we get a redirect (http 302) on the home page.""" - self.assertEqual(self.resp.status_code, 302) - - -# class projectsPageTestCase(TestCase): -# def setUp(self): -# site, created = Site.object.get_or_create(domain="localdev.akvo.org", -# name="localdev") -# with self.settings(SITE_ID=site.id): -# c = Client() -# self.resp = c.get('/projects/') -# -# def test_response(self): -# self.assertEqual(self.resp.status_code, 200) + """Ping /.""" + response = self.c.get('/', follow=True) + expected_host = settings.RSR_DOMAIN + self.assertRedirects(response=response, expected_url='/projects/', status_code=302, + target_status_code=200, host=expected_host) diff --git a/akvo/rsr/tests/pages/test_not_found.py b/akvo/rsr/tests/pages/test_not_found.py new file mode 100644 index 0000000000..e645377ec6 --- /dev/null +++ b/akvo/rsr/tests/pages/test_not_found.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.conf import settings +from django.test import Client, TestCase + + +class NotFoundPageTest(TestCase): + + """Simple ping to non existing page.""" + + def setUp(self): + """Setup.""" + self.c = Client(HTTP_HOST=settings.RSR_DOMAIN) + + def test_not_found(self): + """.""" + response = self.c.get('/does-not-exist') + self.assertEqual(response.status_code, 404) diff --git a/akvo/rsr/tests/pages/test_organisations_dir.py b/akvo/rsr/tests/pages/test_organisations_dir.py new file mode 100644 index 0000000000..e7dab8484d --- /dev/null +++ b/akvo/rsr/tests/pages/test_organisations_dir.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.conf import settings +from django.test import Client, TestCase + + +class PingTest(TestCase): + + """Simple ping.""" + + def setUp(self): + """Setup.""" + self.c = Client(HTTP_HOST=settings.RSR_DOMAIN) + + def test_ping(self): + """Ping /organisations/.""" + response = self.c.get('/organisations/') + self.assertEqual(response.status_code, 200) diff --git a/akvo/rsr/tests/pages/test_project_dir.py b/akvo/rsr/tests/pages/test_project_dir.py new file mode 100644 index 0000000000..7b9073a7a2 --- /dev/null +++ b/akvo/rsr/tests/pages/test_project_dir.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.conf import settings +from django.test import Client, TestCase + + +class PingTest(TestCase): + + """Simple ping.""" + + def setUp(self): + """Setup.""" + self.c = Client(HTTP_HOST=settings.RSR_DOMAIN) + + def test_ping(self): + """Ping /projects/.""" + response = self.c.get('/projects/') + self.assertEqual(response.status_code, 200) diff --git a/akvo/rsr/tests/pages/test_updates_dir.py b/akvo/rsr/tests/pages/test_updates_dir.py new file mode 100644 index 0000000000..b8bbf36829 --- /dev/null +++ b/akvo/rsr/tests/pages/test_updates_dir.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.conf import settings +from django.test import Client, TestCase + + +class PingTest(TestCase): + + """Simple ping.""" + + def setUp(self): + """Setup.""" + self.c = Client(HTTP_HOST=settings.RSR_DOMAIN) + + def test_ping(self): + """Ping /updates/.""" + response = self.c.get('/updates/') + self.assertEqual(response.status_code, 200) diff --git a/akvo/rsr/tests/test_middleware.py b/akvo/rsr/tests/test_middleware.py index 2e2c1114de..6f2b57e285 100644 --- a/akvo/rsr/tests/test_middleware.py +++ b/akvo/rsr/tests/test_middleware.py @@ -2,158 +2,167 @@ """Akvo RSR is covered by the GNU Affero General Public License. -See more details in the license.txt file located at the root folder of the -Akvo RSR module. For additional details on the GNU license please -see < http://www.gnu.org/licenses/agpl.html >. +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ from django.conf import settings -from django.test import TestCase +from django.core.exceptions import DisallowedHost +from django.test import Client, TestCase from django.test.client import RequestFactory -from akvo.rsr.middleware import (_is_rsr_host, _partner_site, HostDispatchMiddleware) +from akvo.rsr.middleware import _is_rsr_host, _is_naked_app_host, _partner_site from akvo.rsr.models import PartnerSite, Organisation +STOCK_RSR_NETLOC = "http://{}".format(settings.RSR_DOMAIN) +AKVOAPP_NETLOC = "http://{}".format(settings.AKVOAPP_DOMAIN) -class PagesRouterMiddlewareTestCase(TestCase): - """Testing the routing mechanism.""" +class ValidStockRSRTestCase(TestCase): + + """Testing request to stock RSR. + + valid hosts : + - settings.RSR_DOMAIN + - 127.0.0.1 + - localhost + """ + + def setUp(self): + """Setup.""" + self.factory = RequestFactory() + self.req_RSR_DOMAIN = self.factory.get('/', {}, HTTP_HOST=settings.RSR_DOMAIN) + self.req_127 = self.factory.get('/', {}, HTTP_HOST='127.0.0.1') + self.req_localhost = self.factory.get('/', {}, HTTP_HOST='localhost') + + def test_is_rsr_host(self): + """Test request to normal RSR host.""" + self.assertTrue(_is_rsr_host(self.req_RSR_DOMAIN.get_host())) + self.assertTrue(_is_rsr_host(self.req_127.get_host())) + self.assertTrue(_is_rsr_host(self.req_localhost.get_host())) + + +class InValidStockRSRTestCase(TestCase): + + """Testing request to stock RSR. + + invalid hosts : + - "invalid_host" + - "" + """ def setUp(self): """Setup.""" self.factory = RequestFactory() - self.mw = HostDispatchMiddleware() - self.RSR_DOMAIN = settings.RSR_DOMAIN - self.AKVOAPP_DOMAIN = settings.AKVOAPP_DOMAIN + self.req_not_found_host = self.factory.get('/', {}, HTTP_HOST='not-found.akvo.org') + self.req_not_found_host2 = self.factory.get('/', {}, HTTP_HOST='not-found.test.akvo.org') + self.req_invalid_host = self.factory.get('/', {}, HTTP_HOST='invalid_host') + self.req_empty_host = self.factory.get('/', {}, HTTP_HOST='') + + def test_is_rsr_host(self): + """Test request to normal RSR host.""" + self.assertFalse(_is_rsr_host(self.req_not_found_host.get_host())) + self.assertFalse(_is_rsr_host(self.req_not_found_host2.get_host())) + with self.assertRaises(DisallowedHost): + _is_rsr_host(self.req_invalid_host.get_host()) + with self.assertRaises(DisallowedHost): + _is_rsr_host(self.req_empty_host.get_host()) + + +class NakedAKVOAPP_DOMAINTestCase(TestCase): + + """Testing request to naked AKVOAPP_DOMAIN.""" + + def test_is_rsr_host(self): + """Make sure AKVOAPP domain is not a valid stock RSR host.""" + self.assertFalse(_is_rsr_host(settings.AKVOAPP_DOMAIN)) + + def test_is_akvoapp_host(self): + """Make sure AKVOAPP domain is a valid app domain.""" + self.assertTrue(_is_naked_app_host(settings.AKVOAPP_DOMAIN)) + + def test_akvoapp_redirect(self): + """Call naked app domain will return a redirect to the stock RSR page. + + Since that page + redirects to /projets there is another 302 in the target status code. + """ + c = Client(HTTP_HOST=settings.AKVOAPP_DOMAIN) + resp_naked = c.get('/', follow=True) + self.assertRedirects(response=resp_naked, expected_url=STOCK_RSR_NETLOC, + status_code=302, target_status_code=302) + + +class ValidAkvoPageTestCase(TestCase): + + """Testing request to valid Akvo pages.""" + + def setUp(self): + """Setup.""" + valid_host = "partner1.{}".format(settings.AKVOAPP_DOMAIN) + self.c = Client(HTTP_HOST=valid_host) o1 = Organisation(name='p1', long_name='Partner1') o1.save() ps1 = PartnerSite(organisation=o1, hostname='partner1', cname='projects.partner1.org') ps1.save() - # Valid RSR hosts - self.rsr_req0 = self.factory.get('/', {}, HTTP_HOST=self.RSR_DOMAIN) - self.rsr_req1 = self.factory.get('/', {}, HTTP_HOST='127.0.0.1') - self.rsr_req2 = self.factory.get('/', {}, HTTP_HOST='localhost') - # Invalid but on the correct domain - self.invalid_rsr_req0 = self.factory.get('/', {}, - HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) - # Valid request to the app domain (used by third parties) - self.naked_app_req0 = self.factory.get('/', {}, HTTP_HOST=self.AKVOAPP_DOMAIN) - # self.valid_app_req0 = ... - self.app_req0_hostname = 'partner1' - self.app_req0 = self.factory.get('/', {}, - HTTP_HOST='{}.{}'.format(self.app_req0_hostname, - self.AKVOAPP_DOMAIN)) - # Invalid request to the app domain (used by third parties) - self.invalid_app_req0 = self.factory.get('/', {}, - HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) - # Valid request with other host configured in a partner page - self.valid_app_req0 = self.factory.get('/', {}, HTTP_HOST=ps1.cname) - # Invalid request with other host - self.invalid_req0 = self.factory.get('/', {}, HTTP_HOST='notfound.example.com') + def test_partner_site(self): + """.""" + self.assertTrue("partner1.{}".format(settings.AKVOAPP_DOMAIN)) - def test_is_rsr_host(self): + def test_valid_partner_site(self): """.""" - self.assertEqual(_is_rsr_host(self.rsr_req0.get_host()), True) - self.assertEqual(_is_rsr_host(self.rsr_req1.get_host()), True) - self.assertEqual(_is_rsr_host(self.rsr_req2.get_host()), True) - self.assertEqual(_is_rsr_host(self.invalid_rsr_req0.get_host()), False) - self.assertEqual(_is_rsr_host(self.naked_app_req0.get_host()), False) - self.assertEqual(_is_rsr_host(self.app_req0.get_host()), False) - self.assertEqual(_is_rsr_host(self.invalid_app_req0.get_host()), False) - self.assertEqual(_is_rsr_host(self.invalid_req0.get_host()), False) + valid_resp = self.c.get('/') + expected_host = "partner1.{}".format(settings.AKVOAPP_DOMAIN) + self.assertRedirects(response=valid_resp, expected_url="/projects/", + status_code=302, target_status_code=200, host=expected_host) + + +class ValidCnameAkvoPageTestCase(TestCase): + + """Testing request to valid Akvo pages.""" + + def setUp(self): + """Setup.""" + # valid_host = "partner1.{}".format(settings.AKVOAPP_DOMAIN) + self.cname = "projects.partner1.org" + self.c = Client(HTTP_HOST=self.cname) + o1 = Organisation(name='p1', long_name='Partner1') + o1.save() + ps1 = PartnerSite(organisation=o1, hostname='partner1', cname=self.cname) + ps1.save() + + def test_partner_site(self): + """.""" + self.assertTrue(_partner_site(self.cname)) + + def test_valid_partner_site(self): + """.""" + valid_resp = self.c.get('/') + # expected_host = "partner1.{}".format(settings.AKVOAPP_DOMAIN) + self.assertRedirects(response=valid_resp, expected_url="/projects/", + status_code=302, target_status_code=200, host=self.cname) + + +class InvalidAkvoPageTestCase(TestCase): + + """Testing request to stock RSR. + + invalid hosts : + - "invalid_host" + - "" + """ + + def setUp(self): + """Setup.""" + self.c = Client(HTTP_HOST=settings.AKVOAPP_DOMAIN) def test_partner_site(self): """.""" with self.assertRaises(PartnerSite.DoesNotExist): - _partner_site(self.invalid_app_req0.get_host()) - - # with self.assertRaises(PartnerSite.DoesNotExist): - # partner_site(self.app_req0.get_host()) - # self.assertEqual(partner_site(self.app_req0.get_host()).hostname, 'partner1') - self.assertEqual(_partner_site(self.app_req0.get_host()).hostname, self.app_req0_hostname) - self.assertEqual(_partner_site(self.valid_app_req0.get_host()).cname, - 'projects.partner1.org') - - # print PartnerSite.objects.all() - - # - # try: - # site = partner_site(self.invalid_app_req0.get_host()) - # except PartnerSite.DoesNotExist: - # - # with self.assertRaises(ObjectDoesNotExist) as cm: - # site = partner_site(self.invalid_app_req0.get_host()) - # - # # self.assertEqual(cm, True) - # the_exception = cm.exception - # self.assertEqual(the_exception, PartnerSite.DoesNotExist) - # self.assertEqual(the_exception.error_code, 3) - - # self.assertRaises(partner_site('partner.{}'.format(self.AKVOAPP_DOMAIN))) - # self.assertEqual(True, True) - # self.assertEqual(partner_site('partner.{}'.format(self.AKVOAPP_DOMAIN)), False) - # - # self.req0 = self.factory.get('/', {}, HTTP_HOST=self.RSR_DOMAIN) - # self.req1 = self.factory.get('/', {}, HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) - # self.req2 = self.factory.get('/', {}, HTTP_HOST=self.AKVOAPP_DOMAIN) - # self.req3 = self.factory.get('/', {}, HTTP_HOST='notfound.{}'.format(self.RSR_DOMAIN)) - # # self.req4 = self.factory.get('/', {}, HTTP_HOST='valid.{}'.format(self.AKVOAPP_DOMAIN)) - # self.req5 = self.factory.get('/', {}, - # HTTP_HOST='notfound.{}'.format(self.AKVOAPP_DOMAIN)) - # - # def test_is_rsr_instance(self): - # """.""" - # self.assertEqual(is_rsr_instance(self.req0.get_host()), True) - # self.assertEqual(is_rsr_instance(self.req1.get_host()), True) - # self.assertEqual(is_rsr_instance(self.req2.get_host()), False) - # self.assertEqual(is_rsr_instance(self.req3.get_host()), False) - # self.assertEqual(is_rsr_instance(self.req5.get_host()), False) - # - # def test_is_rsr_domain(self): - # """.""" - # self.assertEqual(is_rsr_domain(self.req0), True) - # self.assertEqual(is_rsr_domain(self.req1), False) - # self.assertEqual(is_rsr_domain(self.req2), False) - # self.assertEqual(is_rsr_domain(self.req3), False) - # self.assertEqual(is_rsr_domain(self.req5), False) - # - # def test_is_akvoapp_domain(self): - # """.""" - # self.assertEqual(is_akvoapp_domain(self.req1), False) - # self.assertEqual(is_akvoapp_domain(self.req2), True) - # self.assertEqual(is_akvoapp_domain(self.req3), False) - # self.assertEqual(is_akvoapp_domain(self.req5), False) - -# class PagesRouterMiddlewareTestCase(TestCase): -# -# """Testing the routing mechanism.""" -# -# def setUp(self): -# """Setup.""" -# self.factory = RequestFactory() -# self.mw = ReallySimpleRouterMiddleware() -# -# self.req1 = self.factory.get('/', {}, HTTP_HOST='rsr.akvo.org') -# self.req2 = self.factory.get('/', {}, HTTP_HOST='rsr.test.akvo.org') -# self.req3 = self.factory.get('/', {}, HTTP_HOST='rsr.uat.akvo.org') -# self.req4 = self.factory.get('/', {}, HTTP_HOST='rsr.localdev.akvo.org') -# self.req5 = self.factory.get('/', {}, HTTP_HOST='notfound.akvo.org') -# -# self.req5 = self.factory.get('/', {}, HTTP_HOST='akvoapp.org') -# self.req6 = self.factory.get('/', {}, HTTP_HOST='test.akvoapp.org') -# self.req7 = self.factory.get('/', {}, HTTP_HOST='uat.akvoapp.org') -# self.req8 = self.factory.get('/', {}, HTTP_HOST='localdev.akvoapp.org') -# self.req5 = self.factory.get('/', {}, HTTP_HOST='notfound.akvoapp.org') -# -# # RSR_DOMAIN = 'rsr.localdev.akvo.org' -# # AKVOAPP_DOMAIN = 'localakvoapp.org' -# -# def test_get_domain(self): -# """.""" -# self.assertEqual(get_domain(self.req0), "rsr.akvo.org") -# self.assertEqual(get_domain(self.req1), "rsr.akvo.org") -# self.assertEqual(get_domain(self.req2), "rsr.localdev.akvo.org") -# -# def test_process_request(self): -# """Test inbound.""" -# self.assertEqual(None, None) + _partner_site("invalid.{}".format(settings.AKVOAPP_DOMAIN)) + + def test_invalid_partner_site(self): + """.""" + invalid_resp = self.c.get('/') + self.assertRedirects(response=invalid_resp, expected_url=STOCK_RSR_NETLOC, + status_code=302, target_status_code=302) diff --git a/akvo/rsr/views/__init__.py b/akvo/rsr/views/__init__.py index ccceaa6c2c..517aa420d7 100644 --- a/akvo/rsr/views/__init__.py +++ b/akvo/rsr/views/__init__.py @@ -1,13 +1,15 @@ # -*- coding: utf-8 -*- """Akvo RSR is covered by the GNU Affero General Public License. -See more details in the license.txt file located at the root folder of the -Akvo RSR module. For additional details on the GNU license please -see < http://www.gnu.org/licenses/agpl.html >. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ + from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect def index(request): + """.""" return HttpResponseRedirect(reverse('project-directory', args=[])) diff --git a/akvo/settings/10-base.conf b/akvo/settings/10-base.conf index 31732cd0f7..da2bc65333 100644 --- a/akvo/settings/10-base.conf +++ b/akvo/settings/10-base.conf @@ -21,7 +21,6 @@ INSTALLED_APPS = ( 'django.contrib.humanize', 'django.contrib.messages', 'django.contrib.sessions', - 'django.contrib.sites', 'django.contrib.staticfiles', 'django.contrib.webdesign', 'akvo.codelists', @@ -63,7 +62,6 @@ AUTH_USER_MODEL = 'rsr.User' MIDDLEWARE_CLASSES = ( 'akvo.rsr.middleware.HostDispatchMiddleware', # 'akvo.rsr.middleware_old.PagesLocaleMiddleware', - # 'django.middleware.gzip.GZipMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.http.ConditionalGetMiddleware', From 1d027b03289a73f40ec979d5efa07513f8411f2a Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Thu, 9 Apr 2015 16:07:29 +0200 Subject: [PATCH 20/22] [#809 #1305] Fixed issue with piwik id --- akvo/rsr/templatetags/piwik_tags.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/akvo/rsr/templatetags/piwik_tags.py b/akvo/rsr/templatetags/piwik_tags.py index cfda464256..dad719fa5a 100644 --- a/akvo/rsr/templatetags/piwik_tags.py +++ b/akvo/rsr/templatetags/piwik_tags.py @@ -22,6 +22,8 @@ def piwik_tracking_code(context): """Try and use configured partner site Piwik values otherwise pull from settings.""" try: piwik_id = settings.PIWIK_SITE_ID, + if isinstance(piwik_id, tuple): + piwik_id = piwik_id[0] except AttributeError: raise ImproperlyConfigured('PIWIK_SITE_ID does not exist.') @@ -30,11 +32,10 @@ def piwik_tracking_code(context): except AttributeError: raise ImproperlyConfigured('PIWIK_URL does not exist.') - try: + if context['request'].rsr_page and context['request'].rsr_page.piwik_id: return { 'id': context['request'].rsr_page.piwik_id, - 'url': piwik_url} - except AttributeError: - pass + 'url': piwik_url + } return {'id': piwik_id, 'url': piwik_url} From a93ffad78088a1fff8503ae1789da22747a701b1 Mon Sep 17 00:00:00 2001 From: Daniel Karlsson Date: Thu, 9 Apr 2015 23:01:34 +0200 Subject: [PATCH 21/22] [#809 #1305] Fixed broken widgets. - Added correct piwik template tag - Added simple tests for widgets - Small syntax cleanup --- akvo/rsr/tests/pages/test_widgets.py | 52 ++++++++++++++++++++++++ akvo/rsr/views/widgets.py | 26 +++++++----- akvo/templates/base.html | 1 - akvo/templates/widgets/base.html | 3 +- akvo/templates/widgets/projects_map.html | 3 +- akvo/urls.py | 9 ++-- 6 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 akvo/rsr/tests/pages/test_widgets.py diff --git a/akvo/rsr/tests/pages/test_widgets.py b/akvo/rsr/tests/pages/test_widgets.py new file mode 100644 index 0000000000..73c11d9dda --- /dev/null +++ b/akvo/rsr/tests/pages/test_widgets.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. +""" + +from django.conf import settings +from django.test import Client, TestCase +from akvo.rsr.models import Project, Organisation + + +class PingWidgetsTest(TestCase): + + """Simple ping.""" + + def setUp(self): + """Setup.""" + self.c = Client(HTTP_HOST=settings.RSR_DOMAIN) + Project.objects.create(title="Test Project") + Organisation.objects.create(name="Partner1") + + def test_narrow(self): + """Ping /widgets/project-narrow.""" + p = Project.objects.get(title="Test Project") + response = self.c.get('/widgets/project-narrow/{}/'.format(p.id)) + self.assertEqual(response.status_code, 200) + + def test_cobranded_banner(self): + """Ping /widgets/cobranded-banner.""" + p = Project.objects.get(title="Test Project") + response = self.c.get('/widgets/cobranded-banner/{}/'.format(p.id)) + self.assertEqual(response.status_code, 200) + + def test_project_small(self): + """Ping /widgets/project-small.""" + p = Project.objects.get(title="Test Project") + response = self.c.get('/widgets/project-small/{}/'.format(p.id)) + self.assertEqual(response.status_code, 200) + + def test_project_map(self): + """Ping /widgets/projects/map.""" + o = Organisation.objects.get(name="Partner1") + response = self.c.get('/widgets/projects/map/?organisation_id={}'.format(o.id)) + self.assertEqual(response.status_code, 200) + + def test_project_list(self): + """Ping /widgets/projects/list.""" + o = Organisation.objects.get(name="Partner1") + response = self.c.get('/widgets/projects/list/?organisation_id={}'.format(o.id)) + self.assertEqual(response.status_code, 200) diff --git a/akvo/rsr/views/widgets.py b/akvo/rsr/views/widgets.py index ad40993167..4e805e0f54 100644 --- a/akvo/rsr/views/widgets.py +++ b/akvo/rsr/views/widgets.py @@ -1,22 +1,20 @@ # -*- coding: utf-8 -*- +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ -Akvo RSR is covered by the GNU Affero General Public License. -See more details in the license.txt file located at the root folder of the -Akvo RSR module. For additional details on the GNU license please see -< http://www.gnu.org/licenses/agpl.html >. -""" + from __future__ import absolute_import import random from django.shortcuts import get_object_or_404 from django.views.generic import TemplateView - from akvo.rsr.models import Organisation, Project __all__ = [ - 'GetWidgetView', 'ProjectMapView', 'CobrandedBannerView', 'ProjectNarrowView', @@ -24,7 +22,9 @@ class BaseWidgetView(TemplateView): - """Setup a common base widget""" + + """Setup a common base widget.""" + def get_context_data(self, **kwargs): context = super(BaseWidgetView, self).get_context_data(**kwargs) context['style'] = 'darkBG' @@ -34,16 +34,20 @@ def get_context_data(self, **kwargs): class ProjectBaseWidgetView(BaseWidgetView): - """Extends the base widget with a project from url""" + + """Extends the base widget with a project from url.""" + def get_context_data(self, **kwargs): context = super(ProjectBaseWidgetView, self).get_context_data(**kwargs) context['project'] = get_object_or_404( - Project, pk=self.kwargs['project_id']) + Project, pk=int(self.kwargs['project_id'])) return context class RandomBaseWidgetView(BaseWidgetView): - """Extends the base widget with random project""" + + """Extends the base widget with random project.""" + def get_context_data(self, **kwargs): context = super(RandomBaseWidgetView, self).get_context_data(**kwargs) org_id = self.request.GET.get('organisation_id', '0') diff --git a/akvo/templates/base.html b/akvo/templates/base.html index 8b96a19af2..ae67965a4d 100644 --- a/akvo/templates/base.html +++ b/akvo/templates/base.html @@ -102,7 +102,6 @@ e.style.display = 'none'; } - {% piwik_tracking_code %} diff --git a/akvo/templates/widgets/base.html b/akvo/templates/widgets/base.html index 1fdae29f1d..927b592739 100644 --- a/akvo/templates/widgets/base.html +++ b/akvo/templates/widgets/base.html @@ -10,7 +10,6 @@ {% block body %}{% endblock body %} -{# Piwik #} -{% tracking_code %} +{% piwik_tracking_code %} diff --git a/akvo/templates/widgets/projects_map.html b/akvo/templates/widgets/projects_map.html index fbda6ec002..18c2a8820a 100644 --- a/akvo/templates/widgets/projects_map.html +++ b/akvo/templates/widgets/projects_map.html @@ -32,7 +32,6 @@ Akvo.org - {# Piwik #} - {% tracking_code %} + {% piwik_tracking_code %} diff --git a/akvo/urls.py b/akvo/urls.py index 15e395fd5f..67e9a6bb1b 100644 --- a/akvo/urls.py +++ b/akvo/urls.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- -""" - Akvo RSR is covered by the GNU Affero General Public License. - See more details in the license.txt file located at the root folder of the - Akvo RSR module. For additional details on the GNU license please - see < http://www.gnu.org/licenses/agpl.html >. +"""Akvo RSR is covered by the GNU Affero General Public License. + +See more details in the license.txt file located at the root folder of the Akvo RSR module. +For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >. """ from akvo.api.urls import named_api From 3465e23ffdf49be4df270f9c27a034073da510af Mon Sep 17 00:00:00 2001 From: Kasper Brandt Date: Fri, 10 Apr 2015 10:16:20 +0200 Subject: [PATCH 22/22] [#809] Removed unneccesary prints for permissions --- akvo/rsr/management.py | 50 ------------------------------------------ akvo/utils.py | 4 +--- 2 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 akvo/rsr/management.py diff --git a/akvo/rsr/management.py b/akvo/rsr/management.py deleted file mode 100644 index f6f0dd9521..0000000000 --- a/akvo/rsr/management.py +++ /dev/null @@ -1,50 +0,0 @@ -from django.conf import settings -from django.contrib.auth.models import Permission -from django.contrib.contenttypes.models import ContentType -from django.db.models import get_app, get_models -from django.db.models.signals import post_syncdb - -if "akvo.rsr" in settings.INSTALLED_APPS: - from akvo.rsr import models as rsr - def create_limited_change_permissions(sender, **kwargs): - print "Adding RSR limited permissions" - print - models = [ - rsr.Organisation, rsr.Project, rsr.User, rsr.PartnerSite - ] - for model in models: - opts = model._meta - model_name = opts.object_name.lower() - permission, created = Permission.objects.get_or_create( - codename=u"rsr_limited_change_%s" % model_name, - defaults={ - 'name': u'RSR limited change %s' % model_name, - 'content_type_id': ContentType.objects.get_for_model(model).id, - } - ) - if created: - print 'Created RSR limited change %s Permission' % model_name - else: - print 'RSR limited change %s Permission already exists in the database' % model_name - - post_syncdb.connect(create_limited_change_permissions, sender=rsr) - - def remove_rest_api_permissions(sender, **kwargs): - """ Remove permissions for REST API.""" - app = get_app('rsr') - methods = ['post', 'put', 'patch', 'delete'] - for model in get_models(app): - opts = model._meta - model_name = opts.object_name.lower() - for method in methods: - try: - permission = Permission.objects.get( - codename="{}_{}_{}".format('rsr_rest', method, model_name) - ) - permission.delete() - print 'Deleted RSR rest API {} permission for {}'.format(method, model_name) - except: - print 'RSR rest API {} permission for {} already deleted'.format(method, model_name) - - - post_syncdb.connect(remove_rest_api_permissions, sender=rsr) diff --git a/akvo/utils.py b/akvo/utils.py index 4f75c49c4a..d3c1f14ebe 100644 --- a/akvo/utils.py +++ b/akvo/utils.py @@ -468,6 +468,4 @@ def codelist_value(model, instance, field, version=settings.IATI_VERSION): def check_auth_groups(group_names): for group_name in group_names: - group, created = Group.objects.get_or_create(name=group_name) - if created: - print "Created group => {}".format(group) + Group.objects.get_or_create(name=group_name)