<commit_before># -*- 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 .utils import add_log

from django.conf import settings
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import get_model, ObjectDoesNotExist

import datetime
import fields

FIELDS = [
    'title',
    'subtitle',
    'status',
    'project_plan_summary',
    'goals_overview',
    'background',
    'current_status',
    'target_group',
    'project_plan',
    'sustainability',
    'custom_fields',
    'planned_start_date',
    'actual_start_date',
    'planned_end_date',
    'actual_end_date',
    'current_image',
    'language',
    'currency',
    'hierarchy',
    'scope',
    'collaboration_type',
    'default_aid_type',
    'default_finance_type',
    'default_flow_type',
    'default_tied_status',
    'budget_items',
    'country_budget_items',
    'capital_spend',
    'transactions',
    'planned_disbursements',
    'partnerships',
    'related_projects',
    'contacts',
    'results',
    'conditions',
    'locations',
    'recipient_countries',
    'recipient_regions',
    'sectors',
    'policy_markers',
    'links',
    'documents',
    'legacy_data',
    'crs_add',
    'fss',
]


class IatiImportActivity(object):
    def set_start_date(self):
        """
        Set the start date of the project import.
        """
        self.project_import_log.start_date = datetime.datetime.now()
        self.project_import_log.save()

    def set_end_date(self):
        """
        Set the end date of the project import.
        """
        self.project_import_log.end_date = datetime.datetime.now()
        self.project_import_log.save()

    def set_status(self, status):
        """
        Set the status of the import

        :param status: Integer; based on the IATI project import status
        """
        self.project_import_log.status = status
        self.project_import_log.save()

    def publish(self):
        """
        Try to publish the project in case the project is not yet published. Unless an akvo:publish
        attribute is set to False in the 'iati-activity' element.
        """
        if self.project.is_published():
            return

        if '{%s}publish' % settings.AKVO_NS in self.activity.attrib.keys() and \
                self.activity.attrib['{%s}publish' % settings.AKVO_NS].lower() == 'false':
            return

        try:
            self.project.publishingstatus.status = 'published'
            self.project.publishingstatus.full_clean()
            self.project.publishingstatus.save()
        except ValidationError as e:
            message = u'Project could not be published: '
            message += str(e).replace("{'__all__': [", '').replace("u'", "'").replace(']}', '')
            add_log(self.iati_import, 'publish', message, self.project, 1)

    def log_changes(self):
        """
        Log the changes that have been made to the project in the LogEntry model.
        """
        if self.changes:
            message = u'IATI import, changed: '
            for change in self.changes:
                message += u'%s, ' % change
            message = message[:-2] + u'.'

            LogEntry.objects.log_action(
                user_id=self.user.pk,
                content_type_id=ContentType.objects.get_for_model(self.project).pk,
                object_id=self.project.pk,
                object_repr=self.project.__unicode__(),
                action_flag=CHANGE,
                change_message=message
            )

    def set_sync_owner(self):
        """
        Check if the project can be edited by the current reporting organisation and set
        the sync_owner.

        :return: Boolean; True if all checks are passed and False otherwise
        """
        sync_owner = self.project.sync_owner
        reporting_org_element = self.activity.find('reporting-org')

        if not reporting_org_element is None and 'ref' in reporting_org_element.attrib.keys():
            iati_org_id = reporting_org_element.attrib['ref']
            try:
                organisation = get_model('rsr', 'organisation').objects.get(iati_org_id=iati_org_id)
            except ObjectDoesNotExist:
                add_log(self.iati_import, 'reporting_org',
                        'Reporting organisation not present in RSR.', self.project, 1)
                return False

            if not organisation.can_become_reporting:
                add_log(self.iati_import, 'reporting_org',
                        'Reporting organisation not allowed to import projects in RSR.',
                        self.project, 1)
                return False

            if not self.created and sync_owner and sync_owner != organisation:
                add_log(self.iati_import, 'sync_owner',
                        'Project has a different sync_owner (%s).' % sync_owner.name,
                        self.project, 1)
                return False

            self.project.sync_owner = organisation
            self.project.save()
            return True

        add_log(self.iati_import, 'reporting_org',
                'Reporting organisation not correctly specified.', self.project, 1)
        return False

    def get_or_create_project(self):
        """
        Get an existing project or create a new project if no existing project can be found
        in the RSR database, based on the IATI identifier.

        :return: Tuple; (Project instance, Boolean indicating whether the project was created)
        """
        iati_identifier_element = self.activity.find('iati-identifier')
        if not iati_identifier_element is None and iati_identifier_element.text:
            iati_identifier = iati_identifier_element.text
        else:
            add_log(self.iati_import, 'iati_identifier', 'identifier not found', self.project, 1)
            return None, None<commit_msg>[#1770] Add secondary reporter<commit_after># -*- 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 .utils import add_log

from django.conf import settings
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import get_model, ObjectDoesNotExist

import datetime
import fields

FIELDS = [
    'title',
    'subtitle',
    'status',
    'project_plan_summary',
    'goals_overview',
    'background',
    'current_status',
    'target_group',
    'project_plan',
    'sustainability',
    'custom_fields',
    'planned_start_date',
    'actual_start_date',
    'planned_end_date',
    'actual_end_date',
    'current_image',
    'language',
    'currency',
    'hierarchy',
    'scope',
    'collaboration_type',
    'default_aid_type',
    'default_finance_type',
    'default_flow_type',
    'default_tied_status',
    'budget_items',
    'country_budget_items',
    'capital_spend',
    'transactions',
    'planned_disbursements',
    'partnerships',
    'related_projects',
    'contacts',
    'results',
    'conditions',
    'locations',
    'recipient_countries',
    'recipient_regions',
    'sectors',
    'policy_markers',
    'links',
    'documents',
    'legacy_data',
    'crs_add',
    'fss',
]


class IatiImportActivity(object):
    def set_start_date(self):
        """
        Set the start date of the project import.
        """
        self.project_import_log.start_date = datetime.datetime.now()
        self.project_import_log.save()

    def set_end_date(self):
        """
        Set the end date of the project import.
        """
        self.project_import_log.end_date = datetime.datetime.now()
        self.project_import_log.save()

    def set_status(self, status):
        """
        Set the status of the import

        :param status: Integer; based on the IATI project import status
        """
        self.project_import_log.status = status
        self.project_import_log.save()

    def publish(self):
        """
        Try to publish the project in case the project is not yet published. Unless an akvo:publish
        attribute is set to False in the 'iati-activity' element.
        """
        if self.project.is_published():
            return

        if '{%s}publish' % settings.AKVO_NS in self.activity.attrib.keys() and \
                self.activity.attrib['{%s}publish' % settings.AKVO_NS].lower() == 'false':
            return

        try:
            self.project.publishingstatus.status = 'published'
            self.project.publishingstatus.full_clean()
            self.project.publishingstatus.save()
        except ValidationError as e:
            message = u'Project could not be published: '
            message += str(e).replace("{'__all__': [", '').replace("u'", "'").replace(']}', '')
            add_log(self.iati_import, 'publish', message, self.project, 1)

    def log_changes(self):
        """
        Log the changes that have been made to the project in the LogEntry model.
        """
        if self.changes:
            message = u'IATI import, changed: '
            for change in self.changes:
                message += u'%s, ' % change
            message = message[:-2] + u'.'

            LogEntry.objects.log_action(
                user_id=self.user.pk,
                content_type_id=ContentType.objects.get_for_model(self.project).pk,
                object_id=self.project.pk,
                object_repr=self.project.__unicode__(),
                action_flag=CHANGE,
                change_message=message
            )

    def set_sync_owner(self):
        """
        Check if the project can be edited by the current reporting organisation and set
        the sync_owner.

        :return: Boolean; True if all checks are passed and False otherwise
        """
        sync_owner = self.project.sync_owner
        reporting_org_element = self.activity.find('reporting-org')

        if not reporting_org_element is None and 'ref' in reporting_org_element.attrib.keys():
            iati_org_id = reporting_org_element.attrib['ref']
            try:
                organisation = get_model('rsr', 'organisation').objects.get(iati_org_id=iati_org_id)
            except ObjectDoesNotExist:
                add_log(self.iati_import, 'reporting_org',
                        'Reporting organisation not present in RSR.', self.project, 1)
                return False

            if not organisation.can_become_reporting:
                add_log(self.iati_import, 'reporting_org',
                        'Reporting organisation not allowed to import projects in RSR.',
                        self.project, 1)
                return False

            if not self.created and sync_owner and sync_owner != organisation:
                add_log(self.iati_import, 'sync_owner',
                        'Project has a different sync_owner (%s).' % sync_owner.name,
                        self.project, 1)
                return False

            if 'secondary-reporter' in reporting_org_element.attrib.keys():
                if reporting_org_element.attrib['secondary-reporter'] == '1':
                    self.project.sync_owner_secondary_reporter = True
                elif reporting_org_element.attrib['secondary-reporter'] == '0':
                    self.project.sync_owner_secondary_reporter = False

            self.project.sync_owner = organisation
            self.project.save(update_fields=['sync_owner', 'sync_owner_secondary_reporter'])
            return True

        add_log(self.iati_import, 'reporting_org',
                'Reporting organisation not correctly specified.', self.project, 1)
        return False

    def get_or_create_project(self):
        """
        Get an existing project or create a new project if no existing project can be found
        in the RSR database, based on the IATI identifier.

        :return: Tuple; (Project instance, Boolean indicating whether the project was created)
        """
        iati_identifier_element = self.activity.find('iati-identifier')
        if not iati_identifier_element is None and iati_identifier_element.text:
            iati_identifier = iati_identifier_element.text
        else:
            add_log(self.iati_import, 'iati_identifier', 'identifier not found', self.project, 1)
            return None, None
{'fraction_non_alphanumeric': 0.09592529711375213, 'fraction_numerical': 0.001697792869269949, 'mean_word_length': 2.3083992851672197, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7576696', 'n_tokens_mistral': 3679, 'n_tokens_neox': 3560, 'n_words': 921}