<commit_before># -*- coding: utf-8 -*-
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from openerp import models, fields, api
from itertools import groupby
from operator import attrgetter

class MrpBomLine(models.Model):
    _inherit = 'mrp.bom.line'

    product_id = fields.Many2one(required=False)
    product_tmpl_id = fields.Many2one(
        comodel_name='product.template', string='Product')
    attribute_value_ids = fields.Many2many(
        domain="[('id', 'in', possible_value_ids[0][2])]")
    possible_value_ids = fields.Many2many(
        comodel_name='product.attribute.value',
        compute='_compute_possible_attribute_values')
    product_uom_category = fields.Many2one(
        comodel_name='product.uom.categ', string='UoM category',
        compute="_compute_product_category")
    product_uom = fields.Many2one(
        domain="[('category_id', '=', product_uom_category)]")

    @api.depends('product_id', 'product_tmpl_id')
    def _compute_product_category(self):
        for line in self:
            line.product_uom_category = (
                line.product_id.uom_id.category_id or
                line.product_tmpl_id.uom_id.category_id)

    @api.depends('bom_id.product_tmpl_id',
                 'bom_id.product_tmpl_id.attribute_line_ids')
    def _compute_possible_attribute_values(self):
        for line in self:
            attr_values = self.env['product.attribute.value']
            for attr_line in line.bom_id.product_tmpl_id.attribute_line_ids:
                attr_values |= attr_line.value_ids
            line.possible_value_ids = attr_values.sorted()

    @api.multi
    def onchange_product_id(self, product_id, product_qty=0):
        res = super(MrpBomLine, self).onchange_product_id(
            product_id, product_qty=product_qty)
        if product_id:
            product = self.env['product.product'].browse(product_id)
            res['value']['product_tmpl_id'] = product.product_tmpl_id.id
        return res

    @api.multi
    @api.onchange('product_tmpl_id')
    def onchange_product_tmpl_id(self):
        if self.product_tmpl_id:
            self.product_uom = (self.product_id.uom_id or
                                self.product_tmpl_id.uom_id)
            return {'domain': {'product_id': [('product_tmpl_id', '=',
                                               self.product_tmpl_id.id)]}}
        return {'domain': {'product_id': []}}

class MrpBom(models.Model):
    _inherit = 'mrp.bom'

    def _check_product_suitable(self, check_attribs, component_attribs):
        """ Check if component is suitable for given attributes
        @param check_attribs: Attribute id list
        @param component_attribs: Component defined attributes to check
        @return: Component validity
        """
        getattr = attrgetter('attribute_id')
        for key, group in groupby(component_attribs, getattr):
            if not set(check_attribs).intersection([x.id for x in group]):
                return False
        return True

    def _skip_bom_line(self, line, product):
        today = fields.Date.context_today(self)
        if (line.date_start and
                line.date_start > today or
                line.date_stop and (line.date_stop < today)):
            return True
        # all bom_line_id variant values must be in the product
        if line.attribute_value_ids:
            production_attr_values = []
            if not product and self.env.context.get('production'):
                production = self.env.context['production']
                for attr_value in production.product_attribute_ids:
                    production_attr_values.append(attr_value.value.id)
                if not self._check_product_suitable(
                        production_attr_values,
                        line.attribute_value_ids):
                    return True
            elif not product or not self._check_product_suitable(
                    product.attribute_value_ids.ids,
                    line.attribute_value_ids):
                return True
        return False

    @api.model
    def _bom_find_prepare(self, bom_line, properties=None):
        if not bom_line.product_id:
            if not bom_line.type != "phantom":
                return self._bom_find(
                    product_tmpl_id=bom_line.product_tmpl_id.id,
                    properties=properties)
            else:
                return False
        return super(MrpBom, self)._bom_find_prepare(
            bom_line, properties=properties)

    @api.model
    def _prepare_consume_line(self, bom_line, quantity, factor=1):
        res = super(MrpBom, self)._prepare_consume_line(
            bom_line, quantity, factor=factor)
        if not bom_line.product_id:
            tmpl_id = bom_line.product_tmpl_id
            res['name'] = tmpl_id.name
            res['product_tmpl_id'] = tmpl_id.id
            production = self.env.context.get('production')
            if not production and\
                    self.env.context.get('active_model') == 'mrp.production':
                production = self.env['mrp.production'].browse(
                    self.env.context.get('active_id'))
            self.env.context.get('active_id')
            product_attribute_ids = (
                tmpl_id._get_product_attribute_ids_inherit_dict(
                    production.product_attribute_ids))
            comp_product = self.env['product.product']._product_find(
                tmpl_id, product_attribute_ids)
            res['product_id'] = comp_product and comp_product.id
        else:
            res['product_tmpl_id'] = bom_line.product_id.product_tmpl_id.id
            product_attribute_ids = (
                bom_line.product_id._get_product_attributes_values_dict())
        res['product_attribute_ids'] = map(
            lambda x: (0, 0, x), product_attribute_ids)
        for val in res['product_attribute_ids']:
            val = val[2]
            val['product_tmpl_id'] = res['product_tmpl_id']
            val['owner_model'] = 'mrp.production.product.line'
        return res

    @api.model
    def _get_bom_product_name(self, bom_line):
        if not bom_line.product_id:
            return bom_line.product_tmpl_id.name_get()[0][1]
        else:
            return super(MrpBom, self)._get_bom_product_name(bom_line)
<commit_msg>[FIX] mrp_product_variants: Fix error in skip_bom_line<commit_after># -*- coding: utf-8 -*-
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from openerp import models, fields, api
from itertools import groupby
from operator import attrgetter

class MrpBomLine(models.Model):
    _inherit = 'mrp.bom.line'

    product_id = fields.Many2one(required=False)
    product_tmpl_id = fields.Many2one(
        comodel_name='product.template', string='Product')
    attribute_value_ids = fields.Many2many(
        domain="[('id', 'in', possible_value_ids[0][2])]")
    possible_value_ids = fields.Many2many(
        comodel_name='product.attribute.value',
        compute='_compute_possible_attribute_values')
    product_uom_category = fields.Many2one(
        comodel_name='product.uom.categ', string='UoM category',
        compute="_compute_product_category")
    product_uom = fields.Many2one(
        domain="[('category_id', '=', product_uom_category)]")

    @api.depends('product_id', 'product_tmpl_id')
    def _compute_product_category(self):
        for line in self:
            line.product_uom_category = (
                line.product_id.uom_id.category_id or
                line.product_tmpl_id.uom_id.category_id)

    @api.depends('bom_id.product_tmpl_id',
                 'bom_id.product_tmpl_id.attribute_line_ids')
    def _compute_possible_attribute_values(self):
        for line in self:
            attr_values = self.env['product.attribute.value']
            for attr_line in line.bom_id.product_tmpl_id.attribute_line_ids:
                attr_values |= attr_line.value_ids
            line.possible_value_ids = attr_values.sorted()

    @api.multi
    def onchange_product_id(self, product_id, product_qty=0):
        res = super(MrpBomLine, self).onchange_product_id(
            product_id, product_qty=product_qty)
        if product_id:
            product = self.env['product.product'].browse(product_id)
            res['value']['product_tmpl_id'] = product.product_tmpl_id.id
        return res

    @api.multi
    @api.onchange('product_tmpl_id')
    def onchange_product_tmpl_id(self):
        if self.product_tmpl_id:
            self.product_uom = (self.product_id.uom_id or
                                self.product_tmpl_id.uom_id)
            return {'domain': {'product_id': [('product_tmpl_id', '=',
                                               self.product_tmpl_id.id)]}}
        return {'domain': {'product_id': []}}

class MrpBom(models.Model):
    _inherit = 'mrp.bom'

    def _check_product_suitable(self, check_attribs, component_attribs):
        """ Check if component is suitable for given attributes
        @param check_attribs: Attribute id list
        @param component_attribs: Component defined attributes to check
        @return: Component validity
        """
        getattr = attrgetter('attribute_id')
        for key, group in groupby(component_attribs, getattr):
            if not set(check_attribs).intersection([x.id for x in group]):
                return False
        return True

    def _skip_bom_line(self, line, product):
        today = fields.Date.context_today(self)
        if (line.date_start and
                line.date_start > today or
                line.date_stop and (line.date_stop < today)):
            return True
        # all bom_line_id variant values must be in the product
        if line.attribute_value_ids:
            production_attr_values = []
            if not product and self.env.context.get('production'):
                production = self.env.context['production']
                for attr_value in production.product_attribute_ids:
                    production_attr_values.append(attr_value.value_id.id)
                if not self._check_product_suitable(
                        production_attr_values,
                        line.attribute_value_ids):
                    return True
            elif not product or not self._check_product_suitable(
                    product.attribute_value_ids.ids,
                    line.attribute_value_ids):
                return True
        return False

    @api.model
    def _bom_find_prepare(self, bom_line, properties=None):
        if not bom_line.product_id:
            if not bom_line.type != "phantom":
                return self._bom_find(
                    product_tmpl_id=bom_line.product_tmpl_id.id,
                    properties=properties)
            else:
                return False
        return super(MrpBom, self)._bom_find_prepare(
            bom_line, properties=properties)

    @api.model
    def _prepare_consume_line(self, bom_line, quantity, factor=1):
        res = super(MrpBom, self)._prepare_consume_line(
            bom_line, quantity, factor=factor)
        if not bom_line.product_id:
            tmpl_id = bom_line.product_tmpl_id
            res['name'] = tmpl_id.name
            res['product_tmpl_id'] = tmpl_id.id
            production = self.env.context.get('production')
            if not production and\
                    self.env.context.get('active_model') == 'mrp.production':
                production = self.env['mrp.production'].browse(
                    self.env.context.get('active_id'))
            self.env.context.get('active_id')
            product_attribute_ids = (
                tmpl_id._get_product_attribute_ids_inherit_dict(
                    production.product_attribute_ids))
            comp_product = self.env['product.product']._product_find(
                tmpl_id, product_attribute_ids)
            res['product_id'] = comp_product and comp_product.id
        else:
            res['product_tmpl_id'] = bom_line.product_id.product_tmpl_id.id
            product_attribute_ids = (
                bom_line.product_id._get_product_attributes_values_dict())
        res['product_attribute_ids'] = map(
            lambda x: (0, 0, x), product_attribute_ids)
        for val in res['product_attribute_ids']:
            val = val[2]
            val['product_tmpl_id'] = res['product_tmpl_id']
            val['owner_model'] = 'mrp.production.product.line'
        return res

    @api.model
    def _get_bom_product_name(self, bom_line):
        if not bom_line.product_id:
            return bom_line.product_tmpl_id.name_get()[0][1]
        else:
            return super(MrpBom, self)._get_bom_product_name(bom_line)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
###############################################################################
#
# ODOO (ex OpenERP)
# Open Source Management Solution
# Copyright (C) 2001-2015 Micronaet S.r.l. (<http://www.micronaet.it>)
# Developer: Nicola Riolini @thebrush (<https://it.linkedin.com/in/thebrush>)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

import os
import sys
import logging
import openerp
import xlsxwriter # XLSX export
import openerp.addons.decimal_precision as dp
from openerp.osv import fields, osv, expression, orm
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from openerp import SUPERUSER_ID
from openerp import tools
from openerp.tools.translate import _
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
    DEFAULT_SERVER_DATETIME_FORMAT,
    DATETIME_FORMATS_MAP,
    float_compare)

_logger = logging.getLogger(__name__)

class StockStatusPrintImageReportWizard(orm.TransientModel):
    ''' Wizard for print stock status
    '''
    _name = 'stock.status.print.image.report.wizard'

    def extract_xls_inventory_file(self, cr, uid, ids, data=None,
            context=None):
        ''' Extract inventory as XLS extranal files every category in different
            page
        '''
        # ---------------------------------------------------------------------
        # Utility:
        # ---------------------------------------------------------------------
        def write_header(current_WS, header):
            ''' Write header in first line:
            '''
            col = 0
            for title in header:
                current_WS.write(0, col, title)
                col += 1
            return

        # ---------------------------------------------------------------------
        #                        XLS log export:
        # ---------------------------------------------------------------------
        filename = '/home/administrator/photo/xls/inventory_table.xlsx'
        WB = xlsxwriter.Workbook(filename)

        # ---------------------------------------------------------------------
        # Search all inventory category:
        # ---------------------------------------------------------------------
        inv_pool = self.pool.get('product.product.inventory.category')
        inv_ids = inv_pool.search(cr, uid, [], context=context)

        # ---------------------------------------------------------------------
        # Create work sheet:
        # ---------------------------------------------------------------------
        header = ['DB', 'CODICE', 'DESCRIZIONE', 'UM', 'CAT. STAT.',
            'CATEGORIA', 'FORNITORE', 'ESISTENZA']

        # Create elemnt for empty category:
        WS = {
            #ID: worksheet, counter
            0: [WB.add_worksheet('Non assegnati'), 1],
            }
        write_header(WS[0][0], header)

        # Create all others category:
        for category in inv_pool.browse(
                cr, uid, inv_ids, context=context):
            WS[category.id] = [WB.add_worksheet(category.name), 1]
            write_header(WS[category.id][0], header)

        # ---------------------------------------------------------------------
        # Prepare BOM check
        # ---------------------------------------------------------------------
        line_pool = self.pool.get('mrp.bom.line')
        line_ids = line_pool.search(cr, uid, [
            ('bom_id.bom_category', 'in', ('parent', 'dynamic', 'half')),
            ], context=context)

        in_bom_ids = [item.product_id.id for item in line_pool.browse(
            cr, uid, line_ids, context=context)]

        # ---------------------------------------------------------------------
        # Populate product in correct page
        # ---------------------------------------------------------------------
        for product in self.pool.get(
                'product.product').stock_status_report_get_object(
                    cr, uid, data=data, context=context):
            if product.inventory_category_id.id in WS:
                record = WS[product.inventory_category_id.id]
            else:
                record = WS[0]

            # Write data in correct WS:
            record[0].write(record[1], 0,
                'X' if product.id in in_bom_ids else '')
            record[0].write(record[1], 1, product.default_code)
            record[0].write(record[1], 2, product.name)
            record[0].write(record[1], 3, product.uom_id.name or '')
            record[0].write(record[1], 4, product.statistic_category or '')
            record[0].write(record[1], 5, product.categ_id.name or '')
            record[0].write(record[1], 6,
                product.seller_ids[0].name.name if product.seller_ids else (
                    product.first_supplier_id.name or ''))
            if data.get('with_stock', False):
                record[0].write(record[1], 7, product.mx_net_qty or '')
            record[1] += 1

        return True
    # -------------------------------------------------------------------------
    #                             Wizard button event
    # -------------------------------------------------------------------------
    def print_report(self, cr, uid, ids, context=None):
        ''' Print report product
        '''
        if context is None:
            context = {}

        wiz_proxy = self.browse(cr, uid, ids)[0]

        datas = {
            'wizard': True, # started from wizard
            'partner_id': wiz_proxy.partner_id.id,
            'partner_name': wiz_proxy.partner_id.name,
            'default_code': wiz_proxy.default_code or False,
            'categ_ids': [item.id for item in wiz_proxy.categ_ids],
            'categ_name': [item.name for item in wiz_proxy.categ_ids],
            'catalog_ids': [item.id for item in wiz_proxy.catalog_ids],
            'catalog_name': [item.name for item in wiz_proxy.catalog_ids],
            'status': wiz_proxy.status or False,
            'sortable': wiz_proxy.sortable or False,
            'mode': wiz_proxy.mode or False,
            'with_photo': wiz_proxy.with_photo,
            'with_stock': wiz_proxy.with_stock,
            }
        if wiz_proxy.statistic_category:
            datas['statistic_category'] = [
                item.strip() for item in (
                    wiz_proxy.statistic_category or '').split('|')]
        else:
            datas['statistic_category'] = False

        if datas['mode'] == 'status':
            report_name = 'stock_status_report'
        elif datas['mode'] == 'simple':
            report_name = 'stock_status_simple_report'
        elif datas['mode'] == 'inventory':
            report_name = 'stock_status_inventory_report'
        else: # inventory_xls
            return self.extract_xls_inventory_file(
                cr, uid, ids, datas, context=context)

        return {
            'type': 'ir.actions.report.xml',
            'report_name': report_name,
            'datas': datas,
            }

    _columns = {
        'partner_id': fields.many2one('res.partner', 'Supplier',
            domain=[
                ('supplier', '=', True),
                ('is_company', '=', True),
                ('is_address', '=', False),
                ]),
        'default_code': fields.char('Partial code', size=30),
        'statistic_category': fields.char('Statistic category (separ.: |)',
            size=50),
        'categ_ids': fields.many2many(
            'product.category', 'product_category_status_rel',
            'product_id', 'category_id',
            'Category'),
        'catalog_ids': fields.many2many(
            'product.product.catalog', 'product_catalog_status_rel',
            'product_id', 'catalog_id',
            'Catalog'),
        'status': fields.selection([
            ('catalog', 'Catalog'),
            ('out', 'Out catalog'),
            ('stock', 'Stock'),
            ('obsolete', 'Obsolete'),
            ('sample', 'Sample'),
            ('todo', 'Todo'),
            ], 'Gamma'),
        'sortable': fields.boolean('Sortable'),
        'with_photo': fields.boolean('With photo'),
        'with_stock': fields.boolean('With stock'),
        'mode': fields.selection([
            ('status', 'Stock status'),
            ('simple', 'Simple status'),
            ('inventory', 'Inventory'),
            ('inventory_xls', 'Inventory XLS (exported file not report)'),
            ], 'Mode', required=True)
        }

    _defaults = {
        'with_photo': lambda *x: True,
        'mode': lambda *x: 'status',
        }

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>change path<commit_after># -*- coding: utf-8 -*-
###############################################################################
#
# ODOO (ex OpenERP)
# Open Source Management Solution
# Copyright (C) 2001-2015 Micronaet S.r.l. (<http://www.micronaet.it>)
# Developer: Nicola Riolini @thebrush (<https://it.linkedin.com/in/thebrush>)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

import os
import sys
import logging
import openerp
import xlsxwriter # XLSX export
import openerp.addons.decimal_precision as dp
from openerp.osv import fields, osv, expression, orm
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from openerp import SUPERUSER_ID
from openerp import tools
from openerp.tools.translate import _
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
    DEFAULT_SERVER_DATETIME_FORMAT,
    DATETIME_FORMATS_MAP,
    float_compare)

_logger = logging.getLogger(__name__)

class StockStatusPrintImageReportWizard(orm.TransientModel):
    ''' Wizard for print stock status
    '''
    _name = 'stock.status.print.image.report.wizard'

    def extract_xls_inventory_file(self, cr, uid, ids, data=None,
            context=None):
        ''' Extract inventory as XLS extranal files every category in different
            page
        '''
        # ---------------------------------------------------------------------
        # Utility:
        # ---------------------------------------------------------------------
        def write_header(current_WS, header):
            ''' Write header in first line:
            '''
            col = 0
            for title in header:
                current_WS.write(0, col, title)
                col += 1
            return

        # ---------------------------------------------------------------------
        #                        XLS log export:
        # ---------------------------------------------------------------------
        filename = '/home/administrator/photo/output/inventory_table.xlsx'
        WB = xlsxwriter.Workbook(filename)

        # ---------------------------------------------------------------------
        # Search all inventory category:
        # ---------------------------------------------------------------------
        inv_pool = self.pool.get('product.product.inventory.category')
        inv_ids = inv_pool.search(cr, uid, [], context=context)

        # ---------------------------------------------------------------------
        # Create work sheet:
        # ---------------------------------------------------------------------
        header = ['DB', 'CODICE', 'DESCRIZIONE', 'UM', 'CAT. STAT.',
            'CATEGORIA', 'FORNITORE', 'ESISTENZA']

        # Create elemnt for empty category:
        WS = {
            #ID: worksheet, counter
            0: [WB.add_worksheet('Non assegnati'), 1],
            }
        write_header(WS[0][0], header)

        # Create all others category:
        for category in inv_pool.browse(
                cr, uid, inv_ids, context=context):
            WS[category.id] = [WB.add_worksheet(category.name), 1]
            write_header(WS[category.id][0], header)

        # ---------------------------------------------------------------------
        # Prepare BOM check
        # ---------------------------------------------------------------------
        line_pool = self.pool.get('mrp.bom.line')
        line_ids = line_pool.search(cr, uid, [
            ('bom_id.bom_category', 'in', ('parent', 'dynamic', 'half')),
            ], context=context)

        in_bom_ids = [item.product_id.id for item in line_pool.browse(
            cr, uid, line_ids, context=context)]

        # ---------------------------------------------------------------------
        # Populate product in correct page
        # ---------------------------------------------------------------------
        for product in self.pool.get(
                'product.product').stock_status_report_get_object(
                    cr, uid, data=data, context=context):
            if product.inventory_category_id.id in WS:
                record = WS[product.inventory_category_id.id]
            else:
                record = WS[0]

            # Write data in correct WS:
            record[0].write(record[1], 0,
                'X' if product.id in in_bom_ids else '')
            record[0].write(record[1], 1, product.default_code)
            record[0].write(record[1], 2, product.name)
            record[0].write(record[1], 3, product.uom_id.name or '')
            record[0].write(record[1], 4, product.statistic_category or '')
            record[0].write(record[1], 5, product.categ_id.name or '')
            record[0].write(record[1], 6,
                product.seller_ids[0].name.name if product.seller_ids else (
                    product.first_supplier_id.name or ''))
            if data.get('with_stock', False):
                record[0].write(record[1], 7, product.mx_net_qty or '')
            record[1] += 1

        return True
    # -------------------------------------------------------------------------
    #                             Wizard button event
    # -------------------------------------------------------------------------
    def print_report(self, cr, uid, ids, context=None):
        ''' Print report product
        '''
        if context is None:
            context = {}

        wiz_proxy = self.browse(cr, uid, ids)[0]

        datas = {
            'wizard': True, # started from wizard
            'partner_id': wiz_proxy.partner_id.id,
            'partner_name': wiz_proxy.partner_id.name,
            'default_code': wiz_proxy.default_code or False,
            'categ_ids': [item.id for item in wiz_proxy.categ_ids],
            'categ_name': [item.name for item in wiz_proxy.categ_ids],
            'catalog_ids': [item.id for item in wiz_proxy.catalog_ids],
            'catalog_name': [item.name for item in wiz_proxy.catalog_ids],
            'status': wiz_proxy.status or False,
            'sortable': wiz_proxy.sortable or False,
            'mode': wiz_proxy.mode or False,
            'with_photo': wiz_proxy.with_photo,
            'with_stock': wiz_proxy.with_stock,
            }
        if wiz_proxy.statistic_category:
            datas['statistic_category'] = [
                item.strip() for item in (
                    wiz_proxy.statistic_category or '').split('|')]
        else:
            datas['statistic_category'] = False

        if datas['mode'] == 'status':
            report_name = 'stock_status_report'
        elif datas['mode'] == 'simple':
            report_name = 'stock_status_simple_report'
        elif datas['mode'] == 'inventory':
            report_name = 'stock_status_inventory_report'
        else: # inventory_xls
            return self.extract_xls_inventory_file(
                cr, uid, ids, datas, context=context)

        return {
            'type': 'ir.actions.report.xml',
            'report_name': report_name,
            'datas': datas,
            }

    _columns = {
        'partner_id': fields.many2one('res.partner', 'Supplier',
            domain=[
                ('supplier', '=', True),
                ('is_company', '=', True),
                ('is_address', '=', False),
                ]),
        'default_code': fields.char('Partial code', size=30),
        'statistic_category': fields.char('Statistic category (separ.: |)',
            size=50),
        'categ_ids': fields.many2many(
            'product.category', 'product_category_status_rel',
            'product_id', 'category_id',
            'Category'),
        'catalog_ids': fields.many2many(
            'product.product.catalog', 'product_catalog_status_rel',
            'product_id', 'catalog_id',
            'Catalog'),
        'status': fields.selection([
            ('catalog', 'Catalog'),
            ('out', 'Out catalog'),
            ('stock', 'Stock'),
            ('obsolete', 'Obsolete'),
            ('sample', 'Sample'),
            ('todo', 'Todo'),
            ], 'Gamma'),
        'sortable': fields.boolean('Sortable'),
        'with_photo': fields.boolean('With photo'),
        'with_stock': fields.boolean('With stock'),
        'mode': fields.selection([
            ('status', 'Stock status'),
            ('simple', 'Simple status'),
            ('inventory', 'Inventory'),
            ('inventory_xls', 'Inventory XLS (exported file not report)'),
            ], 'Mode', required=True)
        }

    _defaults = {
        'with_photo': lambda *x: True,
        'mode': lambda *x: 'status',
        }

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before>import logging
import winreg

from nativeconfig.config.base_config import BaseConfig

LOG = logging.getLogger('nativeconfig')

ERROR_NO_MORE_ITEMS = 259
ERROR_NO_MORE_FILES = 18

def traverse_registry_key(key, sub_key):
    """
    Traverse registry key and yield one by one.

    @raise WindowsError: If key cannot be opened (e.g. does not exist).
    """
    current_key = winreg.OpenKey(key, sub_key, 0, winreg.KEY_ALL_ACCESS)

    try:
        i = 0

        while True:
            next_key = winreg.EnumKey(current_key, i)

            for k in traverse_registry_key(key, r'{}\{}'.format(sub_key, next_key)):
                yield k

            i += 1
    except OSError:
        yield sub_key

class RegistryConfig(BaseConfig):
    """
    Store config in Windows Registry.

    @cvar REGISTRY_KEY: Key in the registry where config will be stored.
    @cvar REGISTRY_PATH: Path relative to REGISTRY_KEY that points to the config.
    """
    LOG = LOG.getChild('RegistryConfig')
    REGISTRY_KEY = winreg.HKEY_CURRENT_USER

    def __init__(self):
        k = winreg.CreateKey(self.REGISTRY_KEY, self.REGISTRY_PATH)
        winreg.CloseKey(k)

        super(RegistryConfig, self).__init__()

    #{ BaseConfig

    def get_value_cache_free(self, name):
        try:
            with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH) as app_key:
                try:
                    value, value_type = winreg.QueryValueEx(app_key, name)

                    if not value_type == winreg.REG_SZ:
                        raise ValueError("Value must be of REG_SZ type!")

                    return value
                except OSError:
                    pass
        except:
            self.LOG.exception("Unable to get \"%s\" from the registry:", name)

        return None

    def set_value_cache_free(self, name, raw_value):
        try:
            if raw_value is not None:
                with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH, 0, winreg.KEY_WRITE) as app_key:
                    winreg.SetValueEx(app_key, name, 0, winreg.REG_SZ, raw_value)
            else:
                self.del_value_cache_free(name)
        except:
            self.LOG.exception("Unable to set \"%s\" in the registry:", name)

    def del_value_cache_free(self, name):
        try:
            try:
                for k in traverse_registry_key(self.REGISTRY_KEY, r'{}\{}'.format(self.REGISTRY_PATH, name)):
                    winreg.DeleteKey(self.REGISTRY_KEY, k)
            except OSError:
                with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH, 0, winreg.KEY_ALL_ACCESS) as app_key:
                    winreg.DeleteValue(app_key, name)
        except:
            self.LOG.info("Unable to delete \"%s\" from the registry:", name)

    def get_array_value_cache_free(self, name):
        try:
            with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH) as app_key:
                value, value_type = winreg.QueryValueEx(app_key, name)

                if not value_type == winreg.REG_MULTI_SZ:
                    raise ValueError("Value must be of REG_MULTI_SZ type!")

                return value
        except:
            self.LOG.info("Unable to get array \"%s\" from the registry:", name, exc_info=True)

        return None

    def set_array_value_cache_free(self, name, value):
        try:
            if value is not None:
                with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH, 0, winreg.KEY_WRITE) as app_key:
                    winreg.SetValueEx(app_key, name, 0, winreg.REG_MULTI_SZ, value)
            else:
                self.del_value_cache_free(name)
        except:
            self.LOG.exception("Unable to set \"%s\" in the registry:", name)

    def get_dict_value_cache_free(self, name):
        try:
            with winreg.OpenKey(self.REGISTRY_KEY, r'{}\{}'.format(self.REGISTRY_PATH, name), 0, winreg.KEY_ALL_ACCESS) as app_key:
                v = {}

                try:
                    i = 0
                    while True:
                        name, value, value_type = winreg.EnumValue(app_key, i)

                        if value_type != winreg.REG_SZ:
                            raise ("Value must be of REG_SZ type!")

                        if value is not None:
                            v[name] = value

                        i += 1
                except OSError as e:
                    if e.winerror != ERROR_NO_MORE_ITEMS and e.winerror != ERROR_NO_MORE_FILES:
                        raise
                    else:
                        pass  # end of keys

                return v
        except:
            self.LOG.info("Unable to get dict '%s' from the registry:")

        return None

    def set_dict_value_cache_free(self, name, value):
        try:
            self.del_value_cache_free(name)

            if value is not None:
                with winreg.CreateKey(self.REGISTRY_KEY, r'{}\{}'.format(self.REGISTRY_PATH, name)) as app_key:
                    for k, v in value.items():
                        winreg.SetValueEx(app_key, k, 0, winreg.REG_SZ, v)
        except:
            self.LOG.exception("Unable to set \"%s\" in the registry:", name)

    #}
<commit_msg>Fix missing argument required by formatting.<commit_after>import logging
import winreg

from nativeconfig.config.base_config import BaseConfig

LOG = logging.getLogger('nativeconfig')

ERROR_NO_MORE_ITEMS = 259
ERROR_NO_MORE_FILES = 18

def traverse_registry_key(key, sub_key):
    """
    Traverse registry key and yield one by one.

    @raise WindowsError: If key cannot be opened (e.g. does not exist).
    """
    current_key = winreg.OpenKey(key, sub_key, 0, winreg.KEY_ALL_ACCESS)

    try:
        i = 0

        while True:
            next_key = winreg.EnumKey(current_key, i)

            for k in traverse_registry_key(key, r'{}\{}'.format(sub_key, next_key)):
                yield k

            i += 1
    except OSError:
        yield sub_key

class RegistryConfig(BaseConfig):
    """
    Store config in Windows Registry.

    @cvar REGISTRY_KEY: Key in the registry where config will be stored.
    @cvar REGISTRY_PATH: Path relative to REGISTRY_KEY that points to the config.
    """
    LOG = LOG.getChild('RegistryConfig')
    REGISTRY_KEY = winreg.HKEY_CURRENT_USER

    def __init__(self):
        k = winreg.CreateKey(self.REGISTRY_KEY, self.REGISTRY_PATH)
        winreg.CloseKey(k)

        super(RegistryConfig, self).__init__()

    #{ BaseConfig

    def get_value_cache_free(self, name):
        try:
            with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH) as app_key:
                try:
                    value, value_type = winreg.QueryValueEx(app_key, name)

                    if not value_type == winreg.REG_SZ:
                        raise ValueError("Value must be of REG_SZ type!")

                    return value
                except OSError:
                    pass
        except:
            self.LOG.exception("Unable to get \"%s\" from the registry:", name)

        return None

    def set_value_cache_free(self, name, raw_value):
        try:
            if raw_value is not None:
                with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH, 0, winreg.KEY_WRITE) as app_key:
                    winreg.SetValueEx(app_key, name, 0, winreg.REG_SZ, raw_value)
            else:
                self.del_value_cache_free(name)
        except:
            self.LOG.exception("Unable to set \"%s\" in the registry:", name)

    def del_value_cache_free(self, name):
        try:
            try:
                for k in traverse_registry_key(self.REGISTRY_KEY, r'{}\{}'.format(self.REGISTRY_PATH, name)):
                    winreg.DeleteKey(self.REGISTRY_KEY, k)
            except OSError:
                with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH, 0, winreg.KEY_ALL_ACCESS) as app_key:
                    winreg.DeleteValue(app_key, name)
        except:
            self.LOG.info("Unable to delete \"%s\" from the registry:", name)

    def get_array_value_cache_free(self, name):
        try:
            with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH) as app_key:
                value, value_type = winreg.QueryValueEx(app_key, name)

                if not value_type == winreg.REG_MULTI_SZ:
                    raise ValueError("Value must be of REG_MULTI_SZ type!")

                return value
        except:
            self.LOG.info("Unable to get array \"%s\" from the registry:", name, exc_info=True)

        return None

    def set_array_value_cache_free(self, name, value):
        try:
            if value is not None:
                with winreg.OpenKey(self.REGISTRY_KEY, self.REGISTRY_PATH, 0, winreg.KEY_WRITE) as app_key:
                    winreg.SetValueEx(app_key, name, 0, winreg.REG_MULTI_SZ, value)
            else:
                self.del_value_cache_free(name)
        except:
            self.LOG.exception("Unable to set \"%s\" in the registry:", name)

    def get_dict_value_cache_free(self, name):
        try:
            with winreg.OpenKey(self.REGISTRY_KEY, r'{}\{}'.format(self.REGISTRY_PATH, name), 0, winreg.KEY_ALL_ACCESS) as app_key:
                v = {}

                try:
                    i = 0
                    while True:
                        name, value, value_type = winreg.EnumValue(app_key, i)

                        if value_type != winreg.REG_SZ:
                            raise ("Value must be of REG_SZ type!")

                        if value is not None:
                            v[name] = value

                        i += 1
                except OSError as e:
                    if e.winerror != ERROR_NO_MORE_ITEMS and e.winerror != ERROR_NO_MORE_FILES:
                        raise
                    else:
                        pass  # end of keys

                return v
        except:
            self.LOG.exception("Unable to get dict '%s' from the registry:", name)

        return None

    def set_dict_value_cache_free(self, name, value):
        try:
            self.del_value_cache_free(name)

            if value is not None:
                with winreg.CreateKey(self.REGISTRY_KEY, r'{}\{}'.format(self.REGISTRY_PATH, name)) as app_key:
                    for k, v in value.items():
                        winreg.SetValueEx(app_key, k, 0, winreg.REG_SZ, v)
        except:
            self.LOG.exception("Unable to set \"%s\" in the registry:", name)

    #}
<|endoftext|>


<commit_before>###########################################################################
#          (C) Vrije Universiteit, Amsterdam (the Netherlands)            #
#                                                                         #
# This file is part of AmCAT - The Amsterdam Content Analysis Toolkit     #
#                                                                         #
# AmCAT is free software: you can redistribute it and/or modify it under  #
# the terms of the GNU Affero General Public License as published by the  #
# Free Software Foundation, either version 3 of the License, or (at your  #
# option) any later version.                                              #
#                                                                         #
# AmCAT is distributed in the hope that it will be useful, but WITHOUT    #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public     #
# License for more details.                                               #
#                                                                         #
# You should have received a copy of the GNU Affero General Public        #
# License along with AmCAT.  If not, see <http://www.gnu.org/licenses/>.  #
###########################################################################

from django.core.urlresolvers import reverse

from amcat.scripts.actions.process_parsing import CheckParsing
from navigator.views.scriptview import ProjectScriptView
from amcat.models import ArticleSet, AnalysedArticle

from django.db.models import Count
from django_boolean_sum import BooleanSum

class ProcessParsingView(ProjectScriptView):
    script = CheckParsing
    success_template_name = "navigator/project/process_parsing.html"

    def get_template_names(self):
        if getattr(self, 'success', None):
            return [self.success_template_name]
        else:
            return [self.template_name]

    def get_context_data(self, **kwargs):
        context = super(ProcessParsingView, self).get_context_data(**kwargs)
        aset, plugin = [self.form.cleaned_data[x] for x in ("articleset", "plugin")]

        context["set"] = aset
        context["plugin"] = plugin
        context["totaln"] = aset.articles.count()

        q = (AnalysedArticle.objects.filter(article__articlesets_set=aset, plugin=plugin)
             .values("article__articlesets_set__project", "plugin_id", "article__articlesets_set")
             .annotate(assigned=Count("id"), done=BooleanSum("done"), error=BooleanSum("error")))

        context.update(q[0])
        print context

        return context

    def form_valid(self, form):
        result = self.run_form(form)
        return self.render_to_response(self.get_context_data(form=form, result=result, success=True))

    def get_form(self, form_class):
        form = super(ProcessParsingView, self).get_form(form_class)
        if self.request.method == 'GET':
            #form.fields['target_project'].queryset = qs
            # only show favourites
            qs = ArticleSet.objects.filter(favourite_of_projects=self.project.id)
            form.fields['articleset'].queryset=qs
            del form.fields['analysed_articles']
        return form

<commit_msg>bugfix<commit_after>###########################################################################
#          (C) Vrije Universiteit, Amsterdam (the Netherlands)            #
#                                                                         #
# This file is part of AmCAT - The Amsterdam Content Analysis Toolkit     #
#                                                                         #
# AmCAT is free software: you can redistribute it and/or modify it under  #
# the terms of the GNU Affero General Public License as published by the  #
# Free Software Foundation, either version 3 of the License, or (at your  #
# option) any later version.                                              #
#                                                                         #
# AmCAT is distributed in the hope that it will be useful, but WITHOUT    #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public     #
# License for more details.                                               #
#                                                                         #
# You should have received a copy of the GNU Affero General Public        #
# License along with AmCAT.  If not, see <http://www.gnu.org/licenses/>.  #
###########################################################################

from django.core.urlresolvers import reverse

from amcat.scripts.actions.process_parsing import CheckParsing
from navigator.views.scriptview import ProjectScriptView
from amcat.models import ArticleSet, AnalysedArticle

from django.db.models import Count
from django_boolean_sum import BooleanSum

# WvA: dit slaat eigenlijk nergens op. Ik dacht dat ik het resultaat van run moest gaan
# gebruiken, maar dat doe ik totaal niet. Ik zou gewoon kunnen redirecten naar een success form

# nog beter is een aparte "analysed set" pagina, met de stats, een refresh button, en
# een lijst van artikelen, klikbaar naar de 'analysed article' view.

# (maar niet nu :-))

class ProcessParsingView(ProjectScriptView):
    script = CheckParsing
    success_template_name = "navigator/project/process_parsing.html"

    def get_template_names(self):
        if getattr(self, 'success', None):
            return [self.success_template_name]
        else:
            return [self.template_name]

    def get_context_data(self, **kwargs):
        context = super(ProcessParsingView, self).get_context_data(**kwargs)
        if getattr(self, 'success', None):
            aset, plugin = [self.form.cleaned_data[x] for x in ("articleset", "plugin")]

            context["set"] = aset
            context["plugin"] = plugin
            context["totaln"] = aset.articles.count()

            q = (AnalysedArticle.objects.filter(article__articlesets_set=aset, plugin=plugin)
                 .values("article__articlesets_set__project", "plugin_id", "article__articlesets_set")
                 .annotate(assigned=Count("id"), done=BooleanSum("done"), error=BooleanSum("error")))
            context.update(q[0])
        return context

    def form_valid(self, form):
        result = self.run_form(form)
        return self.render_to_response(self.get_context_data(form=form, result=result, success=True))

    def get_form(self, form_class):
        form = super(ProcessParsingView, self).get_form(form_class)
        if self.request.method == 'GET':
            #form.fields['target_project'].queryset = qs
            # only show favourites
            qs = ArticleSet.objects.filter(favourite_of_projects=self.project.id)
            form.fields['articleset'].queryset=qs
            del form.fields['analysed_articles']
        return form

<|endoftext|>


<commit_before>import datetime

from django.apps import AppConfig
from django.core.checks import Error, register

class BoardingHouseDemoConfig(AppConfig):
    name = 'boardinghouse.contrib.demo'

    def ready(self):
        # Make sure our required setting exists.
        from django.conf import settings
        if not hasattr(settings, 'BOARDINGHOUSE_DEMO_PREFIX'):
            settings.BOARDINGHOUSE_DEMO_PREFIX = '__demo_'

        if not hasattr(settings, 'BOARDINGHOUSE_DEMO_PERIOD'):
            settings.BOARDINGHOUSE_DEMO_PERIOD = datetime.timedelta(31)

        from boardinghouse.contrib.demo import receivers  # NOQA

@register('settings')
def check_demo_prefix_stats_with_underscore(app_configs=None, **kwargs):
    from django.conf import settings

    if not settings.BOARDINGHOUSE_DEMO_PREFIX.startswith('_'):
        return [Error('BOARDINGHOUSE_DEMO_PREFIX must start with an underscore',
                      id='boardinghouse.contrib.demo.E001')]

@register('settings')
def check_demo_expiry_is_timedelta(app_configs=None, **kwargs):
    from django.conf import settings

    if not isinstance(settings.BOARDINGHOUSE_DEMO_PERIOD, datetime.timedelta):
        return [Error('BOARDINGHOUSE_DEMO_PERIOD must be a datetime.timedelta() instance',
                      id='boardinghouse.contrib.demo.E002')]
<commit_msg>Ensure system check functions return lists.<commit_after>import datetime

from django.apps import AppConfig
from django.core.checks import Error, register

class BoardingHouseDemoConfig(AppConfig):
    name = 'boardinghouse.contrib.demo'

    def ready(self):
        # Make sure our required setting exists.
        from django.conf import settings
        if not hasattr(settings, 'BOARDINGHOUSE_DEMO_PREFIX'):
            settings.BOARDINGHOUSE_DEMO_PREFIX = '__demo_'

        if not hasattr(settings, 'BOARDINGHOUSE_DEMO_PERIOD'):
            settings.BOARDINGHOUSE_DEMO_PERIOD = datetime.timedelta(31)

        from boardinghouse.contrib.demo import receivers  # NOQA

@register('settings')
def check_demo_prefix_stats_with_underscore(app_configs=None, **kwargs):
    from django.conf import settings

    if not settings.BOARDINGHOUSE_DEMO_PREFIX.startswith('_'):
        return [Error('BOARDINGHOUSE_DEMO_PREFIX must start with an underscore',
                      id='boardinghouse.contrib.demo.E001')]

    return []

@register('settings')
def check_demo_expiry_is_timedelta(app_configs=None, **kwargs):
    from django.conf import settings

    if not isinstance(settings.BOARDINGHOUSE_DEMO_PERIOD, datetime.timedelta):
        return [Error('BOARDINGHOUSE_DEMO_PERIOD must be a datetime.timedelta() instance',
                      id='boardinghouse.contrib.demo.E002')]

    return []
<|endoftext|>


<commit_before>from tasks.base_tasks import (RepoFileUnzipTask, GeoFile2TempTableTask, ColumnsTask, TagsTask,
                              TableTask, SimplifiedTempTableTask, TempTableTask)
from tasks.meta import current_session
from tasks.util import copyfile
from tasks.meta import GEOM_REF, OBSColumn, OBSTag, OBSTable
from tasks.tags import SectionTags, SubsectionTags, LicenseTags, BoundaryTags
from lib.timespan import get_timespan
from tasks.uk.shoreline import Shoreline

from collections import OrderedDict

class DownloadPostcodeAreas(RepoFileUnzipTask):

    # Source: https://datashare.is.ed.ac.uk/handle/10283/2405
    URL = 'https://datashare.is.ed.ac.uk/bitstream/handle/10283/2405/gb_postcode_areas.zip?sequence=1&isAllowed=y'

    def get_url(self):
        return self.URL

class ImportPostcodeAreas(GeoFile2TempTableTask):

    other_options = '-s_srs "EPSG:27700"'

    def requires(self):
        return DownloadPostcodeAreas()

    def input_files(self):
        return self.input().path

class ShorelineClippedPostcodeAreas(TempTableTask):
    def requires(self):
        return {
            'shoreline': Shoreline(),
            'postcode_area': ImportPostcodeAreas(),
        }

    def version(self):
        return 1

    def run(self):
        session = current_session()

        stmt = '''
                CREATE TABLE {output_table} AS
                SELECT name, label, ST_Intersection(pa.wkb_geometry, shore.the_geom) wkb_geometry
                  FROM {postcode_areas_table} pa,
                       {shoreline_table} shore
               '''.format(
                   output_table=self.output().table,
                   postcode_areas_table=self.input()['postcode_area'].table,
                   shoreline_table=self.input()['shoreline'].table,
               )

        session.execute(stmt)

class SimplifiedPostcodeAreas(SimplifiedTempTableTask):
    def requires(self):
        return ShorelineClippedPostcodeAreas()

class SourceTags(TagsTask):

    def version(self):
        return 1

    def tags(self):
        return[
            OBSTag(id='uk_ed_datashare_source',
                   name='Edinburgh DataShare',
                   type='source',
                   description='''
                               Edinburgh DataShare is a digital repository of research data produced at the University of Edinburgh, hosted by Information Services.
                               Edinburgh University researchers who have produced research data associated with an existing or forthcoming publication, or which has potential use for other researchers, are invited to upload their dataset for sharing and safekeeping.
                               A persistent identifier and suggested citation will be provided.
                               ''')
                   ]

class PostcodeAreasColumns(ColumnsTask):

    def version(self):
        return 1

    def requires(self):
        return {
            'subsections': SubsectionTags(),
            'sections': SectionTags(),
            'source': SourceTags(),
            'license': LicenseTags(),
            'boundary': BoundaryTags(),
        }

    def columns(self):
        input_ = self.input()
        license = input_['license']['uk_ed_datashare']
        source = input_['source']['uk_ed_datashare_source']
        boundary_type = input_['boundary']
        geom = OBSColumn(
            id='pa_geo',
            type='Geometry',
            name='GB Postcode Areas',
            description='''
                        Dataset contains polygons corresponding to the top level (Postcode Area) of the GB Postcode Hierarchy.
                        Thiessen polygons were generated from all records in OS OpenData Code-Point Open.
                        Resulting coverage was dissolved up to postcode area level and then clipped to GB extent of the realm using OS OpenData Boundary-Line.
                        Names of postcode areas were added from Wikipedia. GIS vector data.
                        This dataset was first accessioned in the EDINA ShareGeo Open repository on 2010-07-22 and migrated to Edinburgh DataShare on 2017-02-21.
                        ''',
            weight=8,
            tags=[input_['subsections']['boundary'], input_['sections']['uk'], source, license,
                  boundary_type['cartographic_boundary'], boundary_type['interpolation_boundary']]
        )
        geomref = OBSColumn(
            id='pa_id',
            type='Text',
            name='GB Postcode Area ID',
            weight=0,
            targets={geom: GEOM_REF}
        )
        geomname = OBSColumn(
            id='pa_name',
            type='Text',
            name='GB Postcode Area Name',
            weight=0,
            targets={geom: GEOM_REF}
        )

        return OrderedDict([
            ('the_geom', geom),
            ('pa_id', geomref),
            ('name', geomname),
        ])

class PostcodeAreas(TableTask):

    def requires(self):
        return {
            'geom_columns': PostcodeAreasColumns(),
            'data': SimplifiedPostcodeAreas(),
        }

    def version(self):
        return 1

    def table_timespan(self):
        return get_timespan('2017')

    # TODO: https://github.com/CartoDB/bigmetadata/issues/435
    def targets(self):
        return {
            OBSTable(id='.'.join([self.schema(), self.name()])): GEOM_REF,
        }

    def columns(self):
        input_ = self.input()
        cols = OrderedDict()
        cols.update(input_['geom_columns'])
        return cols

    def populate(self):
        session = current_session()
        session.execute('INSERT INTO {output} '
                        'SELECT ST_MakeValid(wkb_geometry) as the_geom, label pa_id, name '
                        'FROM {input}'.format(
                            output=self.output().table,
                            input=self.input()['data'].table,
                        ))
<commit_msg>Union of UK postal areas geometries with the same labels<commit_after>from tasks.base_tasks import (RepoFileUnzipTask, GeoFile2TempTableTask, ColumnsTask, TagsTask,
                              TableTask, SimplifiedTempTableTask, TempTableTask)
from tasks.meta import current_session
from tasks.util import copyfile
from tasks.meta import GEOM_REF, OBSColumn, OBSTag, OBSTable
from tasks.tags import SectionTags, SubsectionTags, LicenseTags, BoundaryTags
from lib.timespan import get_timespan
from tasks.uk.shoreline import Shoreline

from collections import OrderedDict

class DownloadPostcodeAreas(RepoFileUnzipTask):

    # Source: https://datashare.is.ed.ac.uk/handle/10283/2405
    URL = 'https://datashare.is.ed.ac.uk/bitstream/handle/10283/2405/gb_postcode_areas.zip?sequence=1&isAllowed=y'

    def get_url(self):
        return self.URL

class ImportPostcodeAreas(GeoFile2TempTableTask):

    other_options = '-s_srs "EPSG:27700"'

    def requires(self):
        return DownloadPostcodeAreas()

    def input_files(self):
        return self.input().path

class ShorelineClippedPostcodeAreas(TempTableTask):
    def requires(self):
        return {
            'shoreline': Shoreline(),
            'postcode_area': ImportPostcodeAreas(),
        }

    def version(self):
        return 1

    def run(self):
        session = current_session()

        stmt = '''
                CREATE TABLE {output_table} AS
                SELECT name, label, ST_Intersection(pa.wkb_geometry, shore.the_geom) wkb_geometry
                  FROM {postcode_areas_table} pa,
                       {shoreline_table} shore
               '''.format(
                   output_table=self.output().table,
                   postcode_areas_table=self.input()['postcode_area'].table,
                   shoreline_table=self.input()['shoreline'].table,
               )

        session.execute(stmt)

class SimplifiedPostcodeAreas(SimplifiedTempTableTask):
    def requires(self):
        return ShorelineClippedPostcodeAreas()

class SimplifiedUniquePostcodeAreas(TempTableTask):
    def requires(self):
        return SimplifiedPostcodeAreas()

    def run(self):
        session = current_session()
        session.execute('''
            CREATE TABLE {output} AS
            SELECT name, label, st_union(wkb_geometry) wkb_geometry
            FROM {input}
            GROUP BY name, label
            '''.format(
            output=self.output().table,
            input=self.input().table,
        ))

        session.commit()

class SourceTags(TagsTask):

    def version(self):
        return 1

    def tags(self):
        return[
            OBSTag(id='uk_ed_datashare_source',
                   name='Edinburgh DataShare',
                   type='source',
                   description='''
                               Edinburgh DataShare is a digital repository of research data produced at the University of Edinburgh, hosted by Information Services.
                               Edinburgh University researchers who have produced research data associated with an existing or forthcoming publication, or which has potential use for other researchers, are invited to upload their dataset for sharing and safekeeping.
                               A persistent identifier and suggested citation will be provided.
                               ''')
                   ]

class PostcodeAreasColumns(ColumnsTask):

    def version(self):
        return 1

    def requires(self):
        return {
            'subsections': SubsectionTags(),
            'sections': SectionTags(),
            'source': SourceTags(),
            'license': LicenseTags(),
            'boundary': BoundaryTags(),
        }

    def columns(self):
        input_ = self.input()
        license = input_['license']['uk_ed_datashare']
        source = input_['source']['uk_ed_datashare_source']
        boundary_type = input_['boundary']
        geom = OBSColumn(
            id='pa_geo',
            type='Geometry',
            name='GB Postcode Areas',
            description='''
                        Dataset contains polygons corresponding to the top level (Postcode Area) of the GB Postcode Hierarchy.
                        Thiessen polygons were generated from all records in OS OpenData Code-Point Open.
                        Resulting coverage was dissolved up to postcode area level and then clipped to GB extent of the realm using OS OpenData Boundary-Line.
                        Names of postcode areas were added from Wikipedia. GIS vector data.
                        This dataset was first accessioned in the EDINA ShareGeo Open repository on 2010-07-22 and migrated to Edinburgh DataShare on 2017-02-21.
                        ''',
            weight=8,
            tags=[input_['subsections']['boundary'], input_['sections']['uk'], source, license,
                  boundary_type['cartographic_boundary'], boundary_type['interpolation_boundary']]
        )
        geomref = OBSColumn(
            id='pa_id',
            type='Text',
            name='GB Postcode Area ID',
            weight=0,
            targets={geom: GEOM_REF}
        )
        geomname = OBSColumn(
            id='pa_name',
            type='Text',
            name='GB Postcode Area Name',
            weight=0,
            targets={geom: GEOM_REF}
        )

        return OrderedDict([
            ('the_geom', geom),
            ('pa_id', geomref),
            ('name', geomname),
        ])

class PostcodeAreas(TableTask):

    def requires(self):
        return {
            'geom_columns': PostcodeAreasColumns(),
            'data': SimplifiedUniquePostcodeAreas(),
        }

    def version(self):
        return 2

    def table_timespan(self):
        return get_timespan('2017')

    # TODO: https://github.com/CartoDB/bigmetadata/issues/435
    def targets(self):
        return {
            OBSTable(id='.'.join([self.schema(), self.name()])): GEOM_REF,
        }

    def columns(self):
        input_ = self.input()
        cols = OrderedDict()
        cols.update(input_['geom_columns'])
        return cols

    def populate(self):
        session = current_session()
        session.execute('INSERT INTO {output} '
                        'SELECT ST_MakeValid(wkb_geometry) as the_geom, label pa_id, name '
                        'FROM {input}'.format(
                            output=self.output().table,
                            input=self.input()['data'].table,
                        ))
<|endoftext|>


<commit_before># (C) Datadog, Inc. 2018-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import re
import sys

from ..errors import ManifestError
from ..fs import chdir, read_file, read_file_lines, write_file, write_file_lines
from ..subprocess import run_command
from .utils import get_version_file, load_manifest

# Maps the Python platform strings to the ones we have in the manifest
PLATFORMS_TO_PY = {'windows': 'win32', 'mac_os': 'darwin', 'linux': 'linux2'}
ALL_PLATFORMS = sorted(PLATFORMS_TO_PY)
VERSION = re.compile(r'__version__ *= *(?:[\'"])(.+?)(?:[\'"])')
DATADOG_PACKAGE_PREFIX = 'datadog-'

def get_release_tag_string(check_name, version_string):
    """
    Compose a string to use for release tags
    """
    if check_name:
        return f'{check_name}-{version_string}'
    else:
        return version_string

def update_version_module(check_name, old_ver, new_ver):
    """
    Change the Python code in the __about__.py module so that `__version__`
    contains the new value.
    """
    version_file = get_version_file(check_name)
    contents = read_file(version_file)

    contents = contents.replace(old_ver, new_ver)
    write_file(version_file, contents)

def get_package_name(folder_name):
    """
    Given a folder name for a check, return the name of the
    corresponding Python package
    """
    if folder_name == 'datadog_checks_base':
        return 'datadog-checks-base'
    elif folder_name == 'datadog_checks_downloader':
        return 'datadog-checks-downloader'

    return f"{DATADOG_PACKAGE_PREFIX}{folder_name.replace('_', '-')}"

def get_folder_name(package_name):
    """
    Given a Python package name for a check, return the corresponding folder
    name in the git repo
    """
    if package_name == 'datadog-checks-base':
        return 'datadog_checks_base'
    elif package_name == 'datadog-checks-downloader':
        return 'datadog_checks_downloader'

    return package_name.replace('-', '_')[len(DATADOG_PACKAGE_PREFIX) :]

def get_agent_requirement_line(check, version):
    """
    Compose a text line to be used in a requirements.txt file to install a check
    pinned to a specific version.
    """
    package_name = get_package_name(check)

    # no manifest
    if check in ('datadog_checks_base', 'datadog_checks_downloader'):
        return f'{package_name}=={version}'

    m = load_manifest(check)
    platforms = sorted(m.get('supported_os', []))

    # all platforms
    if platforms == ALL_PLATFORMS:
        return f'{package_name}=={version}'
    # one specific platform
    elif len(platforms) == 1:
        return f"{package_name}=={version}; sys_platform == '{PLATFORMS_TO_PY.get(platforms[0])}'"
    elif platforms:
        if 'windows' not in platforms:
            return f"{package_name}=={version}; sys_platform != 'win32'"
        elif 'mac_os' not in platforms:
            return f"{package_name}=={version}; sys_platform != 'darwin'"
        elif 'linux' not in platforms:
            return f"{package_name}=={version}; sys_platform != 'linux2'"

    raise ManifestError(f"Can't parse the `supported_os` list for the check {check}: {platforms}")

def update_agent_requirements(req_file, check, newline):
    """
    Replace the requirements line for the given check
    """
    package_name = get_package_name(check)
    lines = read_file_lines(req_file)

    for i, line in enumerate(lines):
        current_package_name = line.split('==')[0]

        if current_package_name == package_name:
            lines[i] = f'{newline}\n'
            break

    write_file_lines(req_file, sorted(lines))

def build_package(package_path, sdist):
    with chdir(package_path):
        # Clean up: Files built previously and now deleted might still persist in build directory
        # and will be included in the final wheel. Cleaning up before avoids that.
        result = run_command([sys.executable, 'setup.py', 'clean', '--all'], capture='out')
        if result.code != 0:
            return result

        result = run_command([sys.executable, 'setup.py', 'bdist_wheel', '--universal'], capture='out')
        if result.code != 0:
            return result

        if sdist:
            result = run_command([sys.executable, 'setup.py', 'sdist'], capture='out')
            if result.code != 0:
                return result

    return result
<commit_msg>Update release tooling to support `datadog_checks_dependency_provider` (#10046)<commit_after># (C) Datadog, Inc. 2018-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import re
import sys

from ..errors import ManifestError
from ..fs import chdir, read_file, read_file_lines, write_file, write_file_lines
from ..subprocess import run_command
from .utils import get_version_file, load_manifest

# Maps the Python platform strings to the ones we have in the manifest
PLATFORMS_TO_PY = {'windows': 'win32', 'mac_os': 'darwin', 'linux': 'linux2'}
ALL_PLATFORMS = sorted(PLATFORMS_TO_PY)
VERSION = re.compile(r'__version__ *= *(?:[\'"])(.+?)(?:[\'"])')
DATADOG_PACKAGE_PREFIX = 'datadog-'

def get_release_tag_string(check_name, version_string):
    """
    Compose a string to use for release tags
    """
    if check_name:
        return f'{check_name}-{version_string}'
    else:
        return version_string

def update_version_module(check_name, old_ver, new_ver):
    """
    Change the Python code in the __about__.py module so that `__version__`
    contains the new value.
    """
    version_file = get_version_file(check_name)
    contents = read_file(version_file)

    contents = contents.replace(old_ver, new_ver)
    write_file(version_file, contents)

def get_package_name(folder_name):
    """
    Given a folder name for a check, return the name of the
    corresponding Python package
    """
    if folder_name == 'datadog_checks_base':
        return 'datadog-checks-base'
    elif folder_name == 'datadog_checks_downloader':
        return 'datadog-checks-downloader'
    elif folder_name == 'datadog_checks_dependency_provider':
        return 'datadog-checks-dependency-provider'

    return f"{DATADOG_PACKAGE_PREFIX}{folder_name.replace('_', '-')}"

def get_folder_name(package_name):
    """
    Given a Python package name for a check, return the corresponding folder
    name in the git repo
    """
    if package_name == 'datadog-checks-base':
        return 'datadog_checks_base'
    elif package_name == 'datadog-checks-downloader':
        return 'datadog_checks_downloader'
    elif package_name == 'datadog-checks-dependency-provider':
        return 'datadog_checks_dependency_provider'

    return package_name.replace('-', '_')[len(DATADOG_PACKAGE_PREFIX) :]

def get_agent_requirement_line(check, version):
    """
    Compose a text line to be used in a requirements.txt file to install a check
    pinned to a specific version.
    """
    package_name = get_package_name(check)

    # no manifest
    if check in ('datadog_checks_base', 'datadog_checks_downloader', 'datadog_checks_dependency_provider'):
        return f'{package_name}=={version}'

    m = load_manifest(check)
    platforms = sorted(m.get('supported_os', []))

    # all platforms
    if platforms == ALL_PLATFORMS:
        return f'{package_name}=={version}'
    # one specific platform
    elif len(platforms) == 1:
        return f"{package_name}=={version}; sys_platform == '{PLATFORMS_TO_PY.get(platforms[0])}'"
    elif platforms:
        if 'windows' not in platforms:
            return f"{package_name}=={version}; sys_platform != 'win32'"
        elif 'mac_os' not in platforms:
            return f"{package_name}=={version}; sys_platform != 'darwin'"
        elif 'linux' not in platforms:
            return f"{package_name}=={version}; sys_platform != 'linux2'"

    raise ManifestError(f"Can't parse the `supported_os` list for the check {check}: {platforms}")

def update_agent_requirements(req_file, check, newline):
    """
    Replace the requirements line for the given check
    """
    package_name = get_package_name(check)
    lines = read_file_lines(req_file)

    for i, line in enumerate(lines):
        current_package_name = line.split('==')[0]

        if current_package_name == package_name:
            lines[i] = f'{newline}\n'
            break

    write_file_lines(req_file, sorted(lines))

def build_package(package_path, sdist):
    with chdir(package_path):
        # Clean up: Files built previously and now deleted might still persist in build directory
        # and will be included in the final wheel. Cleaning up before avoids that.
        result = run_command([sys.executable, 'setup.py', 'clean', '--all'], capture='out')
        if result.code != 0:
            return result

        result = run_command([sys.executable, 'setup.py', 'bdist_wheel', '--universal'], capture='out')
        if result.code != 0:
            return result

        if sdist:
            result = run_command([sys.executable, 'setup.py', 'sdist'], capture='out')
            if result.code != 0:
                return result

    return result
<|endoftext|>


<commit_before>"""
Author: Frederik Muller, xmulle20@stud.fit.vutbr.cz
Author: Matej Vido, xvidom00@stud.fit.vutbr.cz
Date:   04/2017
"""

import bcrypt
from flask import request
from bson import json_util, ObjectId
import pymongo

from api import auth, db
from api.module import Module
from api.models.models import Category, CategoryException
from api.role import Role

category = Module('categories', __name__, url_prefix='/categories', no_version=True)

def get_categories():
	res = Category.query.all()
	categories = []
	for category in res:
		if category.parent == None:
			tmp = category.to_dict()
			tmp["children"] = category.children_dict()
			categories.append(tmp)
	return(json_util.dumps(categories))

@auth.required(Role.admin)
def add_category():
	r = request.get_json()
	r.pop("products", [])
	r.pop("children", [])
	parent_dict = r.pop("parent", None)
	parent = None
	if parent_dict != None:
		parent_id = parent_dict.get("id", None)
		if parent_id != None:
			parent = Category.query.get_or_404(parent_id)
	try:
		category = Category.from_dict(r)
	except Exception as e:
		raise CategoryException(str(e))

	try:
		if parent != None:
			parent.children.append(category)
		db.db.session.add(category)
		res = db.db.session.commit()
	except Exception as e:
		db.db.session.rollback()
		print(e)
		raise CategoryException(str(e))

	inserted = Category.query.get_or_404(category.id)

	category = inserted.to_dict()
	category["parent"] = inserted.parent_dict()

	return(json_util.dumps(category))

@auth.required(Role.admin)
def remove_category(category_id):
	"""
	Remove the category
	"""

	category = Category.query.get_or_404(category_id)

	try:
		db.db.session.delete(category)
		db.db.session.commit()
	except Exception as e:
		db.db.session.rollback()
		raise CategoryException(str(e))

	tmp = category.to_dict()

	return(json_util.dumps(tmp))

@auth.required(Role.admin)
def edit_category(category_id):

	category_dict = request.get_json()
	category = Category.query.get_or_404(category_id)

	# check for all fields to be updated
	if "name" in category_dict and category_dict["name"]!= "":
		category.name = category_dict["name"]

	if "description" in category_dict and category_dict["description"] != "":
		category.description = category_dict["description"]

	if "slug" in category_dict and category_dict["slug"] != "":
		category.slug = category_dict["slug"]

	if "hidden" in category_dict and category_dict["hidden"] != "":
		category.hidden = category_dict["hidden"]

	parent_dict = category_dict.get("parent", None)
	if parent_dict != None:
		parent_id = parent_dict.get("id", None)
		if parent_id != None:
			parent = Category.query.get(parent_id)
			if parent != None:
				category.parent = parent

	# Update the category and return updated document
	try:
		db.db.session.commit()
	except Exception as e:
		db.db.session.rollback()
		raise CategoryException(str(e))

	tmp = category.to_dict()
	tmp["parent"] = category.parent_dict()
	tmp["children"] = category.children_dict()

	return(json_util.dumps(tmp))

def get_category(category_id):
	category = Category.query.get_or_404(category_id)
	category_dict = category.to_dict()
	category_dict["products"] = category.products_dict()
	category_dict["parent"] = category.parent_dict()
	category_dict["children"] = category.children_with_products_dict()
	return(json_util.dumps(category_dict))

category.add_url_rule('', view_func=get_categories, methods=['GET'])
category.add_url_rule('', view_func=add_category, methods=['POST'])
category.add_url_rule('/<string:category_id>', view_func=get_category, methods=['GET'])
category.add_url_rule('/<string:category_id>', view_func=edit_category, methods=['PUT'])
category.add_url_rule('/<string:category_id>', view_func=remove_category, methods=['DELETE'])
<commit_msg>api/modules/categories: generate slug<commit_after>"""
Author: Frederik Muller, xmulle20@stud.fit.vutbr.cz
Author: Matej Vido, xvidom00@stud.fit.vutbr.cz
Date:   04/2017
"""

import bcrypt
from flask import request
from bson import json_util, ObjectId
import pymongo
from slugify import slugify

from api import auth, db
from api.module import Module
from api.models.models import Category, CategoryException
from api.role import Role

category = Module('categories', __name__, url_prefix='/categories', no_version=True)

def get_categories():
	res = Category.query.all()
	categories = []
	for category in res:
		if category.parent == None:
			tmp = category.to_dict()
			tmp["children"] = category.children_dict()
			categories.append(tmp)
	return(json_util.dumps(categories))

@auth.required(Role.admin)
def add_category():
	r = request.get_json()
	r.pop("products", [])
	r.pop("children", [])
	parent_dict = r.pop("parent", None)
	parent = None
	if parent_dict != None:
		parent_id = parent_dict.get("id", None)
		if parent_id != None:
			parent = Category.query.get_or_404(parent_id)
	try:
		category = Category.from_dict(r)
	except Exception as e:
		raise CategoryException(str(e))

	try:
		if parent != None:
			parent.children.append(category)
		category.slug = slugify(category.name, to_lower=True)
		db.db.session.add(category)
		res = db.db.session.commit()
	except Exception as e:
		db.db.session.rollback()
		print(e)
		raise CategoryException(str(e))

	inserted = Category.query.get_or_404(category.id)

	category = inserted.to_dict()
	category["parent"] = inserted.parent_dict()

	return(json_util.dumps(category))

@auth.required(Role.admin)
def remove_category(category_id):
	"""
	Remove the category
	"""

	category = Category.query.get_or_404(category_id)

	try:
		db.db.session.delete(category)
		db.db.session.commit()
	except Exception as e:
		db.db.session.rollback()
		raise CategoryException(str(e))

	tmp = category.to_dict()

	return(json_util.dumps(tmp))

@auth.required(Role.admin)
def edit_category(category_id):

	category_dict = request.get_json()
	category = Category.query.get_or_404(category_id)

	# check for all fields to be updated
	if "name" in category_dict and category_dict["name"]!= "":
		category.name = category_dict["name"]
		category.slug = slugify(category.name, to_lower=True)

	if "description" in category_dict and category_dict["description"] != "":
		category.description = category_dict["description"]

	if "slug" in category_dict and category_dict["slug"] != "":
		category.slug = category_dict["slug"]

	if "hidden" in category_dict and category_dict["hidden"] != "":
		category.hidden = category_dict["hidden"]

	parent_dict = category_dict.get("parent", None)
	if parent_dict != None:
		parent_id = parent_dict.get("id", None)
		if parent_id != None:
			parent = Category.query.get(parent_id)
			if parent != None:
				category.parent = parent

	# Update the category and return updated document
	try:
		db.db.session.commit()
	except Exception as e:
		db.db.session.rollback()
		raise CategoryException(str(e))

	tmp = category.to_dict()
	tmp["parent"] = category.parent_dict()
	tmp["children"] = category.children_dict()

	return(json_util.dumps(tmp))

def get_category(category_id):
	category = Category.query.get_or_404(category_id)
	category_dict = category.to_dict()
	category_dict["products"] = category.products_dict()
	category_dict["parent"] = category.parent_dict()
	category_dict["children"] = category.children_with_products_dict()
	return(json_util.dumps(category_dict))

category.add_url_rule('', view_func=get_categories, methods=['GET'])
category.add_url_rule('', view_func=add_category, methods=['POST'])
category.add_url_rule('/<string:category_id>', view_func=get_category, methods=['GET'])
category.add_url_rule('/<string:category_id>', view_func=edit_category, methods=['PUT'])
category.add_url_rule('/<string:category_id>', view_func=remove_category, methods=['DELETE'])
<|endoftext|>