<commit_before># coding: utf-8

from __future__ import unicode_literals, absolute_import

from collections import namedtuple
from itertools import chain
import csv
import datetime
import re

from django.db.models import Avg, Count, Sum, Max, Min
from django.http import HttpResponse
from django.utils.text import force_text
from django.template.loader import render_to_string
from django.utils import timezone

from openpyxl.styles import Font
from openpyxl.utils import get_column_letter
from openpyxl.workbook import Workbook
from openpyxl.writer.excel import save_virtual_workbook

from six import BytesIO, text_type

from .introspection import get_model_from_path_string

DisplayField = namedtuple(
    "DisplayField",
    "path field field_verbose aggregate total group choices field_type",
)

def generate_filename(title, ends_with):
    title = title.split('.')[0]
    title.replace(' ', '_')
    title += ('_' + timezone.now().strftime("%Y-%m-%d_%H%M"))
    if not title.endswith(ends_with):
        title += ends_with
    return title

def add_aggregates(queryset, display_fields):
    agg_funcs = {
        'Avg': Avg, 'Min': Min, 'Max': Max, 'Count': Count, 'Sum': Sum
    }

    for display_field in display_fields:
        if display_field.aggregate:
            func = agg_funcs[display_field.aggregate]
            full_name = display_field.path + display_field.field
            queryset = queryset.annotate(func(full_name))

    return queryset

def report_to_list(queryset, display_fields, user, property_filters=[], preview=False):
    """ Create list from a report with all data filtering.

    queryset: initial queryset to generate results
    display_fields: list of field references or DisplayField models
    user: requesting user
    property_filters: ???
    preview: return only first 50 rows

    Returns list, message in case of issues.
    """
    model_class = queryset.model

    def can_change_or_view(model):
        """ Return True iff `user` has either change or view permission
        for `model`.
        """
        try:
            model_name = model._meta.model_name
        except AttributeError:
            # Needed for Django 1.4.* (LTS).
            model_name = model._meta.module_name

        app_label = model._meta.app_label
        can_change = user.has_perm(app_label + '.change_' + model_name)
        can_view = user.has_perm(app_label + '.view_' + model_name)

        return can_change or can_view

    if not can_change_or_view(model_class):
        return [], 'Permission Denied'

    if isinstance(display_fields, list):
        # Convert list of strings to DisplayField objects.

        new_display_fields = []

        for display_field in display_fields:
            field_list = display_field.split('__')
            field = field_list[-1]
            path = '__'.join(field_list[:-1])

            if path:
                path += '__'  # Legacy format to append a __ here.

            new_model = get_model_from_path_string(model_class, path)
            model_field = new_model._meta.get_field(field)
            choices = model_field.choices
            new_display_fields.append(DisplayField(
                path, field, '', '', None, None, choices, ''
            ))

        display_fields = new_display_fields

    # Build group-by field list.

    group = [df.path + df.field for df in display_fields if df.group]

    # To support group-by with multiple fields, we turn all the other
    # fields into aggregations. The default aggregation is `Max`.

    if group:
        for field in display_fields:
            if (not field.group) and (not field.aggregate):
                field.aggregate = 'Max'

    message = ""
    objects = add_aggregates(queryset, display_fields)

    # Display Values

    display_field_paths = []
    property_list = {}
    display_totals = {}

    for i, display_field in enumerate(display_fields):
        model = get_model_from_path_string(model_class, display_field.path)

        if display_field.field_type == "Invalid":
            continue

        if not model or can_change_or_view(model):
            display_field_key = display_field.path + display_field.field

            if display_field.field_type == "Property":
                property_list[i] = display_field_key
            elif display_field.aggregate == "Avg":
                display_field_key += '__avg'
            elif display_field.aggregate == "Max":
                display_field_key += '__max'
            elif display_field.aggregate == "Min":
                display_field_key += '__min'
            elif display_field.aggregate == "Count":
                display_field_key += '__count'
            elif display_field.aggregate == "Sum":
                display_field_key += '__sum'

            if display_field.field_type not in ('Property', 'Custom Field'):
                display_field_paths.append(display_field_key)

            if display_field.total:
                display_totals[display_field_key] = Decimal(0)

        else:
            message += 'Error: Permission denied on access to {0}.'.format(
                display_field.name
            )

    def increment_total(display_field_key, val):
        """ Increment display total by `val` if given `display_field_key` in
        `display_totals`.
        """
        if display_field_key in display_totals:
            if isinstance(val, bool):
                # True: 1, False: 0
                display_totals[display_field_key] += Decimal(val)
            elif isinstance(val, Number):
                display_totals[display_field_key] += Decimal(str(val))
            elif val:
                display_totals[display_field_key] += Decimal(1)

    # Select pk for primary and m2m relations in order to retrieve objects
    # for adding properties to report rows. Group-by queries do not support
    # Property nor Custom Field filters.

    if not group:
        display_field_paths.insert(0, 'pk')

        m2m_relations = []
        for position, property_path in property_list.items():
            property_root = property_path.split('__')[0]
            root_class = model_class

            try:
                property_root_class = getattr(root_class, property_root)
            except AttributeError:  # django-hstore schema compatibility
                continue

            if type(property_root_class) == ManyToManyDescriptor:
                display_field_paths.insert(1, '%s__pk' % property_root)
                m2m_relations.append(property_root)

    if group:
        values = objects.values(*group)
        values = self.add_aggregates(values, display_fields)
        filtered_report_rows = [
            [row[field] for field in display_field_paths]
            for row in values
        ]
        for row in filtered_report_rows:
            for pos, field in enumerate(display_field_paths):
                increment_total(field, row[pos])
    else:
        filtered_report_rows = []
        values_and_properties_list = []

        values_list = objects.values_list(*display_field_paths)

        for row in values_list:
            row = list(row)
            values_and_properties_list.append(row[1:])
            obj = None  # we will get this only if needed for more complex processing
            # related_objects
            remove_row = False
            # filter properties (remove rows with excluded properties)
            for property_filter in property_filters:
                if not obj:
                    obj = model_class.objects.get(pk=row.pop(0))
                root_relation = property_filter.path.split('__')[0]
                if root_relation in m2m_relations:
                    pk = row[0]
                    if pk is not None:
                        # a related object exists
                        m2m_obj = getattr(obj, root_relation).get(pk=pk)
                        val = reduce(getattr, [property_filter.field], m2m_obj)
                    else:
                        val = None
                else:
                    if property_filter.field_type == 'Custom Field':
                        for relation in property_filter.path.split('__'):
                            if hasattr(obj, root_relation):
                                obj = getattr(obj, root_relation)
                        val = obj.get_custom_value(property_filter.field)
                    else:
                        val = reduce(
                            getattr,
                            (property_filter.path + property_filter.field).split('__'),
                            obj
                        )
                if property_filter.filter_property(val):
                    remove_row = True
                    values_and_properties_list.pop()
                    break
            if not remove_row:
                for i, field in enumerate(display_field_paths[1:]):
                    increment_total(field, row[i + 1])

                for position, display_property in property_list.items():
                    if not obj:
                        obj = model_class.objects.get(pk=row.pop(0))
                    relations = display_property.split('__')
                    root_relation = relations[0]
                    if root_relation in m2m_relations:
                        pk = row.pop(0)
                        if pk is not None:
                            # a related object exists
                            m2m_obj = getattr(obj, root_relation).get(pk=pk)
                            val = reduce(getattr, relations[1:], m2m_obj)
                        else:
                            val = None
                    else:
                        # Could error if a related field doesn't exist
                        try:
                            val = reduce(getattr, relations, obj)
                        except AttributeError:
                            val = None
                    values_and_properties_list[-1].insert(position, val)
                    increment_total(display_property, val)

                filtered_report_rows.append(values_and_properties_list[-1])

            if preview and len(filtered_report_rows) == 50:
                break

    # Sort results if requested.

    if hasattr(display_fields, 'filter'):
        defaults = {
            None: text_type,
            datetime.date: lambda: datetime.date(datetime.MINYEAR, 1, 1),
            datetime.datetime: lambda: datetime.datetime(datetime.MINYEAR, 1, 1),
        }

        # Order sort fields in reverse order so that ascending, descending
        # sort orders work together (based on Python's stable sort). See
        # http://stackoverflow.com/questions/6666748/ for details.

        sort_fields = display_fields.filter(sort__gt=0).order_by('-sort')
        sort_values = sort_fields.values_list('position', 'sort_reverse')

        for pos, reverse in sort_values:
            column = (row[pos] for row in filtered_report_rows)
            type_col = (type(val) for val in column if val is not None)
            field_type = next(type_col, None)
            default = defaults.get(field_type, field_type)()

            filtered_report_rows = sorted(
                filtered_report_rows,
                key=lambda row: self.sort_helper(row[pos], default),
                reverse=reverse,
            )

    values_and_properties_list = filtered_report_rows

    # Build mapping from display field position to choices list.

    choice_lists = {}
    for df in display_fields:
        if df.choices and hasattr(df, 'choices_dict'):
            df_choices = df.choices_dict
            # Insert blank and None as valid choices.
            df_choices[''] = ''
            df_choices[None] = ''
            choice_lists[df.position] = df_choices

    # Build mapping from display field position to format.

    display_formats = {}

    for df in display_fields:
        if hasattr(df, 'display_format') and df.display_format:
            display_formats[df.position] = df.display_format

    def formatter(value, style):
        # Convert value to Decimal to apply numeric formats.
        try:
            value = Decimal(value)
        except Exception:
            pass

        try:
            return style.string.format(value)
        except ValueError:
            return value

    # Iterate rows and convert values by choice lists and field formats.

    final_list = []

    for row in values_and_properties_list:
        row = list(row)

        for position, choice_list in choice_lists.items():
            try:
                row[position] = text_type(choice_list[row[position]])
            except Exception:
                row[position] = text_type(row[position])

        for pos, style in display_formats.items():
            row[pos] = formatter(row[pos], style)

        final_list.append(row)

    values_and_properties_list = final_list

    if display_totals:
        display_totals_row = []

        fields_and_properties = list(display_field_paths[0 if group else 1:])

        for position, value in property_list.items():
            fields_and_properties.insert(position, value)

        for field in fields_and_properties:
            display_totals_row.append(display_totals.get(field, ''))

        # Add formatting to display totals.

        for pos, style in display_formats.items():
            display_totals_row[pos] = formatter(display_totals_row[pos], style)

        values_and_properties_list.append(
            ['TOTALS'] + (len(fields_and_properties) - 1) * ['']
        )
        values_and_properties_list.append(display_totals_row)

    return values_and_properties_list, message

def build_sheet(data, ws, sheet_name='report', header=None, widths=None):
    first_row = 1
    column_base = 1

    ws.title = re.sub(r'\W+', '', sheet_name)[:30]
    if header:
        for i, header_cell in enumerate(header):
            cell = ws.cell(row=first_row, column=i+column_base)
            cell.value = header_cell
            cell.font = Font(bold=True)
            if widths:
                ws.column_dimensions[get_column_letter(i+1)].width = widths[i]

    for row in data:
        for i in range(len(row)):
            item = row[i]
            # If item is a regular string
            if isinstance(item, str):
                # Change it to a unicode string
                try:
                    row[i] = text_type(item)
                except UnicodeDecodeError:
                    row[i] = text_type(item.decode('utf-8', 'ignore'))
            elif type(item) is dict:
                row[i] = text_type(item)
        try:
            ws.append(row)
        except ValueError as e:
            ws.append([e.message])
        except:
            ws.append(['Unknown Error'])

def list_to_workbook(data, title='report', header=None, widths=None):
    """ Create just a openpxl workbook from a list of data """
    wb = Workbook()
    title = re.sub(r'\W+', '', title)[:30]

    if isinstance(data, dict):
        i = 0
        for sheet_name, sheet_data in data.items():
            if i > 0:
                wb.create_sheet()
            ws = wb.worksheets[i]
            build_sheet(
                sheet_data, ws, sheet_name=sheet_name, header=header)
            i += 1
    else:
        ws = wb.worksheets[0]
        build_sheet(data, ws, header=header, widths=widths)
    return wb

def build_xlsx_response(wb, title="report"):
    """ Take a workbook and return a xlsx file response """
    title = generate_filename(title, '.xlsx')
    myfile = BytesIO()
    myfile.write(save_virtual_workbook(wb))
    response = HttpResponse(
        myfile.getvalue(),
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=%s' % title
    response['Content-Length'] = myfile.tell()
    return response

def list_to_xlsx_response(data, title='report', header=None,
                          widths=None):
    """ Make 2D list into a xlsx response for download
    data can be a 2d array or a dict of 2d arrays
    like {'sheet_1': [['A1', 'B1']]}
    """
    wb = list_to_workbook(data, title, header, widths)
    return build_xlsx_response(wb, title=title)

def list_to_csv_response(data, title='report', header=None, widths=None):
    """ Make 2D list into a csv response for download data.
    """
    response = HttpResponse(content_type="text/csv; charset=UTF-8")
    cw = csv.writer(response)
    for row in chain([header] if header else [], data):
        cw.writerow([force_text(s).encode(response.charset) for s in row])
    return response

def list_to_html_response(data, title='', header=None):
    html = render_to_string('export_action/report_html.html', locals())
    return HttpResponse(html)
<commit_msg>removing unused code<commit_after># coding: utf-8

from __future__ import unicode_literals, absolute_import

from collections import namedtuple
from itertools import chain
import csv
import re
try:
    from decimal import Decimal
except:
    from Decimal import Decimal

from django.http import HttpResponse
from django.utils.text import force_text
from django.template.loader import render_to_string
from django.utils import timezone

from openpyxl.styles import Font
from openpyxl.utils import get_column_letter
from openpyxl.workbook import Workbook
from openpyxl.writer.excel import save_virtual_workbook

from six import BytesIO, text_type

from .introspection import get_model_from_path_string

DisplayField = namedtuple(
    "DisplayField",
    "path field field_verbose aggregate total group choices field_type",
)

def generate_filename(title, ends_with):
    title = title.split('.')[0]
    title.replace(' ', '_')
    title += ('_' + timezone.now().strftime("%Y-%m-%d_%H%M"))
    if not title.endswith(ends_with):
        title += ends_with
    return title

def _can_change_or_view(model, user):
    """ Return True iff `user` has either change or view permission
    for `model`.
    """
    try:
        model_name = model._meta.model_name
    except AttributeError:
        # Needed for Django 1.4.* (LTS).
        model_name = model._meta.module_name

    app_label = model._meta.app_label
    can_change = user.has_perm(app_label + '.change_' + model_name)
    can_view = user.has_perm(app_label + '.view_' + model_name)

    return can_change or can_view

def report_to_list(queryset, display_fields, user, preview=False):
    """ Create list from a report with all data filtering.

    queryset: initial queryset to generate results
    display_fields: list of field references or DisplayField models
    user: requesting user
    preview: return only first 50 rows

    Returns list, message in case of issues.
    """
    model_class = queryset.model
    objects = queryset

    if not _can_change_or_view(model_class, user):
        return [], 'Permission Denied'

    if isinstance(display_fields, list):
        # Convert list of strings to DisplayField objects.

        new_display_fields = []

        for display_field in display_fields:
            field_list = display_field.split('__')
            field = field_list[-1]
            path = '__'.join(field_list[:-1])

            if path:
                path += '__'  # Legacy format to append a __ here.

            new_model = get_model_from_path_string(model_class, path)
            model_field = new_model._meta.get_field(field)
            choices = model_field.choices
            df = DisplayField(
                path,
                field,
                '',
                '',
                None,
                None,
                choices,
                ''
            )
            new_display_fields.append(df)

        display_fields = new_display_fields

    message = ""

    # Display Values

    display_field_paths = []

    for i, display_field in enumerate(display_fields):
        model = get_model_from_path_string(model_class, display_field.path)

        if display_field.field_type == "Invalid":
            continue

        if not model or _can_change_or_view(model, user):
            display_field_key = display_field.path + display_field.field

            display_field_paths.append(display_field_key)

        else:
            message += 'Error: Permission denied on access to {0}.'.format(
                display_field.name
            )

    # Select pk for primary and m2m relations in order to retrieve objects
    # for adding properties to report rows. Group-by queries do not support
    # Property nor Custom Field filters.

    display_field_paths.insert(0, 'pk')

    filtered_report_rows = []
    values_and_properties_list = []

    values_list = objects.values_list(*display_field_paths)

    for row in values_list:
        row = list(row)
        values_and_properties_list.append(row[1:])

        filtered_report_rows.append(values_and_properties_list[-1])

        if preview and len(filtered_report_rows) == 50:
            break

    # Sort results if requested.
    values_and_properties_list = filtered_report_rows

    # Build mapping from display field position to choices list.

    choice_lists = {}
    for df in display_fields:
        if df.choices and hasattr(df, 'choices_dict'):
            df_choices = df.choices_dict
            # Insert blank and None as valid choices.
            df_choices[''] = ''
            df_choices[None] = ''
            choice_lists[df.position] = df_choices

    # Build mapping from display field position to format.

    display_formats = {}

    for df in display_fields:
        if hasattr(df, 'display_format') and df.display_format:
            display_formats[df.position] = df.display_format

    def formatter(value, style):
        # Convert value to Decimal to apply numeric formats.
        try:
            value = Decimal(value)
        except Exception:
            pass

        try:
            return style.string.format(value)
        except ValueError:
            return value

    # Iterate rows and convert values by choice lists and field formats.

    final_list = []

    for row in values_and_properties_list:
        row = list(row)

        for position, choice_list in choice_lists.items():
            try:
                row[position] = text_type(choice_list[row[position]])
            except Exception:
                row[position] = text_type(row[position])

        for pos, style in display_formats.items():
            row[pos] = formatter(row[pos], style)

        final_list.append(row)

    values_and_properties_list = final_list

    return values_and_properties_list, message

def build_sheet(data, ws, sheet_name='report', header=None, widths=None):
    first_row = 1
    column_base = 1

    ws.title = re.sub(r'\W+', '', sheet_name)[:30]
    if header:
        for i, header_cell in enumerate(header):
            cell = ws.cell(row=first_row, column=i+column_base)
            cell.value = header_cell
            cell.font = Font(bold=True)
            if widths:
                ws.column_dimensions[get_column_letter(i+1)].width = widths[i]

    for row in data:
        for i in range(len(row)):
            item = row[i]
            # If item is a regular string
            if isinstance(item, str):
                # Change it to a unicode string
                try:
                    row[i] = text_type(item)
                except UnicodeDecodeError:
                    row[i] = text_type(item.decode('utf-8', 'ignore'))
            elif type(item) is dict:
                row[i] = text_type(item)
        try:
            ws.append(row)
        except ValueError as e:
            ws.append([e.message])
        except:
            ws.append(['Unknown Error'])

def list_to_workbook(data, title='report', header=None, widths=None):
    """ Create just a openpxl workbook from a list of data """
    wb = Workbook()
    title = re.sub(r'\W+', '', title)[:30]

    if isinstance(data, dict):
        i = 0
        for sheet_name, sheet_data in data.items():
            if i > 0:
                wb.create_sheet()
            ws = wb.worksheets[i]
            build_sheet(
                sheet_data, ws, sheet_name=sheet_name, header=header)
            i += 1
    else:
        ws = wb.worksheets[0]
        build_sheet(data, ws, header=header, widths=widths)
    return wb

def build_xlsx_response(wb, title="report"):
    """ Take a workbook and return a xlsx file response """
    title = generate_filename(title, '.xlsx')
    myfile = BytesIO()
    myfile.write(save_virtual_workbook(wb))
    response = HttpResponse(
        myfile.getvalue(),
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=%s' % title
    response['Content-Length'] = myfile.tell()
    return response

def list_to_xlsx_response(data, title='report', header=None,
                          widths=None):
    """ Make 2D list into a xlsx response for download
    data can be a 2d array or a dict of 2d arrays
    like {'sheet_1': [['A1', 'B1']]}
    """
    wb = list_to_workbook(data, title, header, widths)
    return build_xlsx_response(wb, title=title)

def list_to_csv_response(data, title='report', header=None, widths=None):
    """ Make 2D list into a csv response for download data.
    """
    response = HttpResponse(content_type="text/csv; charset=UTF-8")
    cw = csv.writer(response)
    for row in chain([header] if header else [], data):
        cw.writerow([force_text(s).encode(response.charset) for s in row])
    return response

def list_to_html_response(data, title='', header=None):
    html = render_to_string('export_action/report_html.html', locals())
    return HttpResponse(html)
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
###############################################################################
#
# ODOO (ex OpenERP)
# Open Source Management Solution
# Copyright (C) 2001-2015 Micronaet S.r.l. (<https://micronaet.com>)
# 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 pickle
import openerp
import openerp.netsvc as netsvc
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, api
from openerp import tools
from openerp.tools.translate import _
from openerp.tools.float_utils import float_round as round
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
    DEFAULT_SERVER_DATETIME_FORMAT,
    DATETIME_FORMATS_MAP,
    float_compare)

_logger = logging.getLogger(__name__)

class StockInventoryHistoryYear(orm.Model):
    """ Model name: stock.inventory.history.year
    """

    _name = 'stock.inventory.history.year'
    _description = 'Inventario fine anno'
    _rec_name = 'name'
    _order = 'name'

    def generate_folder_structure(self, cr, uid, year, context=None):
        """ Generate folder structure
        """
        root_path = os.path.expanduser('~/inventory')

        # Create folder structure
        base_folder = os.path.join(root_path, year)
        os.system('mkdir -p %s' % base_folder)
        folder = os.path.join(base_folder, 'pickle')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'excel')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'log')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'data')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'result')
        os.system('mkdir -p %s' % folder)
        return base_folder

    def get_excel_format(self, excel_pool):
        """ Setup excel format
        """
        excel_pool.set_format(number_format='#,##0.####0')
        return {
            'title': excel_pool.get_format('title'),
            'header': excel_pool.get_format('header'),
            'text': excel_pool.get_format('text'),
            'number': excel_pool.get_format('number'),
            'white': {
                'title': excel_pool.get_format('title'),
                'header': excel_pool.get_format('header'),
                'text': excel_pool.get_format('text'),
                'number': excel_pool.get_format('number'),
            },
            'red': {
                'title': excel_pool.get_format('title'),
                'header': excel_pool.get_format('header'),
                'text': excel_pool.get_format('bg_red'),
                'number': excel_pool.get_format('bg_red_number'),
            },
            'green': {
                'title': excel_pool.get_format('title'),
                'header': excel_pool.get_format('header'),
                'text': excel_pool.get_format('bg_green'),
                'number': excel_pool.get_format('bg_green_number'),
            },
        }

    def button_extract_invoice(self, cr, uid, ids, context=None):
        """ Extract invoice and put in pickle file
        """
        excel_pool = self.pool.get('excel.writer')

        # Read parameters:
        inventory = self.browse(cr, uid, ids, context=context)[0]
        from_date = inventory.from_date
        to_date = inventory.to_date

        if inventory.base_folder:
            base_folder = inventory.base_folder
        else:
            base_folder = self.generate_folder_structure(
                cr, uid, inventory.name, context=context)
            self.write(cr, uid, ids, {
                'base_folder': base_folder,
            }, context=context)

        line_pool = self.pool.get('account.invoice.line')
        modes = {
            'Fatture': ('out_invoice', -1),  # unload
            'NC': ('out_refund', +1),  # load
        }
        for setup in modes:
            mode, sign = modes[setup]
            pickle_file = os.path.join(
                base_folder, 'pickle', '%s.pickle' % setup)
            excel_file = os.path.join(
                base_folder, 'excel', '%s.xlsx' % setup)

            data = []
            # Collect data from invoices and credit note:
            line_ids = line_pool.search(cr, uid, [
                ('invoice_id.date_invoice', '>=', from_date),
                ('invoice_id.date_invoice', '<=', to_date),
                ('invoice_id.type', '=', mode),
            ], context=context)

            # -----------------------------------------------------------------
            #                          Excel export:
            # -----------------------------------------------------------------
            ws_name = setup
            excel_pool.create_worksheet(name=ws_name)
            excel_format = self.get_excel_format(excel_pool)

            # Start writing in the sheet:
            width = [
                15, 40,
                10, 15, 35, 10,
                10, 10]
            excel_pool.column_width(ws_name, width)

            header = [
                'Data', 'Rif.',
                'ID prodotto', 'Codice', 'Nome', 'Q.',
                'Ricodifica', 'Prezzo inventario',
            ]
            row = 0
            excel_pool.write_xls_line(
                ws_name, row, header, default_format=excel_format['header'])

            for line in line_pool.browse(
                    cr, uid, line_ids, context=context):
                row += 1
                invoice = line.invoice_id
                excel_record = [
                    invoice.date_invoice,
                    u'%s [%s]' % (
                        invoice.number, invoice.partner_id.name),
                    line.product_id.id,
                    line.product_id.default_code,
                    u'%s' % line.name,
                    sign * line.quantity,
                    u'',
                    0.0,
                    ]
                record = {
                    'date': excel_record[0],
                    'ref': excel_record[1],
                    'product_id': excel_record[2],
                    'default_code': excel_record[3],
                    'name': excel_record[4],
                    'quantity': excel_record[5],
                    'compress_code': excel_record[6],
                    'inventory_price': excel_record[7],
                }
                data.append(record)

                excel_pool.write_xls_line(
                    ws_name, row, excel_record,
                    default_format=excel_format['white']['text'])

            pickle.dump(data, open(pickle_file, 'wb'))
            excel_pool.save_file_as(excel_file)
        return True

    def button_extract_final(self, cr, uid, ids, context=None):
        """ Extract final status
        """
        product_pool = self.pool.get('product.product.start.history')
        excel_pool = self.pool.get('excel.writer')

        # External parameters:
        pipe_codes = {
            'TBAL': 'TUBAL',
            'TBFE': 'TUBFE',
            'TBFZ': 'TUBFZ',
        }

        # Read parameters:
        inventory = self.browse(cr, uid, ids, context=context)[0]
        to_date = inventory.to_date
        base_folder = inventory.base_folder

        pickle_file = os.path.join(
            base_folder, 'pickle', '%s.pickle' % 'Finale')
        excel_file = os.path.join(
            base_folder, 'excel', 'Finale.xlsx')

        product_ids = product_pool.search(
            cr, uid, [
                ('mx_start_date', '=', to_date),
            ], context=context)

        # -----------------------------------------------------------------
        #                          Excel export:
        # -----------------------------------------------------------------
        ws_name = 'Stato finale'
        excel_pool.create_worksheet(name=ws_name)
        excel_format = self.get_excel_format(excel_pool)

        # Start writing in the sheet:
        width = [
            15, 15, 40, 35, 10,
            10, 12]
        excel_pool.column_width(ws_name, width)

        header = [
            'ID', 'Codice', 'Nome', 'Categoria', 'Ricodifica',
            'Q.', 'Prezzo inventario',
        ]
        row = 0
        excel_pool.write_xls_line(
            ws_name, row, header, default_format=excel_format['header'])

        jump = False
        for line in product_pool.browse(cr, uid, product_ids, context=context):
            row += 1
            product = line.product_id
            product_id = product.id
            default_code = product.default_code
            real_code = default_code
            name = product.name
            qty = line.mx_start_qty
            if product.inventory_category_id:
                category = product.inventory_category_id.name
            else:
                category = ''

            if not default_code:
                _logger.error('Product not found: %s\n' % name)
                continue

            if default_code[:4] in pipe_codes:
                # Clean pipe:
                default_code = pipe_codes[default_code[:4]]
                product_id = ''
            elif default_code[:2] in ('PO', 'MS', 'MT', 'TL', 'TS'):
                # Clean HW packed:
                default_code = default_code[:8].strip()
                product_id = ''
            elif category == 'Prodotti finiti':
                # Final product packed:
                if not default_code[:3].isdigit():
                    default_code = default_code[:6].strip()
                    product_id = ''
            elif category in ('Esclusi', 'Lavorazioni'):
                # Remove category:
                _logger.warning('Saltati prodotti categoria: %s: %s '
                                '[q. %s]\n' % (
                                    category, default_code, qty))
                jump = True

            if qty <= 0:
                jump = True

            # Write line in Excel:
            excel_line = [
                product_id, real_code, name, category, default_code, qty, 0,
            ]
            excel_pool.write_xls_line(
                ws_name, row, excel_line,
                default_format=excel_format['white']['text'])

            if jump:
                continue

            # Save in pickle only used data:
            inventory.append({
                'product_id': product_id,
                'name': name,
                'category': category,
                'qty': qty,
                'default_code': real_code,
                'compress_code': default_code,
            })

        pickle.dump(inventory, open(pickle_file, 'wb'))
        excel_pool.save_file_as(excel_file)
        return True

    _columns = {
        'name': fields.char('Anno', size=64, required=True),
        'base_folder': fields.char(
            'Cartella base', size=180,
            help='Cartella dove sono memorizzati tutti i file della gestione'),
        'from_date': fields.date('Dalla data', required=True),
        'to_date': fields.date('Alla data', required=True),
    }

<commit_msg>generic bugfix (fast message)<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
###############################################################################
#
# ODOO (ex OpenERP)
# Open Source Management Solution
# Copyright (C) 2001-2015 Micronaet S.r.l. (<https://micronaet.com>)
# 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 pickle
import openerp
import openerp.netsvc as netsvc
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, api
from openerp import tools
from openerp.tools.translate import _
from openerp.tools.float_utils import float_round as round
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
    DEFAULT_SERVER_DATETIME_FORMAT,
    DATETIME_FORMATS_MAP,
    float_compare)

_logger = logging.getLogger(__name__)

class StockInventoryHistoryYear(orm.Model):
    """ Model name: stock.inventory.history.year
    """

    _name = 'stock.inventory.history.year'
    _description = 'Inventario fine anno'
    _rec_name = 'name'
    _order = 'name'

    def generate_folder_structure(self, cr, uid, year, context=None):
        """ Generate folder structure
        """
        root_path = os.path.expanduser('~/inventory')

        # Create folder structure
        base_folder = os.path.join(root_path, year)
        os.system('mkdir -p %s' % base_folder)
        folder = os.path.join(base_folder, 'pickle')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'excel')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'log')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'data')
        os.system('mkdir -p %s' % folder)
        folder = os.path.join(base_folder, 'result')
        os.system('mkdir -p %s' % folder)
        return base_folder

    def get_excel_format(self, excel_pool):
        """ Setup excel format
        """
        excel_pool.set_format(number_format='#,##0.####0')
        return {
            'title': excel_pool.get_format('title'),
            'header': excel_pool.get_format('header'),
            'text': excel_pool.get_format('text'),
            'number': excel_pool.get_format('number'),
            'white': {
                'title': excel_pool.get_format('title'),
                'header': excel_pool.get_format('header'),
                'text': excel_pool.get_format('text'),
                'number': excel_pool.get_format('number'),
            },
            'red': {
                'title': excel_pool.get_format('title'),
                'header': excel_pool.get_format('header'),
                'text': excel_pool.get_format('bg_red'),
                'number': excel_pool.get_format('bg_red_number'),
            },
            'green': {
                'title': excel_pool.get_format('title'),
                'header': excel_pool.get_format('header'),
                'text': excel_pool.get_format('bg_green'),
                'number': excel_pool.get_format('bg_green_number'),
            },
        }

    def button_extract_invoice(self, cr, uid, ids, context=None):
        """ Extract invoice and put in pickle file
        """
        excel_pool = self.pool.get('excel.writer')

        # Read parameters:
        inventory = self.browse(cr, uid, ids, context=context)[0]
        from_date = inventory.from_date
        to_date = inventory.to_date

        if inventory.base_folder:
            base_folder = inventory.base_folder
        else:
            base_folder = self.generate_folder_structure(
                cr, uid, inventory.name, context=context)
            self.write(cr, uid, ids, {
                'base_folder': base_folder,
            }, context=context)

        line_pool = self.pool.get('account.invoice.line')
        modes = {
            'Fatture': ('out_invoice', -1),  # unload
            'NC': ('out_refund', +1),  # load
        }
        for setup in modes:
            mode, sign = modes[setup]
            pickle_file = os.path.join(
                base_folder, 'pickle', '%s.pickle' % setup)
            excel_file = os.path.join(
                base_folder, 'excel', '%s.xlsx' % setup)

            data = []
            # Collect data from invoices and credit note:
            line_ids = line_pool.search(cr, uid, [
                ('invoice_id.date_invoice', '>=', from_date),
                ('invoice_id.date_invoice', '<=', to_date),
                ('invoice_id.type', '=', mode),
            ], context=context)

            # -----------------------------------------------------------------
            #                          Excel export:
            # -----------------------------------------------------------------
            ws_name = setup
            excel_pool.create_worksheet(name=ws_name)
            excel_format = self.get_excel_format(excel_pool)

            # Start writing in the sheet:
            width = [
                15, 40,
                10, 15, 35, 10,
                10, 10]
            excel_pool.column_width(ws_name, width)

            header = [
                'Data', 'Rif.',
                'ID prodotto', 'Codice', 'Nome', 'Q.',
                'Ricodifica', 'Prezzo inventario',
            ]
            row = 0
            excel_pool.write_xls_line(
                ws_name, row, header, default_format=excel_format['header'])

            for line in line_pool.browse(
                    cr, uid, line_ids, context=context):
                row += 1
                invoice = line.invoice_id
                excel_record = [
                    invoice.date_invoice,
                    u'%s [%s]' % (
                        invoice.number, invoice.partner_id.name),
                    line.product_id.id,
                    line.product_id.default_code,
                    u'%s' % line.name,
                    sign * line.quantity,
                    u'',
                    0.0,
                    ]
                record = {
                    'date': excel_record[0],
                    'ref': excel_record[1],
                    'product_id': excel_record[2],
                    'default_code': excel_record[3],
                    'name': excel_record[4],
                    'quantity': excel_record[5],
                    'compress_code': excel_record[6],
                    'inventory_price': excel_record[7],
                }
                data.append(record)

                excel_pool.write_xls_line(
                    ws_name, row, excel_record,
                    default_format=excel_format['white']['text'])

            pickle.dump(data, open(pickle_file, 'wb'))
            excel_pool.save_file_as(excel_file)
        return True

    def button_extract_final(self, cr, uid, ids, context=None):
        """ Extract final status
        """
        product_pool = self.pool.get('product.product.start.history')
        excel_pool = self.pool.get('excel.writer')

        # External parameters:
        pipe_codes = {
            'TBAL': 'TUBAL',
            'TBFE': 'TUBFE',
            'TBFZ': 'TUBFZ',
        }

        # Read parameters:
        inventory = self.browse(cr, uid, ids, context=context)[0]
        to_date = inventory.to_date
        base_folder = inventory.base_folder

        pickle_file = os.path.join(
            base_folder, 'pickle', '%s.pickle' % 'Finale')
        excel_file = os.path.join(
            base_folder, 'excel', 'Finale.xlsx')

        product_ids = product_pool.search(
            cr, uid, [
                ('mx_start_date', '=', to_date),
            ], context=context)

        # -----------------------------------------------------------------
        #                          Excel export:
        # -----------------------------------------------------------------
        ws_name = 'Stato finale'
        excel_pool.create_worksheet(name=ws_name)
        excel_format = self.get_excel_format(excel_pool)

        # Start writing in the sheet:
        width = [
            15, 15, 40, 35, 10,
            10, 12]
        excel_pool.column_width(ws_name, width)

        header = [
            'ID', 'Codice', 'Nome', 'Categoria', 'Ricodifica',
            'Q.', 'Prezzo inventario',
        ]
        row = 0
        excel_pool.write_xls_line(
            ws_name, row, header, default_format=excel_format['header'])

        jump = False
        pickle_data = []
        for line in product_pool.browse(cr, uid, product_ids, context=context):
            row += 1
            product = line.product_id
            product_id = product.id
            default_code = product.default_code
            real_code = default_code
            name = product.name
            qty = line.mx_start_qty
            if product.inventory_category_id:
                category = product.inventory_category_id.name
            else:
                category = ''

            if not default_code:
                _logger.error('Product not found: %s\n' % name)
                continue

            if default_code[:4] in pipe_codes:
                # Clean pipe:
                default_code = pipe_codes[default_code[:4]]
                product_id = ''
            elif default_code[:2] in ('PO', 'MS', 'MT', 'TL', 'TS'):
                # Clean HW packed:
                default_code = default_code[:8].strip()
                product_id = ''
            elif category == 'Prodotti finiti':
                # Final product packed:
                if not default_code[:3].isdigit():
                    default_code = default_code[:6].strip()
                    product_id = ''
            elif category in ('Esclusi', 'Lavorazioni'):
                # Remove category:
                _logger.warning('Saltati prodotti categoria: %s: %s '
                                '[q. %s]\n' % (
                                    category, default_code, qty))
                jump = True

            if qty <= 0:
                jump = True

            # Write line in Excel:
            excel_line = [
                product_id, real_code, name, category, default_code, qty, 0,
            ]
            excel_pool.write_xls_line(
                ws_name, row, excel_line,
                default_format=excel_format['white']['text'])

            if jump:
                continue

            # Save in pickle only used data:
            pickle_data.append({
                'product_id': product_id,
                'name': name,
                'category': category,
                'qty': qty,
                'default_code': real_code,
                'compress_code': default_code,
            })

        pickle.dump(pickle_data, open(pickle_file, 'wb'))
        excel_pool.save_file_as(excel_file)
        return True

    _columns = {
        'name': fields.char('Anno', size=64, required=True),
        'base_folder': fields.char(
            'Cartella base', size=180,
            help='Cartella dove sono memorizzati tutti i file della gestione'),
        'from_date': fields.date('Dalla data', required=True),
        'to_date': fields.date('Alla data', required=True),
    }

<|endoftext|>


<commit_before># ***************************************************************************
# *                                                                         *
# *   Copyright (c) 2016 - Bernd Hahnebach <bernd@bimstatik.org>            *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   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 Library General Public License for more details.                  *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with this program; if not, write to the Free Software   *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************

__title__ = "FreeCAD Z88 Disp Reader"
__author__ = "Bernd Hahnebach"
__url__ = "http://www.freecadweb.org"

## @package importZ88O2Results
#  \ingroup FEM
#  \brief FreeCAD Z88 Disp Reader for FEM workbench

import FreeCAD
import os

Debug = False

# ********* generic FreeCAD import and export methods *********
if open.__module__ == '__builtin__':
    # because we'll redefine open below (Python2)
    pyopen = open
elif open.__module__ == 'io':
    # because we'll redefine open below (Python3)
    pyopen = open

def open(filename):
    "called when freecad opens a file"
    docname = os.path.splitext(os.path.basename(filename))[0]
    insert(filename, docname)

def insert(filename, docname):
    "called when freecad wants to import a file"
    try:
        doc = FreeCAD.getDocument(docname)
    except NameError:
        doc = FreeCAD.newDocument(docname)
    FreeCAD.ActiveDocument = doc
    import_z88_disp(filename)

# ********* module specific methods *********
def import_z88_disp(filename, analysis=None, result_name_prefix=None):
    '''insert a FreeCAD FEM mechanical result object in the ActiveDocument
    pure usage:
    import feminout.importZ88O2Results as importZ88O2Results
    disp_file = '/pathtofile/z88o2.txt'
    importZ88O2Results.import_z88_disp(disp_file)

    the z888i1.txt FEMMesh file needs to be in the same directory as z88o2.txt (ahh, make a new document first ;-))
    '''
    from . import importZ88Mesh
    from . import importToolsFem
    import ObjectsFem
    if result_name_prefix is None:
        result_name_prefix = ''
    disp_read = read_z88_disp(filename)
    result_mesh_object = None
    if len(disp_read['Nodes']) > 0:
        if analysis:
            analysis_object = analysis

        # read result mesh
        if filename.endswith('z88o2.txt'):
            mesh_file = filename.replace('o2', 'i1')
            mesh_data = importZ88Mesh.read_z88_mesh(mesh_file)
            femmesh = importToolsFem.make_femmesh(mesh_data)
            result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh')
            result_mesh_object.FemMesh = femmesh
        else:
            FreeCAD.Console.PrintError('Z88 mesh file z88i1.txt not found!')

        # create result obj
        for result_set in disp_read['Results']:
            results_name = result_name_prefix + 'results'

            results = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name)
            results.Mesh = result_mesh_object
            results = importToolsFem.fill_femresult_mechanical(results, result_set, 0)
            if analysis:
                analysis_object.addObject(results)

        if FreeCAD.GuiUp:
            if analysis:
                import FemGui
                FemGui.setActiveAnalysis(analysis_object)
            FreeCAD.ActiveDocument.recompute()

    else:
        FreeCAD.Console.PrintError('Problem on frd file import. No nodes found in frd file.\n')

def read_z88_disp(z88_disp_input):
    '''
    read a z88 disp file and extract the nodes and elements
    z88 Displacement output file is z88o2.txt
    works with Z88OS14
    '''
    nodes = {}
    mode_disp = {}
    mode_results = {}
    results = []

    z88_disp_file = pyopen(z88_disp_input, "r")

    for no, line in enumerate(z88_disp_file):
        lno = no + 1
        linelist = line.split()

        if lno >= 6:
            # disp line
            # print(linelist)
            node_no = int(linelist[0])
            mode_disp_x = float(linelist[1])
            mode_disp_y = float(linelist[2])
            if len(linelist) > 3:
                mode_disp_z = float(linelist[3])
            else:
                mode_disp_z = 0.0
            mode_disp[node_no] = FreeCAD.Vector(mode_disp_x, mode_disp_y, mode_disp_z)
            nodes[node_no] = node_no

    mode_results['disp'] = mode_disp
    results.append(mode_results)

    if Debug:
        for r in results[0]['disp']:
            print(r, ' --> ', results[0]['disp'][r])

    z88_disp_file.close()
    return {'Nodes': nodes, 'Results': results}
<commit_msg>FEM: Z88 result reader, typo in error message<commit_after># ***************************************************************************
# *                                                                         *
# *   Copyright (c) 2016 - Bernd Hahnebach <bernd@bimstatik.org>            *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   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 Library General Public License for more details.                  *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with this program; if not, write to the Free Software   *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************

__title__ = "FreeCAD Z88 Disp Reader"
__author__ = "Bernd Hahnebach"
__url__ = "http://www.freecadweb.org"

## @package importZ88O2Results
#  \ingroup FEM
#  \brief FreeCAD Z88 Disp Reader for FEM workbench

import FreeCAD
import os

Debug = False

# ********* generic FreeCAD import and export methods *********
if open.__module__ == '__builtin__':
    # because we'll redefine open below (Python2)
    pyopen = open
elif open.__module__ == 'io':
    # because we'll redefine open below (Python3)
    pyopen = open

def open(filename):
    "called when freecad opens a file"
    docname = os.path.splitext(os.path.basename(filename))[0]
    insert(filename, docname)

def insert(filename, docname):
    "called when freecad wants to import a file"
    try:
        doc = FreeCAD.getDocument(docname)
    except NameError:
        doc = FreeCAD.newDocument(docname)
    FreeCAD.ActiveDocument = doc
    import_z88_disp(filename)

# ********* module specific methods *********
def import_z88_disp(filename, analysis=None, result_name_prefix=None):
    '''insert a FreeCAD FEM mechanical result object in the ActiveDocument
    pure usage:
    import feminout.importZ88O2Results as importZ88O2Results
    disp_file = '/pathtofile/z88o2.txt'
    importZ88O2Results.import_z88_disp(disp_file)

    the z888i1.txt FEMMesh file needs to be in the same directory as z88o2.txt (ahh, make a new document first ;-))
    '''
    from . import importZ88Mesh
    from . import importToolsFem
    import ObjectsFem
    if result_name_prefix is None:
        result_name_prefix = ''
    disp_read = read_z88_disp(filename)
    result_mesh_object = None
    if len(disp_read['Nodes']) > 0:
        if analysis:
            analysis_object = analysis

        # read result mesh
        if filename.endswith('z88o2.txt'):
            mesh_file = filename.replace('o2', 'i1')
            mesh_data = importZ88Mesh.read_z88_mesh(mesh_file)
            femmesh = importToolsFem.make_femmesh(mesh_data)
            result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh')
            result_mesh_object.FemMesh = femmesh
        else:
            FreeCAD.Console.PrintError('Z88 mesh file z88i1.txt not found!')

        # create result obj
        for result_set in disp_read['Results']:
            results_name = result_name_prefix + 'results'

            results = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name)
            results.Mesh = result_mesh_object
            results = importToolsFem.fill_femresult_mechanical(results, result_set, 0)
            if analysis:
                analysis_object.addObject(results)

        if FreeCAD.GuiUp:
            if analysis:
                import FemGui
                FemGui.setActiveAnalysis(analysis_object)
            FreeCAD.ActiveDocument.recompute()

    else:
        FreeCAD.Console.PrintError('Problem on Z88 result file import. No nodes found in Z88 result file.\n')

def read_z88_disp(z88_disp_input):
    '''
    read a z88 disp file and extract the nodes and elements
    z88 Displacement output file is z88o2.txt
    works with Z88OS14
    '''
    nodes = {}
    mode_disp = {}
    mode_results = {}
    results = []

    z88_disp_file = pyopen(z88_disp_input, "r")

    for no, line in enumerate(z88_disp_file):
        lno = no + 1
        linelist = line.split()

        if lno >= 6:
            # disp line
            # print(linelist)
            node_no = int(linelist[0])
            mode_disp_x = float(linelist[1])
            mode_disp_y = float(linelist[2])
            if len(linelist) > 3:
                mode_disp_z = float(linelist[3])
            else:
                mode_disp_z = 0.0
            mode_disp[node_no] = FreeCAD.Vector(mode_disp_x, mode_disp_y, mode_disp_z)
            nodes[node_no] = node_no

    mode_results['disp'] = mode_disp
    results.append(mode_results)

    if Debug:
        for r in results[0]['disp']:
            print(r, ' --> ', results[0]['disp'][r])

    z88_disp_file.close()
    return {'Nodes': nodes, 'Results': results}
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

# Copyright(C) 2013-2015      Christophe Lampin
#
# This file is part of weboob.
#
# weboob 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.
#
# weboob 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 weboob. If not, see <http://www.gnu.org/licenses/>.

from weboob.browser import LoginBrowser, URL, need_login
from weboob.exceptions import BrowserIncorrectPassword
from weboob.capabilities.bill import Detail
from decimal import Decimal
from .pages import LoginPage, LoginValidationPage, HomePage, AccountPage, LastPaymentsPage, PaymentDetailsPage, BillsPage

__all__ = ['AmeliBrowser']

class AmeliBrowser(LoginBrowser):
    BASEURL = 'https://assure.ameli.fr'

    loginp = URL('/PortailAS/appmanager/PortailAS/assure\?.*_pageLabel=as_login_page', LoginPage)
    login_validationp = URL('https://assure.ameli.fr:443/PortailAS/appmanager/PortailAS/assure;jsessionid=[a-zA-Z0-9!;-]+\?_nfpb=true&_windowLabel=connexioncompte_2&connexioncompte_2_actionOverride=%2Fportlets%2Fconnexioncompte%2Fvalidationconnexioncompte&_pageLabel=as_login_page$', LoginValidationPage)
    homep = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_accueil_page', HomePage)
    accountp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_info_perso_page', AccountPage)
    billsp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_revele_mensuel_presta_page', BillsPage)
    paymentdetailsp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_dernier_paiement_page&paiements_1_actionOverride=%2Fportlets%2Fpaiements%2Fdetailpaiements&paiements_1idPaiement=.*', PaymentDetailsPage)
    lastpaymentsp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_dernier_paiement_page$', LastPaymentsPage)

    logged = False

    def do_login(self):
        self.logger.debug('call Browser.do_login')
        if self.logged:
            return True

        self.loginp.stay_or_go()
        if self.homep.is_here():
            self.logged = True
            return True

        self.page.login(self.username, self.password)

        error = self.page.is_error()
        if error:
            raise BrowserIncorrectPassword(error)

        self.homep.stay_or_go()  # Redirection not interpreted by browser. Mannually redirect on homep

        if not self.homep.is_here():
            raise BrowserIncorrectPassword()

        self.logged = True

    @need_login
    def iter_subscription_list(self):
        self.logger.debug('call Browser.iter_subscription_list')
        self.accountp.stay_or_go()
        return self.page.iter_subscription_list()

    @need_login
    def get_subscription(self, id):
        self.logger.debug('call Browser.get_subscription')
        assert isinstance(id, basestring)
        for sub in self.iter_subscription_list():
            if id == sub._id:
                return sub
        return None

    @need_login
    def iter_history(self, sub):
        self.logger.debug('call Browser.iter_history')
        self.lastpaymentsp.stay_or_go()
        urls = self.page.iter_last_payments()
        for url in urls:
            self.location(url)
            assert self.paymentdetailsp.is_here()
            for payment in self.page.iter_payment_details(sub):
                yield payment

    @need_login
    def iter_details(self, sub):
        self.logger.debug('call Browser.iter_details')
        det = Detail()
        det.id = sub.id
        det.label = sub.label
        det.infos = ''
        det.price = Decimal('0.0')
        yield det

    @need_login
    def iter_bills(self, sub):
        self.logger.debug('call Browser.iter_bills')
        if not sub._id.isdigit():
            return []
        self.billsp.stay_or_go()
        return self.page.iter_bills(sub)

    @need_login
    def get_bill(self, id):
        self.logger.debug('call Browser.get_bill')
        assert isinstance(id, basestring)
        subs = self.iter_subscription_list()
        for sub in subs:
            for b in self.iter_bills(sub):
                if id == b.id:
                    return b
        return False
<commit_msg>PaymentDetailsPage: use a simpler URL<commit_after># -*- coding: utf-8 -*-

# Copyright(C) 2013-2015      Christophe Lampin
#
# This file is part of weboob.
#
# weboob 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.
#
# weboob 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 weboob. If not, see <http://www.gnu.org/licenses/>.

from weboob.browser import LoginBrowser, URL, need_login
from weboob.exceptions import BrowserIncorrectPassword
from weboob.capabilities.bill import Detail
from decimal import Decimal
from .pages import LoginPage, LoginValidationPage, HomePage, AccountPage, LastPaymentsPage, PaymentDetailsPage, BillsPage

__all__ = ['AmeliBrowser']

class AmeliBrowser(LoginBrowser):
    BASEURL = 'https://assure.ameli.fr'

    loginp = URL('/PortailAS/appmanager/PortailAS/assure\?.*_pageLabel=as_login_page', LoginPage)
    login_validationp = URL('https://assure.ameli.fr:443/PortailAS/appmanager/PortailAS/assure;jsessionid=[a-zA-Z0-9!;-]+\?_nfpb=true&_windowLabel=connexioncompte_2&connexioncompte_2_actionOverride=%2Fportlets%2Fconnexioncompte%2Fvalidationconnexioncompte&_pageLabel=as_login_page$', LoginValidationPage)
    homep = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_accueil_page', HomePage)
    accountp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_info_perso_page', AccountPage)
    billsp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_revele_mensuel_presta_page', BillsPage)
    paymentdetailsp = URL('/PortailAS/appmanager/PortailAS/assure\?.*_pageLabel=as_dernier_paiement_page&paiements_1_actionOverride=%2Fportlets%2Fpaiements%2Fdetailpaiements.*', PaymentDetailsPage)
    lastpaymentsp = URL('/PortailAS/appmanager/PortailAS/assure\?_nfpb=true&_pageLabel=as_dernier_paiement_page$', LastPaymentsPage)

    logged = False

    def do_login(self):
        self.logger.debug('call Browser.do_login')
        if self.logged:
            return True

        self.loginp.stay_or_go()
        if self.homep.is_here():
            self.logged = True
            return True

        self.page.login(self.username, self.password)

        error = self.page.is_error()
        if error:
            raise BrowserIncorrectPassword(error)

        self.homep.stay_or_go()  # Redirection not interpreted by browser. Mannually redirect on homep

        if not self.homep.is_here():
            raise BrowserIncorrectPassword()

        self.logged = True

    @need_login
    def iter_subscription_list(self):
        self.logger.debug('call Browser.iter_subscription_list')
        self.accountp.stay_or_go()
        return self.page.iter_subscription_list()

    @need_login
    def get_subscription(self, id):
        self.logger.debug('call Browser.get_subscription')
        assert isinstance(id, basestring)
        for sub in self.iter_subscription_list():
            if id == sub._id:
                return sub
        return None

    @need_login
    def iter_history(self, sub):
        self.logger.debug('call Browser.iter_history')
        self.lastpaymentsp.stay_or_go()
        urls = self.page.iter_last_payments()
        for url in urls:
            self.location(url)
            assert self.paymentdetailsp.is_here()
            for payment in self.page.iter_payment_details(sub):
                yield payment

    @need_login
    def iter_details(self, sub):
        self.logger.debug('call Browser.iter_details')
        det = Detail()
        det.id = sub.id
        det.label = sub.label
        det.infos = ''
        det.price = Decimal('0.0')
        yield det

    @need_login
    def iter_bills(self, sub):
        self.logger.debug('call Browser.iter_bills')
        if not sub._id.isdigit():
            return []
        self.billsp.stay_or_go()
        return self.page.iter_bills(sub)

    @need_login
    def get_bill(self, id):
        self.logger.debug('call Browser.get_bill')
        assert isinstance(id, basestring)
        subs = self.iter_subscription_list()
        for sub in subs:
            for b in self.iter_bills(sub):
                if id == b.id:
                    return b
        return False
<|endoftext|>


<commit_before># Copyright 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import copy
import logging
import optparse
import os
import shlex
import sys

from telemetry.core import browser_finder
from telemetry.core import profile_types
from telemetry.core import util
from telemetry.core import wpr_modes
from telemetry.core.platform.profiler import profiler_finder

util.AddDirToPythonPath(
    util.GetChromiumSrcDir(), 'third_party', 'webpagereplay')
import net_configs  # pylint: disable=F0401

class BrowserFinderOptions(optparse.Values):
  """Options to be used for discovering a browser."""

  def __init__(self, browser_type=None):
    optparse.Values.__init__(self)

    self.browser_type = browser_type
    self.browser_executable = None
    self.chrome_root = None
    self.android_device = None
    self.cros_ssh_identity = None

    self.extensions_to_load = []

    # If set, copy the generated profile to this path on exit.
    self.output_profile_path = None

    self.cros_remote = None

    self.profiler = None
    self.verbosity = 0

    self.report_root_metrics = False

    self.browser_options = BrowserOptions()
    self.output_file = None
    self.skip_navigate_on_repeat = False

    self.android_rndis = False

  def __repr__(self):
    return str(sorted(self.__dict__.items()))

  def Copy(self):
    return copy.deepcopy(self)

  def CreateParser(self, *args, **kwargs):
    parser = optparse.OptionParser(*args, **kwargs)

    # Selection group
    group = optparse.OptionGroup(parser, 'Which browser to use')
    group.add_option('--browser',
        dest='browser_type',
        default=None,
        help='Browser type to run, '
             'in order of priority. Supported values: list,%s' %
             ','.join(browser_finder.ALL_BROWSER_TYPES))
    group.add_option('--browser-executable',
        dest='browser_executable',
        help='The exact browser to run.')
    group.add_option('--chrome-root',
        dest='chrome_root',
        help='Where to look for chrome builds.'
             'Defaults to searching parent dirs by default.')
    group.add_option('--device',
        dest='android_device',
        help='The android device ID to use'
             'If not specified, only 0 or 1 connected devcies are supported.')
    group.add_option(
        '--remote',
        dest='cros_remote',
        help='The IP address of a remote ChromeOS device to use.')
    identity = None
    testing_rsa = os.path.join(
        util.GetChromiumSrcDir(),
        'third_party', 'chromite', 'ssh_keys', 'testing_rsa')
    if os.path.exists(testing_rsa):
      identity = testing_rsa
    group.add_option('--identity',
        dest='cros_ssh_identity',
        default=identity,
        help='The identity file to use when ssh\'ing into the ChromeOS device')
    parser.add_option_group(group)

    # Debugging options
    group = optparse.OptionGroup(parser, 'When things go wrong')
    profiler_choices = profiler_finder.GetAllAvailableProfilers()
    group.add_option(
        '--profiler', default=None, type='choice',
        choices=profiler_choices,
        help='Record profiling data using this tool. Supported values: ' +
             ', '.join(profiler_choices))
    group.add_option(
        '--interactive', dest='interactive', action='store_true',
        help='Let the user interact with the page; the actions specified for '
             'the page are not run.')
    group.add_option(
        '-v', '--verbose', action='count', dest='verbosity',
        help='Increase verbosity level (repeat as needed)')
    group.add_option('--print-bootstrap-deps',
                     action='store_true',
                     help='Output bootstrap deps list.')
    parser.add_option_group(group)

    # Platform options
    group = optparse.OptionGroup(parser, 'Platform options')
    group.add_option('--no-performance-mode', action='store_true',
        help='Some platforms run on "full performance mode" where the '
        'test is executed at maximum CPU speed in order to minimize noise '
        '(specially important for dashboards / continuous builds). '
        'This option prevents Telemetry from tweaking such platform settings.')
    group.add_option(
        '--report-root-metrics', action='store_true',dest='report_root_metrics',
        help='Enable metrics that require root access to record.')
    group.add_option('--android-rndis', dest='android_rndis', default=False,
        action='store_true', help='Use RNDIS forwarding on Android.')
    group.add_option('--no-android-rndis', dest='android_rndis',
        action='store_false', help='Do not use RNDIS forwarding on Android.'
        ' [default]')
    parser.add_option_group(group)

    # Browser options.
    self.browser_options.AddCommandLineArgs(parser)

    real_parse = parser.parse_args
    def ParseArgs(args=None):
      defaults = parser.get_default_values()
      for k, v in defaults.__dict__.items():
        if k in self.__dict__ and self.__dict__[k] != None:
          continue
        self.__dict__[k] = v
      ret = real_parse(args, self) # pylint: disable=E1121

      if self.verbosity >= 2:
        logging.getLogger().setLevel(logging.DEBUG)
      elif self.verbosity:
        logging.getLogger().setLevel(logging.INFO)
      else:
        logging.getLogger().setLevel(logging.WARNING)

      if self.browser_executable and not self.browser_type:
        self.browser_type = 'exact'
      if self.browser_type == 'list':
        try:
          types = browser_finder.GetAllAvailableBrowserTypes(self)
        except browser_finder.BrowserFinderException, ex:
          sys.stderr.write('ERROR: ' + str(ex))
          sys.exit(1)
        sys.stdout.write('Available browsers:\n')
        sys.stdout.write('  %s\n' % '\n  '.join(types))
        sys.exit(0)

      # Parse browser options.
      self.browser_options.UpdateFromParseResults(self)

      return ret
    parser.parse_args = ParseArgs
    return parser

  def AppendExtraBrowserArgs(self, args):
    self.browser_options.AppendExtraBrowserArgs(args)

  def MergeDefaultValues(self, defaults):
    for k, v in defaults.__dict__.items():
      self.ensure_value(k, v)

class BrowserOptions(object):
  """Options to be used for launching a browser."""
  def __init__(self):
    self.browser_type = None
    self.show_stdout = False

    # When set to True, the browser will use the default profile.  Telemetry
    # will not provide an alternate profile directory.
    self.dont_override_profile = False
    self.profile_dir = None
    self.profile_type = None
    self._extra_browser_args = set()
    self.extra_wpr_args = []
    self.wpr_mode = wpr_modes.WPR_OFF
    self.netsim = None

    self.no_proxy_server = False
    self.browser_user_agent_type = None

    self.clear_sytem_cache_for_browser_and_profile_on_start = False
    self.startup_url = None

    # Background pages of built-in component extensions can interfere with
    # performance measurements.
    self.disable_component_extensions_with_background_pages = True

    # Whether to use the new code path for choosing an ephemeral port for
    # DevTools. The bots set this to true. When Chrome 37 reaches stable,
    # remove this setting and the old code path. http://crbug.com/379980
    self.use_devtools_active_port = False

  def __repr__(self):
    return str(sorted(self.__dict__.items()))

  @classmethod
  def AddCommandLineArgs(cls, parser):

    ############################################################################
    # Please do not add any more options here without first discussing with    #
    # a telemetry owner. This is not the right place for platform-specific     #
    # options.                                                                 #
    ############################################################################

    group = optparse.OptionGroup(parser, 'Browser options')
    profile_choices = profile_types.GetProfileTypes()
    group.add_option('--profile-type',
        dest='profile_type',
        type='choice',
        default='clean',
        choices=profile_choices,
        help=('The user profile to use. A clean profile is used by default. '
              'Supported values: ' + ', '.join(profile_choices)))
    group.add_option('--profile-dir',
        dest='profile_dir',
        help='Profile directory to launch the browser with. '
             'A clean profile is used by default')
    group.add_option('--extra-browser-args',
        dest='extra_browser_args_as_string',
        help='Additional arguments to pass to the browser when it starts')
    group.add_option('--extra-wpr-args',
        dest='extra_wpr_args_as_string',
        help=('Additional arguments to pass to Web Page Replay. '
              'See third_party/webpagereplay/replay.py for usage.'))
    group.add_option('--netsim', default=None, type='choice',
        choices=net_configs.NET_CONFIG_NAMES,
        help=('Run benchmark under simulated network conditions. '
              'Will prompt for sudo. Supported values: ' +
              ', '.join(net_configs.NET_CONFIG_NAMES)))
    group.add_option('--show-stdout',
        action='store_true',
        help='When possible, will display the stdout of the process')
    # This hidden option is to be removed, and the older code path deleted,
    # once Chrome 37 reaches Stable. http://crbug.com/379980
    group.add_option('--use-devtools-active-port',
        action='store_true',
        help=optparse.SUPPRESS_HELP)
    parser.add_option_group(group)

    group = optparse.OptionGroup(parser, 'Compatibility options')
    group.add_option('--gtest_output',
        help='Ignored argument for compatibility with runtest.py harness')
    parser.add_option_group(group)

    group = optparse.OptionGroup(parser, 'Synthetic gesture options')
    synthetic_gesture_source_type_choices = [ 'default', 'mouse', 'touch' ]
    group.add_option('--synthetic-gesture-source-type',
        dest='synthetic_gesture_source_type',
        default='default', type='choice',
        choices=synthetic_gesture_source_type_choices,
        help='Specify the source type for synthetic gestures. Note that some ' +
             'actions only support a specific source type. ' +
             'Supported values: ' +
             ', '.join(synthetic_gesture_source_type_choices))
    parser.add_option_group(group)

  def UpdateFromParseResults(self, finder_options):
    """Copies our options from finder_options"""
    browser_options_list = [
        'extra_browser_args_as_string',
        'extra_wpr_args_as_string',
        'netsim',
        'profile_dir',
        'profile_type',
        'show_stdout',
        'synthetic_gesture_source_type',
        'use_devtools_active_port',
        ]
    for o in browser_options_list:
      a = getattr(finder_options, o, None)
      if a is not None:
        setattr(self, o, a)
        delattr(finder_options, o)

    self.browser_type = finder_options.browser_type

    if hasattr(self, 'extra_browser_args_as_string'): # pylint: disable=E1101
      tmp = shlex.split(
        self.extra_browser_args_as_string) # pylint: disable=E1101
      self.AppendExtraBrowserArgs(tmp)
      delattr(self, 'extra_browser_args_as_string')
    if hasattr(self, 'extra_wpr_args_as_string'): # pylint: disable=E1101
      tmp = shlex.split(
        self.extra_wpr_args_as_string) # pylint: disable=E1101
      self.extra_wpr_args.extend(tmp)
      delattr(self, 'extra_wpr_args_as_string')
    if self.profile_type == 'default':
      self.dont_override_profile = True

    if self.profile_dir and self.profile_type != 'clean':
      logging.critical(
          "It's illegal to specify both --profile-type and --profile-dir.\n"
          "For more information see: http://goo.gl/ngdGD5")
      sys.exit(1)

    if self.profile_dir and not os.path.isdir(self.profile_dir):
      logging.critical(
          "Directory specified by --profile-dir (%s) doesn't exist "
          "or isn't a directory.\n"
          "For more information see: http://goo.gl/ngdGD5" % self.profile_dir)
      sys.exit(1)

    if not self.profile_dir:
      self.profile_dir = profile_types.GetProfileDir(self.profile_type)

    # This deferred import is necessary because browser_options is imported in
    # telemetry/telemetry/__init__.py.
    from telemetry.core.backends.chrome import chrome_browser_options
    finder_options.browser_options = (
        chrome_browser_options.CreateChromeBrowserOptions(self))

  @property
  def extra_browser_args(self):
    return self._extra_browser_args

  def AppendExtraBrowserArgs(self, args):
    if isinstance(args, list):
      self._extra_browser_args.update(args)
    else:
      self._extra_browser_args.add(args)
<commit_msg>[Telemetry] Cleanup: remove unused --report_root_metrics flag<commit_after># Copyright 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import copy
import logging
import optparse
import os
import shlex
import sys

from telemetry.core import browser_finder
from telemetry.core import profile_types
from telemetry.core import util
from telemetry.core import wpr_modes
from telemetry.core.platform.profiler import profiler_finder

util.AddDirToPythonPath(
    util.GetChromiumSrcDir(), 'third_party', 'webpagereplay')
import net_configs  # pylint: disable=F0401

class BrowserFinderOptions(optparse.Values):
  """Options to be used for discovering a browser."""

  def __init__(self, browser_type=None):
    optparse.Values.__init__(self)

    self.browser_type = browser_type
    self.browser_executable = None
    self.chrome_root = None
    self.android_device = None
    self.cros_ssh_identity = None

    self.extensions_to_load = []

    # If set, copy the generated profile to this path on exit.
    self.output_profile_path = None

    self.cros_remote = None

    self.profiler = None
    self.verbosity = 0

    self.browser_options = BrowserOptions()
    self.output_file = None
    self.skip_navigate_on_repeat = False

    self.android_rndis = False

  def __repr__(self):
    return str(sorted(self.__dict__.items()))

  def Copy(self):
    return copy.deepcopy(self)

  def CreateParser(self, *args, **kwargs):
    parser = optparse.OptionParser(*args, **kwargs)

    # Selection group
    group = optparse.OptionGroup(parser, 'Which browser to use')
    group.add_option('--browser',
        dest='browser_type',
        default=None,
        help='Browser type to run, '
             'in order of priority. Supported values: list,%s' %
             ','.join(browser_finder.ALL_BROWSER_TYPES))
    group.add_option('--browser-executable',
        dest='browser_executable',
        help='The exact browser to run.')
    group.add_option('--chrome-root',
        dest='chrome_root',
        help='Where to look for chrome builds.'
             'Defaults to searching parent dirs by default.')
    group.add_option('--device',
        dest='android_device',
        help='The android device ID to use'
             'If not specified, only 0 or 1 connected devcies are supported.')
    group.add_option(
        '--remote',
        dest='cros_remote',
        help='The IP address of a remote ChromeOS device to use.')
    identity = None
    testing_rsa = os.path.join(
        util.GetChromiumSrcDir(),
        'third_party', 'chromite', 'ssh_keys', 'testing_rsa')
    if os.path.exists(testing_rsa):
      identity = testing_rsa
    group.add_option('--identity',
        dest='cros_ssh_identity',
        default=identity,
        help='The identity file to use when ssh\'ing into the ChromeOS device')
    parser.add_option_group(group)

    # Debugging options
    group = optparse.OptionGroup(parser, 'When things go wrong')
    profiler_choices = profiler_finder.GetAllAvailableProfilers()
    group.add_option(
        '--profiler', default=None, type='choice',
        choices=profiler_choices,
        help='Record profiling data using this tool. Supported values: ' +
             ', '.join(profiler_choices))
    group.add_option(
        '--interactive', dest='interactive', action='store_true',
        help='Let the user interact with the page; the actions specified for '
             'the page are not run.')
    group.add_option(
        '-v', '--verbose', action='count', dest='verbosity',
        help='Increase verbosity level (repeat as needed)')
    group.add_option('--print-bootstrap-deps',
                     action='store_true',
                     help='Output bootstrap deps list.')
    parser.add_option_group(group)

    # Platform options
    group = optparse.OptionGroup(parser, 'Platform options')
    group.add_option('--no-performance-mode', action='store_true',
        help='Some platforms run on "full performance mode" where the '
        'test is executed at maximum CPU speed in order to minimize noise '
        '(specially important for dashboards / continuous builds). '
        'This option prevents Telemetry from tweaking such platform settings.')
    group.add_option('--android-rndis', dest='android_rndis', default=False,
        action='store_true', help='Use RNDIS forwarding on Android.')
    group.add_option('--no-android-rndis', dest='android_rndis',
        action='store_false', help='Do not use RNDIS forwarding on Android.'
        ' [default]')
    parser.add_option_group(group)

    # Browser options.
    self.browser_options.AddCommandLineArgs(parser)

    real_parse = parser.parse_args
    def ParseArgs(args=None):
      defaults = parser.get_default_values()
      for k, v in defaults.__dict__.items():
        if k in self.__dict__ and self.__dict__[k] != None:
          continue
        self.__dict__[k] = v
      ret = real_parse(args, self) # pylint: disable=E1121

      if self.verbosity >= 2:
        logging.getLogger().setLevel(logging.DEBUG)
      elif self.verbosity:
        logging.getLogger().setLevel(logging.INFO)
      else:
        logging.getLogger().setLevel(logging.WARNING)

      if self.browser_executable and not self.browser_type:
        self.browser_type = 'exact'
      if self.browser_type == 'list':
        try:
          types = browser_finder.GetAllAvailableBrowserTypes(self)
        except browser_finder.BrowserFinderException, ex:
          sys.stderr.write('ERROR: ' + str(ex))
          sys.exit(1)
        sys.stdout.write('Available browsers:\n')
        sys.stdout.write('  %s\n' % '\n  '.join(types))
        sys.exit(0)

      # Parse browser options.
      self.browser_options.UpdateFromParseResults(self)

      return ret
    parser.parse_args = ParseArgs
    return parser

  def AppendExtraBrowserArgs(self, args):
    self.browser_options.AppendExtraBrowserArgs(args)

  def MergeDefaultValues(self, defaults):
    for k, v in defaults.__dict__.items():
      self.ensure_value(k, v)

class BrowserOptions(object):
  """Options to be used for launching a browser."""
  def __init__(self):
    self.browser_type = None
    self.show_stdout = False

    # When set to True, the browser will use the default profile.  Telemetry
    # will not provide an alternate profile directory.
    self.dont_override_profile = False
    self.profile_dir = None
    self.profile_type = None
    self._extra_browser_args = set()
    self.extra_wpr_args = []
    self.wpr_mode = wpr_modes.WPR_OFF
    self.netsim = None

    self.no_proxy_server = False
    self.browser_user_agent_type = None

    self.clear_sytem_cache_for_browser_and_profile_on_start = False
    self.startup_url = None

    # Background pages of built-in component extensions can interfere with
    # performance measurements.
    self.disable_component_extensions_with_background_pages = True

    # Whether to use the new code path for choosing an ephemeral port for
    # DevTools. The bots set this to true. When Chrome 37 reaches stable,
    # remove this setting and the old code path. http://crbug.com/379980
    self.use_devtools_active_port = False

  def __repr__(self):
    return str(sorted(self.__dict__.items()))

  @classmethod
  def AddCommandLineArgs(cls, parser):

    ############################################################################
    # Please do not add any more options here without first discussing with    #
    # a telemetry owner. This is not the right place for platform-specific     #
    # options.                                                                 #
    ############################################################################

    group = optparse.OptionGroup(parser, 'Browser options')
    profile_choices = profile_types.GetProfileTypes()
    group.add_option('--profile-type',
        dest='profile_type',
        type='choice',
        default='clean',
        choices=profile_choices,
        help=('The user profile to use. A clean profile is used by default. '
              'Supported values: ' + ', '.join(profile_choices)))
    group.add_option('--profile-dir',
        dest='profile_dir',
        help='Profile directory to launch the browser with. '
             'A clean profile is used by default')
    group.add_option('--extra-browser-args',
        dest='extra_browser_args_as_string',
        help='Additional arguments to pass to the browser when it starts')
    group.add_option('--extra-wpr-args',
        dest='extra_wpr_args_as_string',
        help=('Additional arguments to pass to Web Page Replay. '
              'See third_party/webpagereplay/replay.py for usage.'))
    group.add_option('--netsim', default=None, type='choice',
        choices=net_configs.NET_CONFIG_NAMES,
        help=('Run benchmark under simulated network conditions. '
              'Will prompt for sudo. Supported values: ' +
              ', '.join(net_configs.NET_CONFIG_NAMES)))
    group.add_option('--show-stdout',
        action='store_true',
        help='When possible, will display the stdout of the process')
    # This hidden option is to be removed, and the older code path deleted,
    # once Chrome 37 reaches Stable. http://crbug.com/379980
    group.add_option('--use-devtools-active-port',
        action='store_true',
        help=optparse.SUPPRESS_HELP)
    parser.add_option_group(group)

    group = optparse.OptionGroup(parser, 'Compatibility options')
    group.add_option('--gtest_output',
        help='Ignored argument for compatibility with runtest.py harness')
    parser.add_option_group(group)

    group = optparse.OptionGroup(parser, 'Synthetic gesture options')
    synthetic_gesture_source_type_choices = [ 'default', 'mouse', 'touch' ]
    group.add_option('--synthetic-gesture-source-type',
        dest='synthetic_gesture_source_type',
        default='default', type='choice',
        choices=synthetic_gesture_source_type_choices,
        help='Specify the source type for synthetic gestures. Note that some ' +
             'actions only support a specific source type. ' +
             'Supported values: ' +
             ', '.join(synthetic_gesture_source_type_choices))
    parser.add_option_group(group)

  def UpdateFromParseResults(self, finder_options):
    """Copies our options from finder_options"""
    browser_options_list = [
        'extra_browser_args_as_string',
        'extra_wpr_args_as_string',
        'netsim',
        'profile_dir',
        'profile_type',
        'show_stdout',
        'synthetic_gesture_source_type',
        'use_devtools_active_port',
        ]
    for o in browser_options_list:
      a = getattr(finder_options, o, None)
      if a is not None:
        setattr(self, o, a)
        delattr(finder_options, o)

    self.browser_type = finder_options.browser_type

    if hasattr(self, 'extra_browser_args_as_string'): # pylint: disable=E1101
      tmp = shlex.split(
        self.extra_browser_args_as_string) # pylint: disable=E1101
      self.AppendExtraBrowserArgs(tmp)
      delattr(self, 'extra_browser_args_as_string')
    if hasattr(self, 'extra_wpr_args_as_string'): # pylint: disable=E1101
      tmp = shlex.split(
        self.extra_wpr_args_as_string) # pylint: disable=E1101
      self.extra_wpr_args.extend(tmp)
      delattr(self, 'extra_wpr_args_as_string')
    if self.profile_type == 'default':
      self.dont_override_profile = True

    if self.profile_dir and self.profile_type != 'clean':
      logging.critical(
          "It's illegal to specify both --profile-type and --profile-dir.\n"
          "For more information see: http://goo.gl/ngdGD5")
      sys.exit(1)

    if self.profile_dir and not os.path.isdir(self.profile_dir):
      logging.critical(
          "Directory specified by --profile-dir (%s) doesn't exist "
          "or isn't a directory.\n"
          "For more information see: http://goo.gl/ngdGD5" % self.profile_dir)
      sys.exit(1)

    if not self.profile_dir:
      self.profile_dir = profile_types.GetProfileDir(self.profile_type)

    # This deferred import is necessary because browser_options is imported in
    # telemetry/telemetry/__init__.py.
    from telemetry.core.backends.chrome import chrome_browser_options
    finder_options.browser_options = (
        chrome_browser_options.CreateChromeBrowserOptions(self))

  @property
  def extra_browser_args(self):
    return self._extra_browser_args

  def AppendExtraBrowserArgs(self, args):
    if isinstance(args, list):
      self._extra_browser_args.update(args)
    else:
      self._extra_browser_args.add(args)
<|endoftext|>


<commit_before>from pprint import pprint

from fo2.connections import db_cursor_so

from base.views import O2BaseGetView

from cd.queries.novo_modulo.solicitacoes import get_solicitacao

class Solicitacao(O2BaseGetView):

    def __init__(self, *args, **kwargs):
        super(Solicitacao, self).__init__(*args, **kwargs)
        self.template_name = 'cd/novo_modulo/solicitacao.html'
        self.title_name = 'Solicitação'
        self.get_args = ['solicitacao']
        self.get_args2context = True

    def mount_context(self):
        cursor = db_cursor_so(self.request)

        data = get_solicitacao(cursor, self.context['solicitacao'])
        pprint(data)

        self.context.update({
            'headers': [
                'Situação',
                'Estágio',
                'OP',
                'OC',
                'Alter.',
                'Referência',
                'Tamanho',
                'Cor',
                'Quantidade',
                'Pedido destino',
                'OP destino',
            ],
            'fields': [
                'situacao',
                'codigo_estagio',
                'ordem_producao',
                'ordem_confeccao',
                'alter_destino',
                'grupo_destino',
                'sub_destino',
                'cor_destino',
                'qtde',
                'pedido_destino',
                'op_destino',
            ],
            'data': data,
        })
<commit_msg>view Solicitacao estágio finalizado<commit_after>from pprint import pprint

from fo2.connections import db_cursor_so

from base.views import O2BaseGetView

from cd.queries.novo_modulo.solicitacoes import get_solicitacao

class Solicitacao(O2BaseGetView):

    def __init__(self, *args, **kwargs):
        super(Solicitacao, self).__init__(*args, **kwargs)
        self.template_name = 'cd/novo_modulo/solicitacao.html'
        self.title_name = 'Solicitação'
        self.get_args = ['solicitacao']
        self.get_args2context = True

    def mount_context(self):
        cursor = db_cursor_so(self.request)

        data = get_solicitacao(cursor, self.context['solicitacao'])

        for row in data:
            if not row['codigo_estagio']:
                row['codigo_estagio'] = 'Finalizado'

        self.context.update({
            'headers': [
                'Situação',
                'Estágio',
                'OP',
                'OC',
                'Alter.',
                'Referência',
                'Tamanho',
                'Cor',
                'Quantidade',
                'Pedido destino',
                'OP destino',
            ],
            'fields': [
                'situacao',
                'codigo_estagio',
                'ordem_producao',
                'ordem_confeccao',
                'alter_destino',
                'grupo_destino',
                'sub_destino',
                'cor_destino',
                'qtde',
                'pedido_destino',
                'op_destino',
            ],
            'data': data,
        })
<|endoftext|>