Пример #1
0
 class MockView(BrowserView):
     template = Template("templates/example.pt")
     interface_override = Template(
         "overrides/interface/z3c.jbot.tests.templates.example.pt")
     http_override = Template(
         "overrides/http/z3c.jbot.tests.templates.example.pt")
     https_override = Template(
         "overrides/https/z3c.jbot.tests.templates.example.pt")
Пример #2
0
class Article10Alternate(BaseArticle2012):
    template = Template('pt/report-data-a8.pt')
    help_text = """ """

    @db.use_db_session('2012')
    def setup_data(self):
        descriptor = get_descriptor(self.descriptor)
        ok_ges_ids = set(descriptor.all_ids())

        t = sql.MSFD10Target
        # muids = [x.id for x in self.muids]
        muids = {m.id: m for m in self.muids}

        count, res = db.get_all_records(
            t,
            t.MarineUnitID.in_(muids.keys()),
            t.Topic == 'EnvironmentalTarget',
        )
        by_muid = defaultdict(list)

        for target_item in res:
            item = A10AlternateItem(target_item, ok_ges_ids)

            if item.needed:
                by_muid[target_item.MarineUnitID].append(item)

        self.rows = {}

        for muid, cols in by_muid.items():
            rows = []

            if not cols:
                continue

            for name in cols[0].keys():
                values = [c[name] for c in cols]
                row = Row(name, values)
                rows.append(row)

            self.rows[muids[muid]] = rows

    def __call__(self):
        self.setup_data()

        return self.template()
Пример #3
0
class SnapshotSelectForm(Form):
    template = Template('../pt/inline-form.pt')
    _updated = False

    @property
    def fields(self):
        snaps = getattr(self.context.context, 'snapshots', [])

        if snaps:
            default = snaps[-1][0]
        else:
            default = None

        dates = [SimpleTerm(x[0], x[0].isoformat(), x[0]) for x in snaps]

        field = Choice(title=u'Date of harvest',
                       __name__='sd',
                       vocabulary=SimpleVocabulary(dates),
                       required=False,
                       default=default)

        return Fields(field)

    def update(self):
        if not self._updated:
            Form.update(self)
            self._updated = True

    @buttonAndHandler(u'View snapshot', name='view')
    def apply(self, action):
        return

    # TODO: make a condition for this button
    @buttonAndHandler(u'Harvest new data', name='harvest')
    def harvest(self, action):
        data = self.context.get_data_from_db()

        self.context.context.snapshots.append((datetime.now(), data))

        self.request.response.redirect('./@@view-report-data-2018')
Пример #4
0
class Article10(BaseArticle2012):
    """ Article 10 implementation for nation descriptors data

    klass(self, self.request, self.country_code, self.descriptor,
          self.article, self.muids, self.colspan)

    TODO: we should also extract DescriptorCriterionIndicators from the file

    How do we show data?

    """

    help_text = """
    - we identify the filename for the original XML file, by looking at the
      MSFD10_Imports table. This is the same file that you can find in the
      report table header on this page.

    - we download this file from CDR and parse it.

    - we lookup all the "<DescriptorCriterionIndicator>" tags in the file and
      filter them according to the current descriptor. See

      https://raw.githubusercontent.com/eea/wise.msfd/master/src/wise/msfd/data/ges_terms.csv

      for the hierarchical definition table of descriptors to indicators and
      criterias. To achieve this we do the following:

        - we get the assigned country criterion indicators from the MarineDB
          2012 database (we use the MSFD_19a_10DescriptiorsCriteriaIndicators
          view)

        - we use the first part of the criterion indicator to match the
          available criterion ids for the current descriptor. This is because
          some DescriptorCriterionIndicator are in a format like:
          1.2.1-indicator 5.2B

    - for each of these DescriptorCriterionIndicator we build a column in the
      result table

    Notes, problems:
    ----------------

    - the threshold values are not included in the report XML in
    the form that they appear in the specification. We take them from the 2012
    A9 report, by matching the criterion id.

    - the Functional/Pressures/Habitats rows cannot be matched per criterion,
      as they are in the spreadsheet, neither by using the database MarineDB or
      the XML files. We read the database view
      MSFD_19b_10PhysicalChemicalFeatures where we match the target id, country
      and region and get a list of ids which we split by type (functional
      group, pressure, habitat, etc), but there's no way of matching to the
      criterion.
    """

    template = Template('pt/report-data-a10.pt')

    def get_article9_columns(self):
        """ Get the view for Article 9 2012, which contains the
        table with the data. This is needed because we show
        the Threshold values from article 9

        :return: article 9 view
        """
        ctx = self.context
        art = 'Art9'
        filename = ctx.get_report_filename(art)
        view = Article9(ctx, ctx.request, ctx.country_code,
                        ctx.country_region_code, ctx.descriptor, art,
                        ctx.muids)
        view.setup_data(filename)

        return view.cols

    def filtered_ges_components(self, seed):
        """ Returns a list of valid ges criterion indicator targets

        Can be something like "1.6.2-indicator 5.2B" or "3.1" or "D1"
        """
        descriptor = get_descriptor(self.descriptor)
        country_criterions = country_ges_components(self.country_code)

        res = set([self.descriptor])

        for d_id in descriptor.all_ids():
            if d_id in country_criterions:
                res.add(d_id)

        for crit in set(country_criterions + seed):
            crit_id = crit.split('-', 1)[0]

            if crit_id in descriptor.all_ids():
                res.add(crit)

        return sorted_by_criterion(res)

    def setup_data(self):
        self.article9_cols = self.get_article9_columns()
        filename = self.context.get_report_filename()

        if not isinstance(filename, tuple):
            filename = [filename]

        _cols = []
        _muids = []

        for fname in filename:
            text = get_xml_report_data(fname)

            if not text:
                self.rows = []

                return self.template()

            root = fromstring(text)

            def xp(xpath, node=root):
                return node.xpath(xpath, namespaces=NSMAP)

            muids = xp('//w:MarineUnitID/text()')
            count, res = db.get_marine_unit_id_names(list(set(muids)))

            labels = [ItemLabel(m, u'{} ({})'.format(t, m)) for m, t in res]

            # special case for PL where marine_unit_ids are not imported into DB
            # therefore we cannot get the labels for them
            if muids and not labels:
                labels = [ItemLabel(m, m) for m in set(muids)]

            _muids.extend(labels)
            muids = ItemList(labels)

            descriptor = get_descriptor(self.descriptor)
            self.descriptor_label = descriptor.title

            reported = xp("//w:DesriptorCriterionIndicator/text()")
            gcs = self.filtered_ges_components(reported)

            self.rows = []

            # wrap the target per MarineUnitID
            all_target_indicators = [
                TargetsIndicators(node) for node in xp('w:TargetsIndicators')
            ]
            cols = [
                A10Item(self, gc, all_target_indicators, self.country_code,
                        self.region_code, muids) for gc in gcs
            ]

            _cols.extend(cols)

        self.muids_labeled = sorted(_muids,
                                    key=lambda l: natural_sort_key(l.name))
        self.cols = _cols
        # unwrap the columns into rows

        for col in _cols:
            for name in col.keys():
                values = []

                for inner in _cols:
                    values.append(inner[name])

                raw_values = []
                vals = []
                for v in values:
                    raw_values.append(v)
                    vals.append(
                        self.context.translate_value(name, v,
                                                     self.country_code))

                row = RawRow(name, vals, raw_values)
                self.rows.append(row)

            break  # only need the "first" row

    def __call__(self):
        self.setup_data()

        return self.template()

    def auto_translate(self):
        # report_def = REPORT_DEFS[self.year][self.article]
        # translatables = report_def.get_translatable_fields()

        self.setup_data()

        translatables = self.context.TRANSLATABLES
        seen = set()

        for item in self.cols:
            for k in translatables:
                value = item[k]
                if not isinstance(value, basestring):
                    continue

                if value not in seen:
                    retrieve_translation(self.country_code, value)
                    seen.add(value)

        return ''
Пример #5
0
class Article8(BaseArticle2012):
    """ Article 8 implementation for nation descriptors data

    klass(self, self.request, self.country_code, self.descriptor,
          self.article, self.muids, self.colspan)
    """

    template = Template('pt/report-data-a8.pt')
    help_text = """
    - we identify the filename for the original XML file, by looking at the
        MSFD10_Imports table. This is the same file that you can find in the
        report table header on this page.

    - we download this file from CDR and parse it.

    - we try to match the type of file to one of two implementation: Article8a
      and Article8b.

    - We extract all "main" tags from the file and filter those tags that have
      matching criterias to the current descriptor, by using theis table:

      https://raw.githubusercontent.com/eea/wise.msfd/master/src/wise/msfd/data/ges_terms.csv

      We use the <Indicator> tag plus the <CriteriaType> tag to determine which
      parent main tag is ok for current descriptor.

      For Article8b we lookup the imported assessment in the database MarineDB,
      to be able to provide the related indicators. For each such indicator
      which we generate a table column.
    """

    def setup_data(self):
        filename = self.context.get_report_filename()

        if not isinstance(filename, tuple):
            filename = [filename]

        report_map = defaultdict(list)
        _xml_muids = []

        for fname in filename:
            text = get_xml_report_data(fname)
            root = fromstring(text)

            def xp(xpath, node=root):
                return node.xpath(xpath, namespaces=NSMAP)

            # TODO: should use declared set of marine unit ids
            xml_muids = sorted(set(xp('//w:MarineUnitID/text()')))
            _xml_muids.extend(xml_muids)

            self.rows = [
                Row('Reporting area(s) [MarineUnitID]',
                    [', '.join(set(xml_muids))]),
            ]

            # each of the following report tags can appear multiple times, once per
            # MarineUnitID. Each one can have multiple <AssessmentPI>,
            # for specific topics. An AssessmentPI can have multiple indicators

            root_tags = get_report_tags(root)

            ReportTag = None

            # basic algorthim to detect what type of report it is
            article = self.article

            if 'Nutrients' in root_tags:
                ReportTag = ReportTag8b
                article = 'Art8b'

            elif 'FunctionalGroupFeatures' in root_tags:
                ReportTag = ReportTag8a
                article = 'Art8a'

            if ReportTag is None:
                logger.warning("Unhandled report type?")
                self.rows = []

                return self.template()

            # override the default translatable
            fields = REPORT_DEFS[self.context.year][article]\
                .get_translatable_fields()
            self.context.TRANSLATABLES.extend(fields)

            for name in root_tags:
                nodes = xp('//w:' + name)

                for node in nodes:
                    try:
                        rep = ReportTag(node, NSMAP)
                    except:
                        # There are some cases when an empty node is reported
                        # and the ReportTag class cannot be initialized because
                        # MarineUnitID element is not present in the node
                        # see ../fi/bal/d5/art8/@@view-report-data-2012
                        # search for node MicrobialPathogens
                        continue
                        import pdb
                        pdb.set_trace()

                    # TODO for D7(maybe for other descriptors too)
                    # find a way to match the node with the descriptor
                    # because all reported criterias and indicators are GESOther

                    if rep.matches_descriptor(self.descriptor):
                        report_map[rep.marine_unit_id].append(rep)

        descriptor = get_descriptor(self.descriptor)
        ges_crits = [descriptor] + list(descriptor.criterions)

        # a bit confusing code, we have multiple sets of rows, grouped in
        # report_data under the marine unit id key.
        report_data = {}

        # TODO: use reported list of muids per country,from database
        for muid in _xml_muids:
            if muid not in report_map:
                logger.warning("MarineUnitID not reported: %s, %s, Article 8",
                               muid, self.descriptor)
                report_data[muid] = []

                continue

            m_reps = report_map[muid]

            if len(m_reps) > 1:
                logger.warning(
                    "Multiple report tags for this "
                    "marine unit id: %r", m_reps)

            rows = []

            for i, report in enumerate(m_reps):

                # if i > 0:       # add a splitter row, to separate reports
                #     rows.append(Row('', ''))
                cols = report.columns(ges_crits)

                for col in cols:
                    for name in col.keys():
                        values = []

                        for inner in cols:
                            values.append(inner[name])
                        translated_values = [
                            self.context.translate_value(
                                name, v, self.country_code) for v in values
                        ]
                        row = RawRow(name, translated_values, values)
                        rows.append(row)

                    break  # only need the "first" row, for headers

            report_data[muid] = rows

        res = {}

        muids = {m.id: m for m in self.muids}

        for mid, v in report_data.items():
            mlabel = muids.get(mid)
            if mlabel is None:
                logger.warning("Report for non-defined muids: %s", mid)
                mid = unicode(mid)
                mlabel = MarineReportingUnit(mid, mid)
            res[mlabel] = v

        # self.muids = sorted(res.keys())
        self.rows = res

    def __call__(self):
        self.setup_data()

        return self.template()

    def auto_translate(self):
        self.setup_data()
        translatables = self.context.TRANSLATABLES
        seen = set()

        for table in self.rows.items():
            muid, table_data = table

            for row in table_data:
                if not row:
                    continue
                if row.title not in translatables:
                    continue

                for value in row.raw_values:
                    if not isinstance(value, basestring):
                        continue
                    if value not in seen:
                        retrieve_translation(self.country_code, value)
                        seen.add(value)

        return ''
Пример #6
0
class Article34_2018(BaseArticle2012):
    """ Implementation for Article 3/4 2018 reported data
    """

    year = '2012'
    root = None

    template = Template('pt/report-data-secondary.pt')
    help_text = ""

    def __init__(self, context, request, country_code, region_code,
                 descriptor, article, muids, filename=None,
                 previous_mrus=None):

        # TODO: use previous_mrus to highlight this file MRUs according to edit
        # status: added or deleted
        super(Article34_2018, self).__init__(context, request, country_code,
                                             region_code, descriptor, article,
                                             muids)

        self.filename = filename
        self.previous_mrus = previous_mrus

    def get_report_file_root(self, filename=None):
        if self.root is None:
            self.setup_data()

        return self.root

    def setup_data(self):
        filename = self.filename
        text = get_xml_report_data(filename)
        self.root = fromstring(text)

        mru_nodes = xp('//w:GeographicalBoundariesID', self.root)
        description = xp('//w:Description', self.root)[0]

        # TODO: also send the previous file data
        main_node = A34Item_2018_main(
            self, self.request, description, mru_nodes, self.previous_mrus
        )
        self.translatable_extra_data = main_node.get_translatable_extra_data()
        self.available_mrus = main_node.available_mrus
        self.available_regions = main_node.available_regions
        self.rows = []

        # TODO: this code needs to be explained. It's hard to understand what
        # its purpose is

        for name in main_node.keys():
            values = []

            for inner in [main_node]:
                values.append(inner[name])

            raw_values = []
            vals = []

            for v in values:
                raw_values.append(v)
                vals.append(self.context.translate_value(
                    name, v, self.country_code))

            row = RawRow(name, vals, raw_values)
            self.rows.append(row)

        self.cols = [main_node]

    def __call__(self):
        if self.root is None:
            self.setup_data()

        return self.template()
Пример #7
0
class A34Item_2018_main(Item):
    mrus_template = Template('pt/mrus-table-art34.pt')
    TRANSLATABLES_EXTRA = ['MRU Name']

    def __init__(self, context, request, description,
                 mru_nodes, previous_mrus=None):

        super(A34Item_2018_main, self).__init__([])
        self.description = description
        self.context = context
        self.request = request

        attrs = [
            ('Member state description', self.member_state_descr),
            ('Region / subregion description', self.region_subregion),
            ('Subdivisions', self.subdivisions),
            ('Marine reporting units description', self.assessment_areas),
        ]

        for title, getter in attrs:
            self[title] = getter()
            setattr(self, title, getter())

        mrus = []

        for node in mru_nodes:
            item = A34Item_2018_mru(node)
            mrus.append(item)

        sorted_mrus = sorted(mrus, key=lambda x: x['Marine Reporting Unit'])
        self._mrus = sorted_mrus
        self.available_mrus = [x['Marine Reporting Unit'] for x in sorted_mrus]
        self.available_regions = set(
            [x['Region or subregion'] for x in sorted_mrus]
        )
        self.previous_mrus = previous_mrus or []
        item_labels = sorted_mrus and sorted_mrus[0].keys() or ""

        sorted_mrus = self.mrus_template(
            item_labels=item_labels,
            item_values=sorted_mrus,
            previous_mrus=self.previous_mrus,
            country_code=self.context.country_code,
            translate_value=self.translate_value
        )

        self['MRUs'] = sorted_mrus
        setattr(self, 'MRUs', sorted_mrus)

        # Region or subregion Member state    Area type   MRU ID  Marine
        # reporting unit  Marine reporting unit

    def get_translatable_extra_data(self):
        """ Get the translatable fields from the MRU nodes

        :return: a list of values to translate
        """
        res = []

        for row in self._mrus:
            for field in self.TRANSLATABLES_EXTRA:
                value = getattr(row, field, None)
                if not value:
                    continue

                res.append(value)

        return set(res)

    def translate_value(self, fieldname, value, source_lang):
        is_translatable = fieldname in self.TRANSLATABLES_EXTRA
        v = self.context.context.translate_view()

        return v.translate(source_lang=source_lang,
                           value=value,
                           is_translatable=is_translatable)

    def sort_mrus(self, cols):
        sorted_cols = sorted(
            cols, key=lambda _r: (
                _r['Member state'],
                _r['Region or subregion'],
                _r['Marine Reporting Unit'],
                _r['MRU Name']
            )
        )

        return sorted_cols

    def member_state_descr(self):
        text = xp('w:MemberState/text()', self.description)

        return text and text[0] or ''

    def region_subregion(self):
        text = xp('w:RegionSubregion/text()', self.description)

        return text and text[0] or ''

    def subdivisions(self):
        text = xp('w:Subdivisions/text()', self.description)

        return text and text[0] or ''

    def assessment_areas(self):
        text = xp('w:AssessmentAreas/text()', self.description)

        return text and text[0] or ''
Пример #8
0
class Article34(BaseArticle2012):
    """ Article 3 & 4 implementation

    klass(self, self.request, self.country_code, self.country_region_code,
            self.descriptor, self.article, self.muids)
    """

    root = None
    year = '2012'

    template = Template('pt/report-data-secondary.pt')
    help_text = ""

    def __init__(self, context, request, country_code, region_code,
                 descriptor, article,  muids, filename):

        super(Article34, self).__init__(context, request, country_code,
                                        region_code, descriptor, article,
                                        muids)

        self.filename = filename

    def sort_cols(self, cols):
        sorted_cols = sorted(
            cols, key=lambda _r: (
                _r['Region / subregion description'],
                _r['Area type'],
                _r['Marine Reporting Unit']
            )
        )

        return sorted_cols

    def setup_data(self):
        filename = self.filename
        text = get_xml_report_data(filename)
        self.root = fromstring(text)

        nodes = xp('//w:GeographicalBoundariesID', self.root)
        description = xp('//w:Description', self.root)[0]

        cols = []

        for node in nodes:
            item = A34Item(self, node, description)
            cols.append(item)

        sorted_cols = self.sort_cols(cols)

        self.rows = []

        for col in sorted_cols:
            for name in col.keys():
                values = []

                for inner in sorted_cols:
                    values.append(inner[name])

                raw_values = []
                vals = []

                for v in values:
                    raw_values.append(v)
                    vals.append(self.context.translate_value(
                        name, v, self.country_code))

                row = RawRow(name, vals, raw_values)
                self.rows.append(row)

            break       # only need the "first" row

        self.cols = sorted_cols

    def __call__(self):
        if self.root is None:
            self.setup_data()

        return self.template()
Пример #9
0
class ReportData2018Secondary(ReportData2018):
    implements(IReportDataViewSecondary)

    descriptor = 'Not linked'
    country_region_code = 'No region'

    Art3 = Template('pt/report-data-secondary-2018.pt')
    Art4 = Template('pt/report-data-secondary-2018.pt')
    Art7 = Template('pt/report-data-secondary-2018.pt')

    def article_name(self):
        get_art_name = super(ReportData2018Secondary, self).article_name

        if self.article not in ('Art3', 'Art4'):
            return get_art_name()

        art_name = '{} & {}'.format(get_art_name('Art3'), get_art_name('Art4'))

        return art_name

    def get_previus_url(self, grouped_urls, url):
        for region, group in grouped_urls.items():
            # find the right group for our url
            if url not in group:
                continue

            # if our url is the last from its group, it does not have previous
            # file
            if group[-1] == url:
                return None

            url_index = group.index(url)

            return group[url_index + 1]

    def get_report_metadata_from_view(self, view, filename):
        fileurl = get_report_file_url(filename)
        root = view.get_report_file_root(filename)

        reporters = date = None
        try:
            reporters = root.attrib['GeneratedBy']
            date = root.attrib['CreationDate']
        except:
            pass

        metadata = ReportingInformation2018(fileurl, reporters, date)

        return metadata

    @property
    def report_header_title(self):
        article = self.article
        if self.article in ('Art3', 'Art4'):
            article = 'Art3-4'

        title = "Member State report: {} / {}".format(
            self.country_name,
            article,
        )

        return title

    def get_template(self, article):
        article = article.replace('-', '')
        template = getattr(self, article, None)

        return template

    def get_implementation_view(self, filename, prev_filename):
        """ In other articles (8, 9, 10) for 2018 year,
        we get the data from the DB (MSFD2018_production)

        Here instead we will get the data from the report xml from CDR
        by initializing and calling the view's class to setup the data
        """

        klass = {
            'Art7': Article7_2018,
            'Art3': Article34_2018,
            'Art4': Article34_2018
        }.get(self.article)

        init_args = [
            self, self.request, self.country_code, self.country_region_code,
            self.descriptor, self.article, self.muids, filename
        ]

        if self.article in ['Art3', 'Art4'] and prev_filename:
            prev_view = klass(self, self.request, self.country_code,
                              self.country_region_code, self.descriptor,
                              self.article, self.muids, prev_filename)
            prev_view.setup_data()
            previous_mrus = prev_view.available_mrus
            init_args.append(previous_mrus)

        view = klass(*init_args)
        view.setup_data()

        return view

    def auto_translate(self):
        self.render_reportdata()
        seen = set()

        all_translatables = (self.translatable_data +
                             self.translatable_extra_data)

        for value in all_translatables:
            if not value:
                continue

            if not isinstance(value, basestring):
                continue

            if value not in seen:
                retrieve_translation(self.country_code, value)
                seen.add(value)

        messages = IStatusMessage(self.request)
        messages.add(
            u"Auto-translation initiated, please refresh "
            u"in a couple of minutes",
            type=u"info")

        url = self.context.absolute_url() + '/@@view-report-data-2018'
        return self.request.response.redirect(url)

    def get_translatable_data(self, view):
        res = []

        for row in view.rows:
            field_name = row.title

            if field_name not in self.TRANSLATABLES:
                continue

            res.extend(row.raw_values)

        return set(res)

    def render_reportdata(self):
        """
        1. Get all reported files under Article 7 or 3/4
        2. Render the data separately for all files
        3. Concat the rendered htmls into a single

        :return: rendered html
        """

        translatable_extra_data = []
        translatable_data = []

        template = self.get_template(self.article)
        urls = get_all_report_filenames(self.country_code, self.article)

        rendered_results = []

        # identify order of files, grouped by region. If multiple regions are
        # reported in a file, then just sort them by envelope release date.
        # once sorted, create view for each file. Each view can potentially get
        # a reference to the previous file data.

        grouped_urls = defaultdict(list)
        for url in urls:
            view = self.get_implementation_view(url, None)
            regions = "-".join(view.available_regions)
            grouped_urls[regions].append(url)

        for (index, url) in enumerate(urls):
            prev_url = self.get_previus_url(grouped_urls, url)

            # For article 3/4 2018, the data from previous "version" of the
            # file should also be sent. Then it will be possible to identify
            # which MRUs have been added/removed
            view = self.get_implementation_view(url, prev_url)
            translatable_extra_data.extend(view.translatable_extra_data)
            translatable_data.extend(self.get_translatable_data(view))

            report = self.get_report_metadata_from_view(view, url)
            # Report Header
            report_by = None
            report_date = get_envelope_release_date(url)

            if report:
                report_by = report.ContactOrganisation
                # report_date = report.ReportingDate

            res = []
            source_file = (url.rsplit('/', 1)[-1], url + '/manage_document')
            factsheet = get_factsheet_url(url)

            view()  # updates the view
            data = [Proxy2018(row, self) for row in view.cols]

            if self.article == 'Art7':
                data_by_mru = group_by_mru(data)
            else:
                data_by_mru = {'no mru': data}

            fields = get_report_definition(self.article).get_fields()

            for mru, rows in data_by_mru.items():
                _rows = items_to_rows(rows, fields)

                res.append((mru, _rows))

            report_header = self.report_header_template(
                title=(index == 0 and self.report_header_title or ''),
                factsheet=factsheet,
                # TODO: find out how to get info about who reported
                report_by=report_by,
                source_file=source_file,
                report_due=None,
                report_date=report_date.date(),
                help_text=self.help_text,
                multiple_source_files=False,
                show_navigation=index == 0,
            )

            rendered_results.append(
                template(data=res,
                         report_header=report_header,
                         show_navigation=False))

        self.translatable_extra_data = translatable_extra_data
        self.translatable_data = translatable_data

        res = "<hr/>".join(rendered_results)
        return res or "No data found"
Пример #10
0
class A34Item_2018_main(Item):
    mrus_template = Template('pt/mrus-table-art34.pt')
    TRANSLATABLES_EXTRA = ['MRU Name']

    def __init__(self,
                 context,
                 request,
                 description,
                 mru_nodes,
                 root,
                 previous_mrus=None,
                 show_mru_usage=False):

        super(A34Item_2018_main, self).__init__([])
        self.description = description
        self.root = root
        self.context = context
        self.request = request

        attrs = [
            ('Member state marine waters', self.member_state_descr),
            ('Region / subregion description', self.region_subregion),
            ('Subdivisions', self.subdivisions),
            ('Marine reporting units description', self.assessment_areas),
        ]

        for title, getter in attrs:
            self[title] = getter()
            setattr(self, title, getter())

        mrus = []

        for node in mru_nodes:
            item = A34Item_2018_mru(node, show_mru_usage)
            mrus.append(item)

        sorted_mrus = sorted(mrus, key=lambda x: x['Marine Reporting Unit'])
        self._mrus = sorted_mrus
        self.available_mrus = [x['Marine Reporting Unit'] for x in sorted_mrus]
        self.available_regions = set(
            [x['Region or subregion'] for x in sorted_mrus])
        self.previous_mrus = previous_mrus or []
        item_labels = sorted_mrus and sorted_mrus[0].keys() or ""

        sorted_mrus = self.mrus_template(
            item_labels=item_labels,
            item_values=sorted_mrus,
            previous_mrus=self.previous_mrus,
            country_code=self.context.country_code,
            translate_value=self.translate_value)

        self['MRUs'] = sorted_mrus
        setattr(self, 'MRUs', sorted_mrus)

        # Region or subregion Member state    Area type   MRU ID  Marine
        # reporting unit  Marine reporting unit

        cooperation_attrs = [
            ('Region/ subregion', self.coop_region_subregion()),
            ('Art. 8 countries involved',
             self.coop_by_params('Art8', 'CountriesInvolved')),
            ('Art. 8 nature of coordination',
             self.coop_by_params('Art8', 'NatureCoordination')),
            ('Art. 8 regional coherence',
             self.coop_by_params('Art8', 'RegionalCoherence')),
            ('Art. 8 regional coherence problems',
             self.coop_by_params('Art8', 'RegionalCoordinationProblems')),
            ('Art. 9 countries involved',
             self.coop_by_params('Art9', 'CountriesInvolved')),
            ('Art. 9 nature of coordination',
             self.coop_by_params('Art9', 'NatureCoordination')),
            ('Art. 9 regional coherence',
             self.coop_by_params('Art9', 'RegionalCoherence')),
            ('Art. 9 regional coherence problems',
             self.coop_by_params('Art9', 'RegionalCoordinationProblems')),
            ('Art. 10 countries involved',
             self.coop_by_params('Art10', 'CountriesInvolved')),
            ('Art. 10 nature of coordination',
             self.coop_by_params('Art10', 'NatureCoordination')),
            ('Art. 10 regional coherence',
             self.coop_by_params('Art10', 'RegionalCoherence')),
            ('Art. 10 regional coherence problems',
             self.coop_by_params('Art10', 'RegionalCoordinationProblems')),
        ]

        for title, data in cooperation_attrs:
            self[title] = data
            setattr(self, title, data)

    def get_translatable_extra_data(self):
        """ Get the translatable fields from the MRU nodes

        :return: a list of values to translate
        """
        res = []

        for row in self._mrus:
            for field in self.TRANSLATABLES_EXTRA:
                value = getattr(row, field, None)
                if not value:
                    continue

                res.append(value)

        return set(res)

    def translate_value(self, fieldname, value, source_lang):
        is_translatable = fieldname in self.TRANSLATABLES_EXTRA
        v = self.context.context.translate_view()

        return v.translate(source_lang=source_lang,
                           value=value,
                           is_translatable=is_translatable)

    def sort_mrus(self, cols):
        sorted_cols = sorted(cols,
                             key=lambda _r:
                             (_r['Member state'], _r['Region or subregion'],
                              _r['Marine Reporting Unit'], _r['MRU Name']))

        return sorted_cols

    def member_state_descr(self):
        text = xp('w:MemberState/text()', self.description)

        return text and text[0] or ''

    def region_subregion(self):
        text = xp('w:RegionSubregion/text()', self.description)

        return text and text[0] or ''

    def subdivisions(self):
        text = xp('w:Subdivisions/text()', self.description)

        return text and text[0] or ''

    def assessment_areas(self):
        text = xp('w:AssessmentAreas/text()', self.description)

        return text and text[0] or ''

    def coop_region_subregion(self):
        texts = xp('//w:Cooperation/w:RegionsSubRegions/text()', self.root)

        return texts and ' !!! '.join(set(texts)) or ''

    def coop_by_params(self, article, node_name):
        xpath = '//w:Cooperation[w:Topic = "{}"]' \
                '/w:{}/descendant-or-self::*/text()'.format(article, node_name)

        texts = xp(xpath, self.root)

        return texts and ', '.join(set(sorted(texts))) or ''
Пример #11
0
class NationalDescriptorSecondaryArticleView(NationalDescriptorArticleView):
    """"""

    assessment_data_2018_tpl = Template(
        './pt/assessment-data-2018-secondary.pt')
    assessment_header_template = Template(
        '../pt/assessment-header-secondary.pt')

    pdf_assessments = _extract_pdf_assessments()

    implements(INationaldescriptorSecondaryArticleView)
    _descriptor = 'Not linked'

    @property
    def country_region_code(self):
        return 'No region'

    @property
    def descriptor_obj(self):
        return 'Not linked'

    @property
    def has_assessment(self):
        """ Article 7 will be not assessed, we do not show the 2018 and
        2012 assessment tables
        """

        if self.article == 'Art7':
            return False

        return True

    def source_pdf_assessment(self):
        for row in self.pdf_assessments:
            country = row[0]
            if country != self.country_code:
                continue

            article = row[1]
            if article != self.article:
                continue

            url = row[2]

            return url

        return None

    def __call__(self):
        alsoProvides(self.request, IDisableCSRFProtection)

        if 'assessor' in self.request.form:
            assessors = self.request.form['assessor']

            if isinstance(assessors, list):
                assessors = ', '.join(assessors)
            self.context.saved_assessment_data.ass_new = assessors

        # BBB:

        context = self.context

        if not hasattr(context, 'saved_assessment_data') or \
                not isinstance(context.saved_assessment_data, PersistentList):
            context.saved_assessment_data = AssessmentData()

        # Assessment data 2012
        # descriptor_criterions = get_descriptor(self.descriptor).criterions
        descriptor_criterions = []

        country_name = self._country_folder.title

        try:
            db_data_2012 = get_assessment_data_2012_db(country_name,
                                                       self.descriptor,
                                                       self.article)
            assessments_2012 = filter_assessment_data_2012(
                db_data_2012,
                self.country_region_code,
                descriptor_criterions,
            )
            self.assessment_data_2012 = self.assessment_data_2012_tpl(
                data=assessments_2012)

            if assessments_2012.get(country_name):
                score_2012 = assessments_2012[country_name].score
                conclusion_2012 = assessments_2012[country_name].overall_ass
            else:  # fallback
                ctry = assessments_2012.keys()[0]
                score_2012 = assessments_2012[ctry].score
                conclusion_2012 = assessments_2012[ctry].overall_ass

            report_by, assessors, assess_date, source_file = \
                get_assessment_head_data_2012(self.article,
                                              self.country_region_code,
                                              self._country_folder.id)
        except:
            logger.exception("Could not get assessment data for 2012")
            self.assessment_data_2012 = ''
            score_2012 = 100
            conclusion_2012 = 'Not found'
            report_by, assessors, assess_date, source_file = [
                'Not found'
            ] * 3 + [('Not found', '')]

        # Assessment header 2012

        self.assessment_header_2012 = self.assessment_header_template(
            report_by=report_by,
            assessor_list=[],
            assessors=assessors,
            assess_date=assess_date,
            source_file=source_file,
            show_edit_assessors=False,
            show_file_version=False,
        )

        # Assessment data 2018
        data = self.context.saved_assessment_data.last()
        elements = self.questions[0].get_all_assessed_elements(
            self.descriptor_obj,
            country_name=self.country_name,
            country_code=self.country_code)
        article_weights = ARTICLE_WEIGHTS
        assessment = format_assessment_data(self.article, elements,
                                            self.questions, self.muids, data,
                                            self.descriptor_obj,
                                            article_weights, self)

        score_2012 = int(round(score_2012))
        conclusion_2012_color = CONCLUSION_COLOR_TABLE.get(score_2012, 0)
        change = int(
            assessment.phase_overall_scores.get_range_index_for_phase(
                'adequacy') - score_2012)

        self.assessment_data_2018_html = self.assessment_data_2018_tpl(
            assessment=assessment,
            score_2012=score_2012,
            conclusion_2012=conclusion_2012,
            conclusion_2012_color=conclusion_2012_color,
            change_since_2012=change,
            can_comment=self.can_comment)

        # Assessment header 2018
        report_by_2018 = u'Commission'
        # assessors_2018 = self.context.saved_assessment_data.assessors
        assessors_2018 = getattr(self.context.saved_assessment_data, 'ass_new',
                                 'Not assessed')
        assess_date_2018 = data.get('assess_date', u'Not assessed')
        source_file_2018 = ('To be addedd...', '.')

        can_edit = self.check_permission('wise.msfd: Edit Assessment')
        show_edit_assessors = self.assessor_list and can_edit

        self.assessment_header_2018_html = self.assessment_header_template(
            report_by=report_by_2018,
            assessor_list=self.assessor_list,
            assessors=assessors_2018,
            assess_date=assess_date_2018,
            source_file=source_file_2018,
            show_edit_assessors=show_edit_assessors,
            show_file_version=False,
        )

        return self.index()

    @property
    def title(self):
        return u"Commission assessment: {} / {} / 2018".format(
            self.country_title,
            self.article,
        )
Пример #12
0
class NationalDescriptorArticleView(BaseView, AssessmentDataMixin):
    implements(INationaldescriptorArticleView)
    section = 'national-descriptors'

    assessment_data_2012_tpl = Template('./pt/assessment-data-2012.pt')
    assessment_data_2018_tpl = Template('./pt/assessment-data-2018.pt')

    year = '2018'  # used by self.muids
    _questions = NAT_DESC_QUESTIONS

    @property
    def title(self):
        return u"Commission assessment / {} / 2018 / {} / {} / {} ".format(
            self.article,
            self.descriptor_title,
            self.country_title,
            self.country_region_name,
        )

    @property
    def criterias(self):
        return self.descriptor_obj.sorted_criterions()  # criterions

    @property
    def questions(self):
        qs = self._questions.get(self.article, [])

        return qs

    @db.use_db_session('2018')
    def get_file_version(self, date_assessed):
        """ Given the assessment date, returns the latest file
        """
        edit_url = self._country_folder.absolute_url() + '/edit'
        file_name = 'Date assessed not set'
        file_url = ''
        report_date = 'Not found'

        if not date_assessed:
            return file_name, edit_url, report_date, edit_url

        t = sql2018.ReportedInformation
        schemas = {
            'Art8': 'ART8_GES',
            'Art9': 'ART9_GES',
            'Art10': 'ART10_Targets',
        }
        count, data = db.get_all_records(t,
                                         t.CountryCode == self.country_code,
                                         t.Schema == schemas[self.article],
                                         order_by=t.ReportingDate)

        file_name = 'File not found'

        for row in data:
            if date_assessed >= row.ReportingDate:
                file_url = row.ReportedFileLink
                report_date = row.ReportingDate
            else:
                break

        if file_url:
            file_name = file_url.split('/')[-1]

        return file_name, file_url, report_date, edit_url

    def __call__(self):
        alsoProvides(self.request, IDisableCSRFProtection)

        if 'assessor' in self.request.form:
            assessors = self.request.form['assessor']

            if isinstance(assessors, list):
                assessors = ', '.join(assessors)
            self.context.saved_assessment_data.ass_new = assessors

        # BBB:

        context = self.context

        if not hasattr(context, 'saved_assessment_data') or \
                not isinstance(context.saved_assessment_data, PersistentList):
            context.saved_assessment_data = AssessmentData()

        # Assessment data 2012
        descriptor_criterions = get_descriptor(self.descriptor).criterions

        country_name = self._country_folder.title

        try:
            db_data_2012 = get_assessment_data_2012_db(country_name,
                                                       self.descriptor,
                                                       self.article)
            assessments_2012 = filter_assessment_data_2012(
                db_data_2012,
                self.country_region_code,  # TODO: this will need refactor
                descriptor_criterions,
            )

            self.assessment_data_2012 = self.assessment_data_2012_tpl(
                data=assessments_2012)

            if assessments_2012.get(country_name):
                score_2012 = assessments_2012[country_name].score
                conclusion_2012 = assessments_2012[country_name].overall_ass
            else:  # fallback
                ctry = assessments_2012.keys()[0]
                score_2012 = assessments_2012[ctry].score
                conclusion_2012 = assessments_2012[ctry].overall_ass

            report_by, assessors, assess_date, source_file = \
                get_assessment_head_data_2012(self.article,
                                              self.country_region_code,
                                              self._country_folder.id)
        except:
            logger.exception("Could not get assessment data for 2012")
            self.assessment_data_2012 = ''
            score_2012 = 0
            conclusion_2012 = 'Not found'
            report_by, assessors, assess_date, source_file = [
                'Not found'
            ] * 3 + [('Not found', '')]

        # Assessment header 2012

        self.assessment_header_2012 = self.assessment_header_template(
            report_by=report_by,
            assessor_list=[],
            assessors=assessors,
            assess_date=assess_date,
            source_file=source_file,
            show_edit_assessors=False,
            show_file_version=False,
        )

        # Assessment data 2018
        data = self.context.saved_assessment_data.last()
        elements = self.questions[0].get_all_assessed_elements(
            self.descriptor_obj, muids=self.muids)

        article_weights = ARTICLE_WEIGHTS
        assessment = format_assessment_data(self.article, elements,
                                            self.questions, self.muids, data,
                                            self.descriptor_obj,
                                            article_weights, self)

        assessment.phase_overall_scores.coherence = self.get_coherence_data(
            self.country_region_code, self.descriptor, self.article)

        # score_2012 = score_2012
        conclusion_2012_color = CONCLUSION_COLOR_TABLE.get(score_2012, 0)

        change = (assessment.phase_overall_scores.get_range_index_for_phase(
            'adequacy') - score_2012)

        # if 2018 adequacy is not relevant, change since 2012 is not relevant
        if assessment.phase_overall_scores.adequacy['conclusion'][0] == '-':
            change = 'Not relevant (-)'

        self.assessment_data_2018_html = self.assessment_data_2018_tpl(
            assessment=assessment,
            score_2012=score_2012,
            conclusion_2012=conclusion_2012,
            conclusion_2012_color=conclusion_2012_color,
            change_since_2012=change,
            can_comment=self.can_comment)

        # Assessment header 2018
        report_by_2018 = u'Commission'
        # assessors_2018 = self.context.saved_assessment_data.assessors
        assessors_2018 = getattr(self.context.saved_assessment_data, 'ass_new',
                                 'Not assessed')
        assess_date_2018 = data.get('assess_date', u'Not assessed')
        source_file_2018 = ('To be addedd...', '.')

        can_edit = self.check_permission('wise.msfd: Edit Assessment')
        show_edit_assessors = self.assessor_list and can_edit

        file_version = self.get_file_version(self.country_date_assessed)

        self.assessment_header_2018_html = self.assessment_header_template(
            report_by=report_by_2018,
            assessor_list=self.assessor_list,
            assessors=assessors_2018,
            assess_date=assess_date_2018,
            source_file=source_file_2018,
            show_edit_assessors=show_edit_assessors,
            show_file_version=True,
            file_version=file_version)

        return self.index()
Пример #13
0
class Article7(BaseArticle2012):
    """ Article 7 implementation for 2012 year

    klass(self, self.request, country_code, region_code,
          descriptor, article,  muids)
    """

    template = Template('pt/report-data-secondary.pt')
    help_text = ""

    def get_report_file_root(self):
        filename = self.context.get_report_filename()
        text = get_xml_report_data(filename)
        root = fromstring(text)

        return root

    def _make_item(self, node):
        item = A7Item(self, node)

        return item

    def setup_data(self):
        root = self.get_report_file_root()

        # basic algorthim to detect what type of report it is
        article = self.article

        # override the default translatable
        fields = REPORT_DEFS[self.context.year][article]\
            .get_translatable_fields()
        self.context.TRANSLATABLES.extend(fields)

        cols = []
        nodes = xp('//w:CompetentAuthority', root)

        for node in nodes:
            # filter empty nodes
            if not node.getchildren():
                continue

            item = self._make_item(node)
            cols.append(item)

        self.rows = []

        for col in cols:
            for name in col.keys():
                values = []

                for inner in cols:
                    values.append(inner[name])

                raw_values = []
                vals = []

                for v in values:
                    raw_values.append(v)
                    vals.append(
                        self.context.translate_value(name, v,
                                                     self.country_code))

                # values = [self.context.translate_value(name, value=v)
                #           for v in values]

                row = RawRow(name, vals, raw_values)
                self.rows.append(row)

            break  # only need the "first" row

        self.cols = cols

    def __call__(self):
        self.setup_data()

        return self.template()

    def auto_translate(self):
        try:
            self.setup_data()
        except AssertionError:
            return

        translatables = self.context.TRANSLATABLES
        seen = set()

        for row in self.rows:
            if not row:
                continue

            if row.title not in translatables:
                continue

            for value in row.raw_values:
                if not isinstance(value, basestring):
                    continue

                if value not in seen:
                    retrieve_translation(self.country_code, value)
                    seen.add(value)

        return ''
Пример #14
0
class ReportData2018(BaseView):
    implements(IReportDataView)

    report_year = '2018'  # used by cache key
    year = '2018'  # used in report definition and translation
    section = 'national-descriptors'
    help_texts = {
        'Art8': """
The data is retrieved from the MSFD2018_production.V_ART8_GES_2018 database
view, filtered by country code and ges component ids. If the current Descriptor
starts with 'D1.', we also append the 'D1' descriptor to the GES Component ids.

We use this table for the list of GES Components and the descriptor that they
belong to:

https://raw.githubusercontent.com/eea/wise.msfd/master/src/wise/msfd/data/ges_terms.csv
""",
        'Art9': """
The data is retrieved from the MSFD2018_production.V_ART9_GES_2018 database
view, filtered by country code and ges component ids. If the current Descriptor
starts with 'D1.', we also append the 'D1' descriptor to the GES Component ids.

We use this table for the list of GES Components and the descriptor that they
belong to:

https://raw.githubusercontent.com/eea/wise.msfd/master/src/wise/msfd/data/ges_terms.csv
""",
        'Art10': """
The data is retrieved from the MSFD2018_production.V_ART10_Targets_2018
database view. Because the GESComponent column is not reliable (the Netherlands
reported using the 1.1.3 GESComponent for all their records), we filter the
data using the Parameters and Features available for the current descriptor.

We use this file for the Descriptor to Parameters and Features association
table:

https://svn.eionet.europa.eu/repositories/Reportnet/Dataflows/MarineDirective/MSFD2018/Webforms/msfd2018-codelists.json
""",
        'Art3': "To be completed...",
        'Art4': "To be completed...",
        'Art7': "To be completed..."
    }

    @property
    def help_text(self):
        return self.help_texts[self.article]

    Art8 = Template('pt/report-data-multiple-muid.pt')
    Art9 = Template('pt/report-data-multiple-muid.pt')
    Art10 = Template('pt/report-data-multiple-muid.pt')
    # Art9 = Template('pt/report-data-single-muid.pt')

    subform = None  # used for the snapshot selection form

    @property
    def all_descriptor_ids(self):
        descr_class = get_descriptor(self.descriptor)
        all_ids = list(descr_class.all_ids())

        if self.descriptor.startswith('D1.'):
            all_ids.append('D1')

        all_ids = set(all_ids)

        return all_ids

    def _get_order_cols_Art8(self, descr):
        descr = descr.split('.')[0]
        criteria_priority = ('MarineReportingUnit', 'GESComponent', 'Criteria',
                             'Feature', 'Element', 'Element2', 'Element2Code',
                             'IntegrationRuleTypeParameter')

        default = (
            'MarineReportingUnit',
            'GESComponent',
            'Feature',
            'Element',
            'Element2',
            'Element2Code',
            'Criteria',
            'IntegrationRuleTypeParameter',
        )

        order_by = {
            'D2':
            criteria_priority,
            'D4':
            criteria_priority,
            'D5': (
                'MarineReportingUnit',
                'GESComponent',
                'Feature',
                'Criteria',
                'Element',
                'Element2',
                'Element2Code',
                'IntegrationRuleTypeParameter',
            ),
            'D6':
            default,
            'D7':
            criteria_priority,
            'D8':
            criteria_priority,
            'D11':
            criteria_priority,
            'default':
            default
        }

        return order_by.get(descr, order_by['default'])

    def _get_order_cols_Art10(self):
        order = ('TargetCode', 'Features', 'Element')

        return order

    def get_data_from_view_Art8(self):
        sess = db.session()
        t = sql2018.t_V_ART8_GES_2018

        descr_class = get_descriptor(self.descriptor)
        all_ids = list(descr_class.all_ids())

        if self.descriptor.startswith('D1.'):
            all_ids.append('D1')

        # muids = [x.id for x in self.muids]
        conditions = [
            t.c.CountryCode == self.country_code,
            # t.c.Region == self.country_region_code,
            # t.c.MarineReportingUnit.in_(muids),     #
            t.c.GESComponent.in_(all_ids)
        ]

        # Handle the case of Romania that submitted duplicate data,
        # where Element is empty, but Criteria has data
        if self.country_code != 'RO':
            conditions.append(
                or_(t.c.Element.isnot(None), t.c.Criteria.isnot(None)))
        else:
            conditions.append(t.c.Element.isnot(None))

        if self.country_code != 'DK':
            conditions.insert(1, t.c.Region == self.country_region_code)
        else:
            # Handle the case of Denmark that have submitted a lot of
            # information under the DK-TOTAL MRU, which doesn't have a region
            # attached.
            conditions.insert(
                1,
                or_(t.c.Region == 'NotReported',
                    t.c.Region == self.country_region_code))

        orderby = [
            getattr(t.c, x) for x in self._get_order_cols_Art8(self.descriptor)
        ]

        # groupby IndicatorCode
        q = sess\
            .query(t)\
            .filter(*conditions)\
            .order_by(*orderby)\
            .distinct()

        # For the following countries filter data by features
        # for other countries return all data
        country_filters = ('BE', )

        if self.country_code not in country_filters:
            return q

        ok_features = set([f.name for f in get_features(self.descriptor)])
        out = []

        for row in q:
            if not self.descriptor.startswith('D1.'):
                out.append(row)
                continue

            feats = set((row.Feature, ))

            if feats.intersection(ok_features):
                out.append(row)

        return out

    def get_data_from_view_Art10(self):
        t = sql2018.t_V_ART10_Targets_2018

        conditions = [t.c.CountryCode == self.country_code]

        if self.country_code != 'DK':
            conditions.insert(1, t.c.Region == self.country_region_code)
        else:
            # Handle the case of Denmark that have submitted a lot of
            # information under the DK-TOTAL MRU, which doesn't have a region
            # attached.
            conditions.insert(
                1,
                or_(t.c.Region == 'NotReported',
                    t.c.Region == self.country_region_code))

        count, res = db.get_all_records_ordered(t,
                                                self._get_order_cols_Art10(),
                                                *conditions)

        out = []

        # GESComponents contains multiple values separated by comma
        # filter rows by splitting GESComponents
        for row in res:
            ges_comps = getattr(row, 'GESComponents', ())
            ges_comps = set([g.strip() for g in ges_comps.split(',')])

            if ges_comps.intersection(self.all_descriptor_ids):
                out.append(row)

        if not self.descriptor.startswith('D1.'):
            return out

        # conditions = []
        # params = get_parameters(self.descriptor)
        # p_codes = [p.name for p in params]
        # conditions.append(t.c.Parameter.in_(p_codes))

        # Filtering results based on FeaturesSmart and other conditions
        # I don't think this code should be kept. Probably the edge case should
        # be documented. It makes it fragile and dependent on correct
        # definitions in FeaturesSmart. I think it's trying to avoid showing
        # too many results when the GESComponent has been incorectly reported
        # on the <Target> records.
        ok_features = set([f.name for f in get_features(self.descriptor)])
        out_filtered = []

        for row in out:
            # Because some Features are missing from FeaturesSmart
            # we consider 'D1' descriptor valid for all 'D1.x'
            # and we keep the data if 'D1' is present in the GESComponents
            # countries_filter = for these countries DO NOT filter by features
            ges_comps = getattr(row, 'GESComponents', ())
            countries_filter = ('RO', 'DK', 'CY', 'MT')
            if 'D1' in ges_comps and self.country_code not in countries_filter:
                out_filtered.append(row)
                continue

            feats = set(row.Features.split(','))

            if feats.intersection(ok_features):
                out_filtered.append(row)

        return out_filtered

    def get_data_from_view_Art9(self):

        t = sql2018.t_V_ART9_GES_2018

        descriptor = get_descriptor(self.descriptor)
        all_ids = list(descriptor.all_ids())

        if self.descriptor.startswith('D1.'):
            all_ids.append('D1')

        conditions = [
            t.c.CountryCode == self.country_code,
            t.c.GESComponent.in_(all_ids)
        ]

        if self.country_code != 'DK':
            conditions.insert(
                1,
                or_(t.c.Region == self.country_region_code,
                    t.c.Region.is_(None)))
        else:
            # Handle the case of Denmark that have submitted a lot of
            # information under the DK-TOTAL MRU, which doesn't have a region
            # attached.
            conditions.insert(
                1,
                or_(t.c.Region == 'NotReported',
                    t.c.Region == self.country_region_code,
                    t.c.Region.is_(None)))

        count, q = db.get_all_records_ordered(t, ('GESComponent', ),
                                              *conditions)

        ok_features = set([f.name for f in get_features(self.descriptor)])
        out = []

        # There are cases when justification for delay is reported
        # for a ges component. In these cases region, mru, features and
        # other fields are empty. Justification for delay should be showed
        # for all regions, mrus
        for row in q:
            if not row.Features:
                out.append(row)
                continue

            if not self.descriptor.startswith('D1.'):
                out.append(row)
                continue

            feats = set(row.Features.split(','))

            if feats.intersection(ok_features):
                out.append(row)

        return out

    def get_data_from_view(self, article):
        data = getattr(self, 'get_data_from_view_' + article)()

        return data

    @db.use_db_session('2018')
    @timeit
    def get_data_from_db(self):
        data = self.get_data_from_view(self.article)
        data = [Proxy2018(row, self) for row in data]

        if self.request.form.get('split-mru') and (len(data) > 2000):
            if self.muids:
                if getattr(self, 'focus_muid', None) is None:
                    self.focus_muid = self.muids[0].name

                self.focus_muids = self._get_muids_from_data(data)

        if self.article == 'Art8':
            order = self._get_order_cols_Art8(self.descriptor)
            data = consolidate_singlevalue_to_list(
                data,
                'IndicatorCode',
                order,
            )

            data_by_mru = group_by_mru(data)

        if self.article == 'Art10':
            # data_by_mru = group_by_mru(data)
            order = self._get_order_cols_Art10()
            data_by_mru = consolidate_singlevalue_to_list(
                data, 'MarineReportingUnit', order)
            if data_by_mru:
                data_by_mru = {"": data_by_mru}
            else:
                data_by_mru = {}

        if self.article == 'Art9':
            # data_by_mru = consolidate_date_by_mru(data_by_mru)
            data_by_mru = consolidate_singlevalue_to_list(
                data, 'MarineReportingUnit')
            if data_by_mru:
                data_by_mru = {"": data_by_mru}
            else:
                data_by_mru = {}
            insert_missing_criterions(data_by_mru, self.descriptor_obj)

        res = []

        fields = get_report_definition(self.article).get_fields()

        for mru, rows in data_by_mru.items():
            _rows = items_to_rows(rows, fields)

            res.append((mru, _rows))

        # resort the results by marine reporting unit
        res_sorted = sorted(res,
                            key=lambda r: natural_sort_key(r[0].__repr__()))

        return res_sorted

    def get_snapshots(self):
        """ Returns all snapshots, in the chronological order they were created
        """
        # TODO: fix this. I'm hardcoding it now to always use generated data
        db_data = self.get_data_from_db()
        snapshot = (datetime.now(), db_data)

        return [snapshot]

        # snapshots = getattr(self.context, 'snapshots', None)
        #
        # if snapshots is None:
        #     self.context.snapshots = PersistentList()
        #
        #     db_data = self.get_data_from_db()
        #     snapshot = (datetime.now(), db_data)
        #
        #     self.context.snapshots.append(snapshot)
        #     self.context.snapshots._p_changed = True
        #
        #     self.context._p_changed = True
        #
        #     return self.context.snapshots
        #
        # return snapshots

    def get_report_data(self):
        """ Returns the data to display in the template

        Returns a list of "rows (tuples of label: data)"
        """

        snapshots = self.get_snapshots()
        self.subform.update()
        fd, errors = self.subform.extractData()
        date_selected = fd['sd']

        data = snapshots[-1][1]

        if hasattr(self, 'focus_muid'):
            # filter the data based on selected muid
            # this is used to optmize display of really long data
            data = [t for t in data if t[0].name == self.focus_muid]

        if date_selected:
            filtered = [x for x in snapshots if x[0] == date_selected]

            if filtered:
                date, data = filtered[0]
            else:
                raise ValueError("Snapshot doesn't exist at this date")

        return data

    def _get_muids_from_data(self, data):
        muids = set()
        for row in data:
            o = getattr(row, '__o')
            muid = o.MarineReportingUnit
            muids.add(muid)

        return list(sorted(muids))

    # def get_muids_from_data(self, data):
    #     # TODO: this shouldn't exist anymore
    #     if isinstance(data[0][0], (unicode, str)):
    #         all_muids = sorted(set([x[0] for x in data]))
    #
    #         return ', '.join(all_muids)
    #
    #     all_muids = [x[0] for x in data]
    #     seen = []
    #     muids = []
    #
    #     for muid in all_muids:
    #         name = muid.name
    #
    #         if name in seen:
    #             continue
    #
    #         seen.append(name)
    #         muids.append(muid)
    #
    #     return ItemList(rows=muids)

    @db.use_db_session('2018')
    @timeit
    def get_report_metadata(self):
        """ Returns metadata about the reported information
        """
        t = sql2018.ReportedInformation
        schemas = {
            'Art8': 'ART8_GES',
            'Art9': 'ART9_GES',
            'Art10': 'ART10_Targets',
        }
        count, item = db.get_item_by_conditions(
            t,
            'ReportingDate',
            t.CountryCode == self.country_code,
            t.Schema == schemas[self.article],
            reverse=True,
        )
        return item

    @property
    def report_header_title(self):
        title = "Member State report / {} / 2018 / {} / {} / {}".format(
            self.article,
            self.descriptor_title,
            self.country_name,
            self.country_region_name,
        )

        return title

    def get_report_header(self):
        report = self.get_report_metadata()

        link = report_by = report_date = None
        if report:
            link = report.ReportedFileLink
            link = (link.rsplit('/', 1)[1], link)
            report_by = report.ContactOrganisation
            report_date = report.ReportingDate

        report_header = self.report_header_template(
            title=self.report_header_title,
            factsheet=None,
            # TODO: find out how to get info about who reported
            report_by=report_by,
            source_file=link,
            report_due='2018-10-15',
            report_date=report_date,
            help_text=self.help_text,
            multiple_source_files=False)

        return report_header

    @cache(get_reportdata_key, dependencies=['translation'])
    def render_reportdata(self):
        logger.info("Quering database for 2018 report data: %s %s %s %s",
                    self.country_code, self.country_region_code, self.article,
                    self.descriptor)

        data = self.get_report_data()
        report_header = self.get_report_header()
        template = self.get_template(self.article)

        return template(data=data, report_header=report_header)

    def data_to_xls(self, data):
        # Create a workbook and add a worksheet.
        out = BytesIO()
        workbook = xlsxwriter.Workbook(out, {'in_memory': True})

        for index, (wtitle, wdata) in enumerate(data):
            _wtitle = '{}_{}'.format(index + 1, unicode(wtitle)[:28])

            worksheet = workbook.add_worksheet(_wtitle)

            for i, (row_label, row_values) in enumerate(wdata):
                worksheet.write(i, 0, row_label.title)

                for j, v in enumerate(row_values):
                    v = unicode(v) or ''
                    transl = get_translated(v, self.country_code) or v
                    worksheet.write(i, j + 1, transl)

        workbook.close()
        out.seek(0)

        return out

    def download(self):
        xlsdata = self.get_report_data()

        xlsio = self.data_to_xls(xlsdata)
        sh = self.request.response.setHeader

        sh(
            'Content-Type', 'application/vnd.openxmlformats-officedocument.'
            'spreadsheetml.sheet')
        fname = "-".join([
            self.country_code, self.country_region_code, self.article,
            self.descriptor
        ])
        sh('Content-Disposition', 'attachment; filename=%s.xlsx' % fname)

        return xlsio.read()

    def auto_translate(self, data=None):
        if not data:
            data = self.get_report_data()

        # report_def = REPORT_DEFS[self.year][self.article]
        # translatables = report_def.get_translatable_fields()
        translatables = self.TRANSLATABLES
        seen = set()

        for table in data:
            muid, table_data = table

            for row in table_data:
                field, cells = row
                if field.name in translatables:
                    for value in cells:
                        if value not in seen:
                            retrieve_translation(self.country_code, value)
                            seen.add(value)

        messages = IStatusMessage(self.request)
        messages.add(
            u"Auto-translation initiated, please refresh "
            u"in a couple of minutes",
            type=u"info")

        url = self.context.absolute_url() + '/@@view-report-data-2018'
        return self.request.response.redirect(url)

    def get_template(self, article):
        template = getattr(self, article, None)

        return template

    @timeit
    def __call__(self):

        # allow focusing on a single muid if the data is too big
        if 'focus_muid' in self.request.form:
            self.focus_muid = self.request.form['focus_muid'].strip()
        # self.focus_muid = 'BAL-AS-EE-ICES_SD_29'

        self.content = ''
        template = self.get_template(self.article)

        if not template:
            return self.index()

        self.subform = self.get_form()

        if ('download' in self.request.form):  # and report_data
            return self.download()

        if 'translate' in self.request.form and self.can_view_assessment_data:
            return self.auto_translate()

        trans_edit_html = self.translate_view()()

        print "will render report"
        report_html = self.render_reportdata()
        self.report_html = report_html + trans_edit_html

        @timeit
        def render_html():
            return self.index()

        return render_html()

    def get_form(self):

        if not self.subform:
            form = SnapshotSelectForm(self, self.request)
            self.subform = form

        return self.subform
Пример #15
0
    def __call__(self):
        """ Article 3 & 4 reports are separated per regions
            This means we can have more than one report xml for a country
            one for each region

            Merge the data from each region, and display it in one table
        """

        # we treat Art 3 & 4 different because of multiple report files

        if self.article not in ('Art3', 'Art4'):
            return super(ReportData2012Secondary, self).__call__()

        template = Template('pt/report-data-view-art34.pt')
        report_header_template = Template('pt/report-data-header-art34.pt')
        regions = get_regions_for_country(self.country_code)

        filenames = [(r[0], r[1],
                      get_report_filename('2012', self.country_code, r[0],
                                          self.article, self.descriptor))
                     for r in regions]

        filenames = sorted(filenames,
                           key=lambda i: ordered_regions_sortkey(i[0]))

        trans_edit_html = self.translate_view()()

        reports = []
        report_data = []

        for region, region_name, filename in filenames:
            if not filename:
                continue

            url = get_report_file_url(filename)
            source_file = (filename, url + '/manage_document')
            factsheet = get_factsheet_url(url)

            view = Article34(self, self.request, self.country_code, region,
                             self.descriptor, self.article, self.muids,
                             filename)

            rendered_view = view()

            rep_info = self.get_reporting_information(filename=filename)
            report_header_data = self.get_report_header_data(
                rep_info.reporters, source_file, factsheet,
                rep_info.report_date)
            report_header = report_header_template(self,
                                                   self.request,
                                                   region=region_name,
                                                   **report_header_data)
            reports.append(report_header + rendered_view + trans_edit_html)

            report_data.append(
                (region, serialize_rows(view.rows), report_header_data))

        self.reports = reports

        if 'download' in self.request.form:

            return self.download_art7(report_data)

        return template(self, self.request)
Пример #16
0
class Article11(BaseArticle2012):
    """ Article 11 implementation for 2014 year

    klass(self, self.request, country_code, region_code,
          descriptor, article,  muids)

        1. Get the report filename with a sparql query
        2. With the filename get the report url from CDR
        3. Get the data from the xml file
    """

    # template = Template('pt/report-data-secondary.pt')
    template = Template('pt/report-data-art11.pt')
    help_text = ""
    available_regions = []
    translatable_extra_data = []
    is_regional = False

    def __init__(self,
                 context,
                 request,
                 country_code,
                 region_code,
                 descriptor,
                 article,
                 muids,
                 filenames=None):

        super(Article11,
              self).__init__(context, request, country_code, region_code,
                             descriptor, article, muids)
        self._filename = filenames

    @property
    def sort_order(self):
        order = ('MonitoringProgrammeName', 'Q4g_SubProgrammeID')

        return order

    def get_report_filename(self):
        if self._filename:
            return self._filename

        filename = get_report_filename(
            '2014',
            self.country_code,
            self.region_code,
            self.article,
            self.descriptor,
        )

        return filename

    def get_report_file_root(self, filename=None):
        if not filename:
            filename = self.get_report_filename()

        text = get_xml_report_data(filename)

        root = fromstring(text)

        return root

    def _make_item(self, mp_node, subprog_node, subprog_name):
        item = A11Item(self, mp_node, subprog_node, subprog_name)

        return item

    def auto_translate(self):
        try:
            self.setup_data()
        except AssertionError:
            return

        translatables = self.context.TRANSLATABLES
        seen = set()

        for row in self.rows:
            if not row:
                continue

            if row.field.name not in translatables:
                continue

            for value in row.raw_values:
                if not isinstance(value, basestring):
                    continue

                if value not in seen:
                    retrieve_translation(self.country_code, value)
                    seen.add(value)

        return ''

    def items_to_rows(self, items):
        rep_fields = self.context.get_report_definition()

        for field in rep_fields:
            field_name = field.name
            values = []

            for inner in items:
                values.append(inner[field_name])

            raw_values = []
            vals = []

            for v in values:
                raw_values.append(v)

                vals.append(
                    self.context.translate_value(field_name, v,
                                                 self.country_code))

            row = national_compoundrow(self.context, field, vals, raw_values)
            self.rows.append(row)

    def setup_data(self):
        descriptor_class = get_descriptor(self.descriptor)
        all_ids = descriptor_class.all_ids()
        self.descriptor_label = descriptor_class.title

        if self.descriptor.startswith('D1.'):
            all_ids.add('D1')

        fileurls = self._filename
        _mp_nodes = []
        _sub_prog_nodes = []

        # separate Monitoring Programmes from Sub Programmes
        for fileurl in fileurls:
            try:
                root = self.get_report_file_root(fileurl)
            except XMLSyntaxError:
                continue

            region = xp('//Region', root)

            if region:
                region = region[0].text

            if region not in self.context.regions:
                continue

            if root.tag == 'MON':
                nodes = xp('//MonitoringProgrammes/*', root)
                _mp_nodes.extend(nodes)

            if root.tag == 'MONSub':
                nodes = xp('//SubProgrammes/*', root)
                _sub_prog_nodes.extend(nodes)

        # filter duplicate MP nodes, only keep the latest
        mp_seen = []
        mp_nodes = []

        for mp_node in _mp_nodes:
            if mp_node.tag in mp_seen:
                continue

            mp_nodes.append(mp_node)

        # filter duplicate SubProg nodes, only keep the latest
        sub_prog_seen = []
        sub_prog_nodes = []

        for sub_node in _sub_prog_nodes:
            subprog_id = xp('./Q4g_SubProgrammeID/text()', sub_node)

            if subprog_id in sub_prog_seen:
                continue

            sub_prog_nodes.append(sub_node)

        items = []

        for mp in mp_nodes:
            # filter empty nodes
            if not mp.getchildren():
                continue

            # filter mp node by ges criteria
            ges_crit = xp('.//Q5a_RelevantGESCriteria', mp)
            if ges_crit:
                ges_crit_text = ges_crit[0].text
                ges_crit = (ges_crit_text and set(ges_crit_text.split(' '))
                            or set())

            if not all_ids.intersection(ges_crit):
                continue

            subprogrammes = xp('.//ReferenceSubProgramme', mp)

            for sub_prog in subprogrammes:
                subprog_id = xp('./SubMonitoringProgrammeID/text()', sub_prog)
                subprog_id = subprog_id[0].replace('.xml', '').strip()
                subp_name = xp('./SubMonitoringProgrammeName/text()', sub_prog)

                sub_prog_node = [
                    x for x in sub_prog_nodes
                    if xp('./Q4g_SubProgrammeID', x)[0].text == subprog_id
                ]
                sub_prog_node = (len(sub_prog_node) and sub_prog_node[0]
                                 or SUBEMPTY)

                item = self._make_item(mp, sub_prog_node, subp_name[0])
                items.append(item)

        self.rows = []

        items = sorted(items,
                       key=lambda i: [getattr(i, o) for o in self.sort_order])

        self.cols = items

        self.items_to_rows(items)

    def __call__(self):
        self.setup_data()

        return self.template(data=self.rows)
Пример #17
0
class Article8Alternate(BaseArticle2012):
    template = Template('pt/report-data-a8.pt')
    help_text = """ """

    implementations = {
        'D1': [
            A8aSpecies,
            A8aFunctional,
        ],
        'D1/D6': [
            A8aHabitat
        ],
        'D2': [
            A8bNIS,
        ],
        'D3': [
            A8bExtractionFishShellfish,
            A8bExtractionSeaweedMaerlOther,
        ],
        'D4': [
            A8aEcosystem,
            A8aPhysical,
            A8bAcidification,
        ],
        'D5': [
            A8bNutrient,
        ],
        'D6': [
            A8bPhysicalDamage
        ],
        'D7': [
            A8bHydrologicalProcessess
        ],
        'D8': [
            A8bPollutantEvents,
            A8bHazardousSubstancesD8
        ],
        'D9': [
            A8bHazardousSubstancesD9,
            A8bMicrobialPathogens
        ],
        'D10': [
            A8bLitter
        ],
        'D11': [
            A8bNoise
        ],
    }

    def setup_data(self):
        # descriptor = get_descriptor(self.descriptor)
        # ok_ges_ids = descriptor.all_ids()
        descriptor = self.descriptor

        if descriptor.startswith('D1.'):
            descriptor = 'D1'       # TODO: handle other cases

        self.rows = defaultdict(list)

        # {muid: {field_name: [values, ...], ...}
        res = defaultdict(lambda: OrderedDefaultDict())
        muids = {m.id: m for m in self.muids}

        for Klass in self.implementations[descriptor]:
            print 'Started Klass: %s' % (Klass.__name__)

            # Klass = self.implementations[descriptor][0]

            # count, res = db.get_all_records(
            #     Impl.mapper,
            #     Impl.mapper.MarineUnitID.in_(self.muids)
            # )

            by_muid = defaultdict(list)

            for item in Klass.items(self.descriptor, muids.keys()):
                by_muid[item.MarineUnitID].append(item)

            for muid, cols in by_muid.items():
                rows = []

                if not cols:
                    continue

                for name in cols[0].keys():
                    values = [c[name] for c in cols]
                    res[muid][name].extend(values)

        for muid, rows in res.items():
            for name, values in rows.items():
                row = Row(name, values)
                self.rows[muids[muid]].append(row)

    def __call__(self):
        self.setup_data()

        return self.template()
Пример #18
0
class Article11Compare(Article11):
    template = Template('pt/report-data-compare.pt')
    is_side_by_side = True

    def __init__(self,
                 context,
                 request,
                 country_code,
                 region_code,
                 descriptor,
                 article,
                 muids,
                 data_2020,
                 filenames=None):

        super(Article11Compare,
              self).__init__(context, request, country_code, region_code,
                             descriptor, article, muids, filenames)

        self.data_2020 = data_2020

    def auto_translate(self):
        try:
            self.setup_data()
        except AssertionError:
            return

        translatables = self.context.TRANSLATABLES
        seen = set()

        # initiate translation for 2014 data
        for row in self.rows:
            if not row:
                continue

            if row.title not in translatables:
                continue

            for value in row.raw_values:
                if not isinstance(value, basestring):
                    continue

                if value not in seen:
                    retrieve_translation(self.country_code, value)
                    seen.add(value)

        # initiate translation for 2020 data
        for row in self.data_2020[0][1]:
            field = row[0]

            if field.title not in translatables:
                continue

            values = row[1]

            for value in values:
                if not isinstance(value, basestring):
                    continue

                if value not in seen:
                    retrieve_translation(self.country_code, value)
                    seen.add(value)

        return ''

    def __call__(self):
        self.setup_data()

        return self.template(data=self.rows, data_2020=self.data_2020)
Пример #19
0
class Article8ESA(BaseArticle2012):
    # TODO not implemented, copy of Article 8
    """ Article 8 implementation for nation descriptors data

    klass(self, self.request, self.country_code, self.descriptor,
          self.article, self.muids, self.colspan)
    """

    template = Template('pt/report-data-a8.pt')
    help_text = ""

    def setup_data(self):

        filename = self.context.get_report_filename()
        text = get_xml_report_data(filename)
        root = fromstring(text)

        def xp(xpath, node=root):
            return node.xpath(xpath, namespaces=NSMAP)

        # TODO: should use declared set of marine unit ids
        xml_muids = sorted(set(xp('//w:MarineUnitID/text()')))

        self.rows = [
            Row('Reporting area(s) [MarineUnitID]',
                [', '.join(set(xml_muids))]),
        ]

        report_map = defaultdict(list)
        root_tags = get_report_tags(root)

        ReportTag = None

        # basic algorthim to detect what type of report it is
        article = self.article

        # override the default translatable
        fields = REPORT_DEFS[self.context.year][article]\
            .get_translatable_fields()
        self.context.TRANSLATABLES.extend(fields)

        for name in root_tags:
            nodes = xp('//w:' + name)

            for node in nodes:
                try:
                    rep = ReportTag(node, NSMAP)
                except:
                    # There are some cases when an empty node is reported
                    # and the ReportTag class cannot be initialized because
                    # MarineUnitID element is not present in the node
                    # see ../fi/bal/d5/art8/@@view-report-data-2012
                    # search for node MicrobialPathogens
                    continue
                    import pdb
                    pdb.set_trace()

                # TODO for D7(maybe for other descriptors too)
                # find a way to match the node with the descriptor
                # because all reported criterias and indicators are GESOther

                if rep.matches_descriptor(self.descriptor):
                    report_map[rep.marine_unit_id].append(rep)

        descriptor = get_descriptor(self.descriptor)
        ges_crits = [descriptor] + list(descriptor.criterions)

        # a bit confusing code, we have multiple sets of rows, grouped in
        # report_data under the marine unit id key.
        report_data = {}

        # TODO: use reported list of muids per country,from database

        for muid in xml_muids:
            if muid not in report_map:
                logger.warning("MarineUnitID not reported: %s, %s, Article 8",
                               muid, self.descriptor)
                report_data[muid] = []

                continue

            m_reps = report_map[muid]

            if len(m_reps) > 1:
                logger.warning(
                    "Multiple report tags for this "
                    "marine unit id: %r", m_reps)

            rows = []

            for i, report in enumerate(m_reps):

                # if i > 0:       # add a splitter row, to separate reports
                #     rows.append(Row('', ''))

                cols = report.columns(ges_crits)

                for col in cols:
                    for name in col.keys():
                        values = []

                        for inner in cols:
                            values.append(inner[name])
                        translated_values = [
                            self.context.translate_value(
                                name, v, self.country_code) for v in values
                        ]
                        row = RawRow(name, translated_values, values)
                        rows.append(row)

                    break  # only need the "first" row, for headers

            report_data[muid] = rows

        res = {}

        muids = {m.id: m for m in self.muids}

        for mid, v in report_data.items():
            mlabel = muids.get(mid)
            if mlabel is None:
                logger.warning("Report for non-defined muids: %s", mid)
                mid = unicode(mid)
                mlabel = MarineReportingUnit(mid, mid)
            res[mlabel] = v

        # self.muids = sorted(res.keys())
        self.rows = res

    def __call__(self):
        self.setup_data()

        return self.template()

    def auto_translate(self):
        self.setup_data()
        translatables = self.context.TRANSLATABLES
        seen = set()

        for table in self.rows.items():
            muid, table_data = table

            for row in table_data:
                if not row:
                    continue
                if row.title not in translatables:
                    continue

                for value in row.raw_values:
                    if not isinstance(value, basestring):
                        continue
                    if value not in seen:
                        retrieve_translation(self.country_code, value)
                        seen.add(value)

        return ''
Пример #20
0
class NationalDescriptorArticleView(BaseView, AssessmentDataMixin):
    implements(INationaldescriptorArticleView)
    section = 'national-descriptors'

    assessment_data_2012_tpl = Template('./pt/assessment-data-2012.pt')
    assessment_data_2018_tpl = Template('./pt/assessment-data-2018.pt')

    year = '2018'  # used by self.muids
    _questions = NAT_DESC_QUESTIONS

    @property
    def title(self):
        return u"Commission assessment / {} / 2018 / {} / {} / {} ".format(
            self.article,
            self.descriptor_title,
            self.country_title,
            self.country_region_name,
        )

    @property
    def criterias(self):
        return self.descriptor_obj.sorted_criterions()  # criterions

    @property
    def questions(self):
        qs = self._questions.get(self.article, [])

        return qs

    def __call__(self):

        if 'assessor' in self.request.form:
            assessors = self.request.form['assessor']

            if isinstance(assessors, list):
                assessors = ', '.join(assessors)
            self.context.saved_assessment_data.ass_new = assessors

        # BBB:

        context = self.context

        if not hasattr(context, 'saved_assessment_data') or \
                not isinstance(context.saved_assessment_data, PersistentList):
            context.saved_assessment_data = AssessmentData()

        # Assessment data 2012
        descriptor_criterions = get_descriptor(self.descriptor).criterions

        country_name = self._country_folder.title

        try:
            db_data_2012 = get_assessment_data_2012_db(country_name,
                                                       self.descriptor,
                                                       self.article)
            assessments_2012 = filter_assessment_data_2012(
                db_data_2012,
                self.country_region_code,  # TODO: this will need refactor
                descriptor_criterions,
            )

            self.assessment_data_2012 = self.assessment_data_2012_tpl(
                data=assessments_2012)

            if assessments_2012.get(country_name):
                score_2012 = assessments_2012[country_name].score
                conclusion_2012 = assessments_2012[country_name].overall_ass
            else:  # fallback
                ctry = assessments_2012.keys()[0]
                score_2012 = assessments_2012[ctry].score
                conclusion_2012 = assessments_2012[ctry].overall_ass

            report_by, assessors, assess_date, source_file = \
                get_assessment_head_data_2012(self.article,
                                              self.country_region_code,
                                              self._country_folder.id)
        except:
            logger.exception("Could not get assessment data for 2012")
            self.assessment_data_2012 = ''
            score_2012 = 100
            conclusion_2012 = 'Not found'
            report_by, assessors, assess_date, source_file = [
                'Not found'
            ] * 3 + [('Not found', '')]

        # Assessment header 2012

        self.assessment_header_2012 = self.assessment_header_template(
            report_by=report_by,
            assessor_list=[],
            assessors=assessors,
            assess_date=assess_date,
            source_file=source_file,
            show_edit_assessors=False,
        )

        # Assessment data 2018
        data = self.context.saved_assessment_data.last()
        elements = self.questions[0].get_all_assessed_elements(
            self.descriptor_obj, muids=self.muids)
        article_weights = ARTICLE_WEIGHTS
        assessment = format_assessment_data(self.article, elements,
                                            self.questions, self.muids, data,
                                            self.descriptor_obj,
                                            article_weights, self)
        assessment.phase_overall_scores.coherence = self.get_coherence_data(
            self.country_region_code, self.descriptor, self.article)

        score_2012 = int(round(score_2012))
        conclusion_2012_color = CONCLUSION_COLOR_TABLE.get(score_2012, 0)
        change = int(
            assessment.phase_overall_scores.get_range_index_for_phase(
                'adequacy') - score_2012)

        self.assessment_data_2018_html = self.assessment_data_2018_tpl(
            assessment=assessment,
            score_2012=score_2012,
            conclusion_2012=conclusion_2012,
            conclusion_2012_color=conclusion_2012_color,
            change_since_2012=change,
            can_comment=self.can_comment)

        # Assessment header 2018
        report_by_2018 = u'Commission'
        # assessors_2018 = self.context.saved_assessment_data.assessors
        assessors_2018 = getattr(self.context.saved_assessment_data, 'ass_new',
                                 'Not assessed')
        assess_date_2018 = data.get('assess_date', u'Not assessed')
        source_file_2018 = ('To be addedd...', '.')

        can_edit = self.check_permission('wise.msfd: Edit Assessment')
        show_edit_assessors = self.assessor_list and can_edit

        self.assessment_header_2018_html = self.assessment_header_template(
            report_by=report_by_2018,
            assessor_list=self.assessor_list,
            assessors=assessors_2018,
            assess_date=assess_date_2018,
            source_file=source_file_2018,
            show_edit_assessors=show_edit_assessors,
        )

        return self.index()