<commit_before>from __future__ import unicode_literals

from django.apps import apps
from django.conf import settings
from django.contrib import admin
from django.contrib.admin.utils import unquote
from django.contrib.admin.views.main import ChangeList
from django.contrib.auth import get_permission_codename
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import NoReverseMatch, reverse
from django.utils.encoding import force_text
from django.utils.text import capfirst
from django.utils.translation import ugettext as _

from .enums import DjangoVersion
from .utils import django_version

class AdminViewPermissionChangeList(ChangeList):
    def __init__(self, *args, **kwargs):
        super(AdminViewPermissionChangeList, self).__init__(*args, **kwargs)
        # TODO: Exam if is None
        self.request = args[0]

        # If user has only view permission change the title of the changelist
        # view
        if self.model_admin.has_view_permission(self.request) and \
                not self.model_admin.has_change_permission(self.request,
                                                           only_change=True):
            if self.is_popup:
                title = _('Select %s')
            else:
                title = _('Select %s to view')
            self.title = title % force_text(self.opts.verbose_name)

class AdminViewPermissionBaseModelAdmin(admin.options.BaseModelAdmin):
    def get_model_perms(self, request):
        """
        Returns a dict of all perms for this model. This dict has the keys
        ``add``, ``change``, ``delete`` and ``view`` mapping to the True/False
        for each of those actions.
        """
        return {
            'add': self.has_add_permission(request),
            'change': self.has_change_permission(request),
            'delete': self.has_delete_permission(request),
            'view': self.has_view_permission(request)
        }

    def has_view_permission(self, request, obj=None):
        """
        Returns True if the given request has permission to view an object.
        Can be overridden by the user in subclasses.
        """
        opts = self.opts
        codename = get_permission_codename('view', opts)
        return request.user.has_perm("%s.%s" % (opts.app_label, codename))

    def has_change_permission(self, request, obj=None, only_change=False):
        """
        Override this method in order to return True whenever a user has view
        permission and avoid re-implementing the change_view and
        changelist_view views. Also, added an extra argument to determine
        whenever this function will return the original response
        """
        change_permission = super(AdminViewPermissionBaseModelAdmin,
                                  self).has_change_permission(request, obj)
        if only_change:
            return change_permission
        else:
            if change_permission or self.has_view_permission(request, obj):
                return True
            else:
                return change_permission

    def get_fields(self, request, obj=None):
        """
        If the user has only the view permission return these readonly fields
        which are in fields attr
        """
        if self.has_view_permission(request, obj) and \
                not self.has_change_permission(request, obj, True):
            fields = super(AdminViewPermissionBaseModelAdmin, self).get_fields(
                request, obj)
            readonly_fields = self.get_readonly_fields(request, obj)
            new_fields = [i for i in fields if i in readonly_fields]
            return new_fields
        else:
            return super(AdminViewPermissionBaseModelAdmin, self).get_fields(
                request, obj)

    def get_readonly_fields(self, request, obj=None):
        """
        Return all fields as readonly for the view permission
        """
        # get read_only fields specified on the admin class is available
        # (needed for @property fields)
        readonly_fields = super(AdminViewPermissionBaseModelAdmin,
                                self).get_readonly_fields(request, obj)

        if (self.has_view_permission(request, obj) and
                not self.has_change_permission(request, obj, True)):

            readonly_fields = (
                list(readonly_fields) +
                [field.name for field in self.opts.local_fields
                 if field.editable] +
                [field.name for field in self.opts.local_many_to_many
                 if field.editable]
            )

            # Try to remove id if user have not specify fields and
            # readonly fields
            try:
                readonly_fields.remove('id')
            except ValueError:
                pass

            if self.fields:
                # Set as readonly fields the specified fields
                readonly_fields = self.fields

        return tuple(readonly_fields)

    def get_actions(self, request):
        """
        Override this funciton to remove the actions from the changelist view
        """
        if self.has_view_permission(request) and \
                not self.has_change_permission(request, only_change=True):
            return None
        else:
            return super(AdminViewPermissionBaseModelAdmin, self).get_actions(
                request)

class AdminViewPermissionInlineModelAdmin(AdminViewPermissionBaseModelAdmin,
                                          admin.options.InlineModelAdmin):
    def get_queryset(self, request):
        """
        Returns a QuerySet of all model instances that can be edited by the
        admin site. This is used by changelist_view.
        """
        if self.has_view_permission(request) and \
                not self.has_change_permission(request, None, True):
            return super(AdminViewPermissionInlineModelAdmin, self)\
                .get_queryset(request)
        else:
            # TODO: Somehow super executes admin.options.InlineModelAdmin
            # get_queryset and AdminViewPermissionBaseModelAdmin which is
            # convinient
            return super(AdminViewPermissionInlineModelAdmin, self)\
                .get_queryset(request)

    '''def has_parent_view_permission(self, request, obj=None):
        if getattr(self.parent_model, 'assigned_modeladmin', None):
            parent_modeladmin = self.parent_model.assigned_modeladmin
            return parent_modeladmin.has_view_permission(request, obj) \
                   and not parent_modeladmin.has_change_permission(request,
                                                                   obj, True)

        return False'''

class AdminViewPermissionModelAdmin(AdminViewPermissionBaseModelAdmin,
                                    admin.ModelAdmin):
    def __init__(self, model, admin_site):
        super(AdminViewPermissionModelAdmin, self).__init__(model, admin_site)
        # Contibute this class to the model
        setattr(self.model, 'assigned_modeladmin', self)

    def get_changelist(self, request, **kwargs):
        """
        Returns the ChangeList class for use on the changelist page.
        """
        return AdminViewPermissionChangeList

    def get_inline_instances(self, request, obj=None):
        inline_instances = []
        for inline_class in self.inlines:
            new_class = type(
                str('DynamicAdminViewPermissionInlineModelAdmin'),
                (inline_class, AdminViewPermissionInlineModelAdmin),
                dict(inline_class.__dict__))

            inline = new_class(self.model, self.admin_site)
            if request:
                if not (inline.has_view_permission(request, obj) or
                        inline.has_add_permission(request) or
                        inline.has_change_permission(request, obj, True) or
                        inline.has_delete_permission(request, obj)):
                    continue
                if inline.has_view_permission(request, obj) and \
                        not inline.has_change_permission(request, obj, True):
                    inline.can_delete = False
                if not inline.has_add_permission(request):
                    inline.max_num = 0
            inline_instances.append(inline)

        return inline_instances

    def change_view(self, request, object_id, form_url='', extra_context=None):
        """
        Override this function to hide the sumbit row from the user who has
        view only permission
        """
        model = self.model
        opts = model._meta

        if object_id:
            obj = None
        else:
            obj = self.get_object(request, unquote(object_id))

        if self.has_view_permission(request, obj) and \
                not self.has_change_permission(request, obj, True):
            extra_context = extra_context or {}
            extra_context['title'] = _('View %s') % force_text(
                opts.verbose_name)

            extra_context['show_save'] = False
            extra_context['show_save_and_continue'] = False

            inlines = self.get_inline_instances(request, obj)
            for inline in inlines:
                if inline.has_change_permission(request, obj, True):
                    extra_context['show_save'] = True
                    extra_context['show_save_and_continue'] = True
                    break

        return super(AdminViewPermissionModelAdmin, self).change_view(
            request, object_id, form_url, extra_context)

class AdminViewPermissionAdminSite(admin.AdminSite):
    def register(self, model_or_iterable, admin_class=None, **options):
        """
        Create a new ModelAdmin class which inherits from the original and
        the above and register all models with that
        """
        SETTINGS_MODELS = getattr(settings, 'ADMIN_VIEW_PERMISSION_MODELS',
                                  None)

        models = model_or_iterable
        if not isinstance(model_or_iterable, tuple):
            models = tuple([model_or_iterable])

        if SETTINGS_MODELS or (SETTINGS_MODELS is not None and len(
                SETTINGS_MODELS) == 0):
            for model in models:
                if django_version() == DjangoVersion.DJANGO_18:
                    model_name = '%s.%s' % (model._meta.app_label,
                                            model._meta.object_name)
                elif django_version() > DjangoVersion.DJANGO_18:
                    model_name = model._meta.label

                if model_name in SETTINGS_MODELS:
                    if admin_class:
                        admin_class = type(
                            str('DynamicAdminViewPermissionModelAdmin'),
                            (admin_class, AdminViewPermissionModelAdmin),
                            dict(admin_class.__dict__))
                    else:
                        admin_class = AdminViewPermissionModelAdmin

                super(AdminViewPermissionAdminSite, self).register(model,
                                                                   admin_class,
                                                                   **options)
        else:
            if admin_class:
                admin_class = type(str('DynamicAdminViewPermissionModelAdmin'),
                                   (
                                       admin_class,
                                       AdminViewPermissionModelAdmin),
                                   dict(admin_class.__dict__))
            else:
                admin_class = AdminViewPermissionModelAdmin

            super(AdminViewPermissionAdminSite, self).register(
                model_or_iterable,
                admin_class, **options)

    def _build_app_dict(self, request, label=None):
        """
        Builds the app dictionary. Takes an optional label parameters to filter
        models of a specific app.
        """
        app_dict = {}

        if label:
            models = {
                m: m_a for m, m_a in self._registry.items()
                if m._meta.app_label == label
            }
        else:
            models = self._registry

        for model, model_admin in models.items():
            app_label = model._meta.app_label

            has_module_perms = model_admin.has_module_permission(request)
            if not has_module_perms:
                if label:
                    raise PermissionDenied
                continue

            perms = model_admin.get_model_perms(request)

            # Check whether user has any perm for this module.
            # If so, add the module to the model_list.
            if True not in perms.values():
                continue

            info = (app_label, model._meta.model_name)
            model_dict = {
                'name': capfirst(model._meta.verbose_name_plural),
                'object_name': model._meta.object_name,
                'perms': perms,
            }
            if perms.get('change') or perms.get('view'):
                try:
                    model_dict['admin_url'] = reverse(
                        'admin:%s_%s_changelist' % info, current_app=self.name)
                except NoReverseMatch:
                    pass
            if perms.get('add'):
                try:
                    model_dict['add_url'] = reverse('admin:%s_%s_add' % info,
                                                    current_app=self.name)
                except NoReverseMatch:
                    pass

            if app_label in app_dict:
                app_dict[app_label]['models'].append(model_dict)
            else:
                app_dict[app_label] = {
                    'name': apps.get_app_config(app_label).verbose_name,
                    'app_label': app_label,
                    'app_url': reverse(
                        'admin:app_list',
                        kwargs={'app_label': app_label},
                        current_app=self.name,
                    ),
                    'has_module_perms': has_module_perms,
                    'models': [model_dict],
                }

        if label:
            return app_dict.get(label)

        return app_dict
<commit_msg>Respect list argument in AdminViewPermissionAdminSite<commit_after>from __future__ import unicode_literals

from django.apps import apps
from django.conf import settings
from django.contrib import admin
from django.contrib.admin.utils import unquote
from django.contrib.admin.views.main import ChangeList
from django.contrib.auth import get_permission_codename
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import NoReverseMatch, reverse
from django.utils.encoding import force_text
from django.utils.text import capfirst
from django.utils.translation import ugettext as _

from .enums import DjangoVersion
from .utils import django_version

class AdminViewPermissionChangeList(ChangeList):
    def __init__(self, *args, **kwargs):
        super(AdminViewPermissionChangeList, self).__init__(*args, **kwargs)
        # TODO: Exam if is None
        self.request = args[0]

        # If user has only view permission change the title of the changelist
        # view
        if self.model_admin.has_view_permission(self.request) and \
                not self.model_admin.has_change_permission(self.request,
                                                           only_change=True):
            if self.is_popup:
                title = _('Select %s')
            else:
                title = _('Select %s to view')
            self.title = title % force_text(self.opts.verbose_name)

class AdminViewPermissionBaseModelAdmin(admin.options.BaseModelAdmin):
    def get_model_perms(self, request):
        """
        Returns a dict of all perms for this model. This dict has the keys
        ``add``, ``change``, ``delete`` and ``view`` mapping to the True/False
        for each of those actions.
        """
        return {
            'add': self.has_add_permission(request),
            'change': self.has_change_permission(request),
            'delete': self.has_delete_permission(request),
            'view': self.has_view_permission(request)
        }

    def has_view_permission(self, request, obj=None):
        """
        Returns True if the given request has permission to view an object.
        Can be overridden by the user in subclasses.
        """
        opts = self.opts
        codename = get_permission_codename('view', opts)
        return request.user.has_perm("%s.%s" % (opts.app_label, codename))

    def has_change_permission(self, request, obj=None, only_change=False):
        """
        Override this method in order to return True whenever a user has view
        permission and avoid re-implementing the change_view and
        changelist_view views. Also, added an extra argument to determine
        whenever this function will return the original response
        """
        change_permission = super(AdminViewPermissionBaseModelAdmin,
                                  self).has_change_permission(request, obj)
        if only_change:
            return change_permission
        else:
            if change_permission or self.has_view_permission(request, obj):
                return True
            else:
                return change_permission

    def get_fields(self, request, obj=None):
        """
        If the user has only the view permission return these readonly fields
        which are in fields attr
        """
        if self.has_view_permission(request, obj) and \
                not self.has_change_permission(request, obj, True):
            fields = super(AdminViewPermissionBaseModelAdmin, self).get_fields(
                request, obj)
            readonly_fields = self.get_readonly_fields(request, obj)
            new_fields = [i for i in fields if i in readonly_fields]
            return new_fields
        else:
            return super(AdminViewPermissionBaseModelAdmin, self).get_fields(
                request, obj)

    def get_readonly_fields(self, request, obj=None):
        """
        Return all fields as readonly for the view permission
        """
        # get read_only fields specified on the admin class is available
        # (needed for @property fields)
        readonly_fields = super(AdminViewPermissionBaseModelAdmin,
                                self).get_readonly_fields(request, obj)

        if (self.has_view_permission(request, obj) and
                not self.has_change_permission(request, obj, True)):

            readonly_fields = (
                list(readonly_fields) +
                [field.name for field in self.opts.local_fields
                 if field.editable] +
                [field.name for field in self.opts.local_many_to_many
                 if field.editable]
            )

            # Try to remove id if user have not specify fields and
            # readonly fields
            try:
                readonly_fields.remove('id')
            except ValueError:
                pass

            if self.fields:
                # Set as readonly fields the specified fields
                readonly_fields = self.fields

        return tuple(readonly_fields)

    def get_actions(self, request):
        """
        Override this funciton to remove the actions from the changelist view
        """
        if self.has_view_permission(request) and \
                not self.has_change_permission(request, only_change=True):
            return None
        else:
            return super(AdminViewPermissionBaseModelAdmin, self).get_actions(
                request)

class AdminViewPermissionInlineModelAdmin(AdminViewPermissionBaseModelAdmin,
                                          admin.options.InlineModelAdmin):
    def get_queryset(self, request):
        """
        Returns a QuerySet of all model instances that can be edited by the
        admin site. This is used by changelist_view.
        """
        if self.has_view_permission(request) and \
                not self.has_change_permission(request, None, True):
            return super(AdminViewPermissionInlineModelAdmin, self)\
                .get_queryset(request)
        else:
            # TODO: Somehow super executes admin.options.InlineModelAdmin
            # get_queryset and AdminViewPermissionBaseModelAdmin which is
            # convinient
            return super(AdminViewPermissionInlineModelAdmin, self)\
                .get_queryset(request)

    '''def has_parent_view_permission(self, request, obj=None):
        if getattr(self.parent_model, 'assigned_modeladmin', None):
            parent_modeladmin = self.parent_model.assigned_modeladmin
            return parent_modeladmin.has_view_permission(request, obj) \
                   and not parent_modeladmin.has_change_permission(request,
                                                                   obj, True)

        return False'''

class AdminViewPermissionModelAdmin(AdminViewPermissionBaseModelAdmin,
                                    admin.ModelAdmin):
    def __init__(self, model, admin_site):
        super(AdminViewPermissionModelAdmin, self).__init__(model, admin_site)
        # Contibute this class to the model
        setattr(self.model, 'assigned_modeladmin', self)

    def get_changelist(self, request, **kwargs):
        """
        Returns the ChangeList class for use on the changelist page.
        """
        return AdminViewPermissionChangeList

    def get_inline_instances(self, request, obj=None):
        inline_instances = []
        for inline_class in self.inlines:
            new_class = type(
                str('DynamicAdminViewPermissionInlineModelAdmin'),
                (inline_class, AdminViewPermissionInlineModelAdmin),
                dict(inline_class.__dict__))

            inline = new_class(self.model, self.admin_site)
            if request:
                if not (inline.has_view_permission(request, obj) or
                        inline.has_add_permission(request) or
                        inline.has_change_permission(request, obj, True) or
                        inline.has_delete_permission(request, obj)):
                    continue
                if inline.has_view_permission(request, obj) and \
                        not inline.has_change_permission(request, obj, True):
                    inline.can_delete = False
                if not inline.has_add_permission(request):
                    inline.max_num = 0
            inline_instances.append(inline)

        return inline_instances

    def change_view(self, request, object_id, form_url='', extra_context=None):
        """
        Override this function to hide the sumbit row from the user who has
        view only permission
        """
        model = self.model
        opts = model._meta

        if object_id:
            obj = None
        else:
            obj = self.get_object(request, unquote(object_id))

        if self.has_view_permission(request, obj) and \
                not self.has_change_permission(request, obj, True):
            extra_context = extra_context or {}
            extra_context['title'] = _('View %s') % force_text(
                opts.verbose_name)

            extra_context['show_save'] = False
            extra_context['show_save_and_continue'] = False

            inlines = self.get_inline_instances(request, obj)
            for inline in inlines:
                if inline.has_change_permission(request, obj, True):
                    extra_context['show_save'] = True
                    extra_context['show_save_and_continue'] = True
                    break

        return super(AdminViewPermissionModelAdmin, self).change_view(
            request, object_id, form_url, extra_context)

class AdminViewPermissionAdminSite(admin.AdminSite):
    def register(self, model_or_iterable, admin_class=None, **options):
        """
        Create a new ModelAdmin class which inherits from the original and
        the above and register all models with that
        """
        SETTINGS_MODELS = getattr(settings, 'ADMIN_VIEW_PERMISSION_MODELS',
                                  None)

        models = model_or_iterable
        if not isinstance(model_or_iterable, (tuple, list)):
            models = tuple([model_or_iterable])

        if SETTINGS_MODELS or (SETTINGS_MODELS is not None and len(
                SETTINGS_MODELS) == 0):
            for model in models:
                if django_version() == DjangoVersion.DJANGO_18:
                    model_name = '%s.%s' % (model._meta.app_label,
                                            model._meta.object_name)
                elif django_version() > DjangoVersion.DJANGO_18:
                    model_name = model._meta.label

                if model_name in SETTINGS_MODELS:
                    if admin_class:
                        admin_class = type(
                            str('DynamicAdminViewPermissionModelAdmin'),
                            (admin_class, AdminViewPermissionModelAdmin),
                            dict(admin_class.__dict__))
                    else:
                        admin_class = AdminViewPermissionModelAdmin

                super(AdminViewPermissionAdminSite, self).register([model],
                                                                   admin_class,
                                                                   **options)
        else:
            if admin_class:
                admin_class = type(str('DynamicAdminViewPermissionModelAdmin'),
                                   (
                                       admin_class,
                                       AdminViewPermissionModelAdmin),
                                   dict(admin_class.__dict__))
            else:
                admin_class = AdminViewPermissionModelAdmin

            super(AdminViewPermissionAdminSite, self).register(
                model_or_iterable,
                admin_class, **options)

    def _build_app_dict(self, request, label=None):
        """
        Builds the app dictionary. Takes an optional label parameters to filter
        models of a specific app.
        """
        app_dict = {}

        if label:
            models = {
                m: m_a for m, m_a in self._registry.items()
                if m._meta.app_label == label
            }
        else:
            models = self._registry

        for model, model_admin in models.items():
            app_label = model._meta.app_label

            has_module_perms = model_admin.has_module_permission(request)
            if not has_module_perms:
                if label:
                    raise PermissionDenied
                continue

            perms = model_admin.get_model_perms(request)

            # Check whether user has any perm for this module.
            # If so, add the module to the model_list.
            if True not in perms.values():
                continue

            info = (app_label, model._meta.model_name)
            model_dict = {
                'name': capfirst(model._meta.verbose_name_plural),
                'object_name': model._meta.object_name,
                'perms': perms,
            }
            if perms.get('change') or perms.get('view'):
                try:
                    model_dict['admin_url'] = reverse(
                        'admin:%s_%s_changelist' % info, current_app=self.name)
                except NoReverseMatch:
                    pass
            if perms.get('add'):
                try:
                    model_dict['add_url'] = reverse('admin:%s_%s_add' % info,
                                                    current_app=self.name)
                except NoReverseMatch:
                    pass

            if app_label in app_dict:
                app_dict[app_label]['models'].append(model_dict)
            else:
                app_dict[app_label] = {
                    'name': apps.get_app_config(app_label).verbose_name,
                    'app_label': app_label,
                    'app_url': reverse(
                        'admin:app_list',
                        kwargs={'app_label': app_label},
                        current_app=self.name,
                    ),
                    'has_module_perms': has_module_perms,
                    'models': [model_dict],
                }

        if label:
            return app_dict.get(label)

        return app_dict
<|endoftext|>


<commit_before># Copyright (C) Collabora Limited 2019
# Author: Guillaume Tucker <guillaume.tucker@collabora.com>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""Push data using kcidb-submit."""

import json
import os
import subprocess

import models
import utils
import utils.db
from utils.report.common import DEFAULT_STORAGE_URL as STORAGE_URL

# Mapping between kcidb revision keys and build documents
BUILD_REV_KEY_MAP = {
    'git_repository_url': models.GIT_URL_KEY,
    'git_repository_commit_hash': models.GIT_COMMIT_KEY,
    'git_repository_commit_name': models.GIT_DESCRIBE_V_KEY,
    'git_repository_branch': models.GIT_BRANCH_KEY,
}

def _make_id(raw_id, ns):
    return ':'.join([ns, str(raw_id)])

def _submit(data, bq_options):
    json_data = json.dumps(data, indent=2)
    if bq_options.get("debug"):
        utils.LOG.info("Submitting with kcidb:")
        utils.LOG.info(json_data)
    local_env = dict(os.environ)
    local_env["GOOGLE_APPLICATION_CREDENTIALS"] = bq_options["credentials"]
    kcidb_path = bq_options.get("kcidb_path", "")
    kcidb_submit = os.path.join(kcidb_path, "kcidb-submit")
    p = subprocess.Popen([kcidb_submit, "-d", bq_options["dataset"]],
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                         env=local_env)
    p.communicate(input=json_data)
    if p.returncode:
        utils.LOG.warn("Failed to push data to BigQuery")

def push_build(build_id, first, bq_options, db_options={}, db=None):
    if db is None:
        db = utils.db.get_db_connection(db_options)
    origin = bq_options.get("origin", "kernelci")
    ns = bq_options.get("namespace", "kernelci.org")
    build = utils.db.find_one2(db[models.BUILD_COLLECTION], build_id)
    build_id = _make_id(build[models.ID_KEY], ns)
    revision_id = _make_id(build[models.KERNEL_KEY], ns)

    bq_data = {
        'version': '1',
    }

    if first:
        bq_revision = {
            'origin': origin,
            'origin_id': revision_id,
        }
        bq_revision.update({
            bq_key: build[build_key]
            for bq_key, build_key in BUILD_REV_KEY_MAP.iteritems()
        })
        bq_data['revisions'] = [bq_revision]

    bq_build = {
        'revision_origin': origin,
        'revision_origin_id': revision_id,
        'origin': origin,
        'origin_id': build_id,
        'valid': build[models.STATUS_KEY] == 'PASS',
        'start_time': build[models.CREATED_KEY].isoformat(),
        'description': build[models.GIT_DESCRIBE_V_KEY],
        'duration': build[models.BUILD_TIME_KEY],
        'architecture': build[models.ARCHITECTURE_KEY],
        'compiler': build[models.COMPILER_VERSION_FULL_KEY],
        'log_url': '/'.join([
            STORAGE_URL,
            build[models.FILE_SERVER_RESOURCE_KEY],
            utils.BUILD_LOG_FILE
        ]),
        'misc': {
            'defconfig': build[models.DEFCONFIG_FULL_KEY],
        },
    }
    bq_data['builds'] = [bq_build]

    _submit(bq_data, bq_options)
<commit_msg>Add push_tests() to kcidb<commit_after># Copyright (C) Collabora Limited 2019
# Author: Guillaume Tucker <guillaume.tucker@collabora.com>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""Push data using kcidb-submit."""

import json
import os
import subprocess

import models
import utils
import utils.db
from utils.report.common import DEFAULT_STORAGE_URL as STORAGE_URL

# Mapping between kcidb revision keys and build documents
BUILD_REV_KEY_MAP = {
    'git_repository_url': models.GIT_URL_KEY,
    'git_repository_commit_hash': models.GIT_COMMIT_KEY,
    'git_repository_commit_name': models.GIT_DESCRIBE_V_KEY,
    'git_repository_branch': models.GIT_BRANCH_KEY,
}

def _make_id(raw_id, ns):
    return ':'.join([ns, str(raw_id)])

def _get_build_doc(group, db):
    keys = [
        models.JOB_KEY,
        models.KERNEL_KEY,
        models.GIT_BRANCH_KEY,
        models.ARCHITECTURE_KEY,
        models.DEFCONFIG_KEY,
        models.BUILD_ENVIRONMENT_KEY,
    ]
    spec = {k: group[k] for k in keys}

    return utils.db.find_one2(db[models.BUILD_COLLECTION], spec)

def _get_test_cases(group, db, hierarchy, ns):
    case_collection = db[models.TEST_CASE_COLLECTION]
    group_collection = db[models.TEST_GROUP_COLLECTION]

    hierarchy = hierarchy + [group[models.NAME_KEY]]
    tests = [
        {
            'id': _make_id(test[models.ID_KEY], ns),
            'path': '.'.join(hierarchy + [test[models.NAME_KEY]]),
            'status': test[models.STATUS_KEY],
            # ToDo: get start and duration times from LAVA log timestamps
            'start_time': test[models.CREATED_KEY].isoformat(),
        }
        for test in (
            utils.db.find_one2(case_collection, test_id)
            for test_id in group[models.TEST_CASES_KEY]
        )
    ]

    for sub_group_id in group[models.SUB_GROUPS_KEY]:
        sub_group = utils.db.find_one2(group_collection, sub_group_id)
        tests += _get_test_cases(sub_group, db, hierarchy, ns)

    return tests

def _submit(data, bq_options):
    json_data = json.dumps(data, indent=2)
    if bq_options.get("debug"):
        utils.LOG.info("Submitting with kcidb:")
        utils.LOG.info(json_data)
    local_env = dict(os.environ)
    local_env["GOOGLE_APPLICATION_CREDENTIALS"] = bq_options["credentials"]
    kcidb_path = bq_options.get("kcidb_path", "")
    kcidb_submit = os.path.join(kcidb_path, "kcidb-submit")
    p = subprocess.Popen([kcidb_submit, "-d", bq_options["dataset"]],
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                         env=local_env)
    p.communicate(input=json_data)
    if p.returncode:
        utils.LOG.warn("Failed to push data to BigQuery")

def push_build(build_id, first, bq_options, db_options={}, db=None):
    if db is None:
        db = utils.db.get_db_connection(db_options)
    origin = bq_options.get("origin", "kernelci")
    ns = bq_options.get("namespace", "kernelci.org")
    build = utils.db.find_one2(db[models.BUILD_COLLECTION], build_id)
    build_id = _make_id(build[models.ID_KEY], ns)
    revision_id = _make_id(build[models.KERNEL_KEY], ns)

    bq_data = {
        'version': '1',
    }

    if first:
        bq_revision = {
            'origin': origin,
            'origin_id': revision_id,
        }
        bq_revision.update({
            bq_key: build[build_key]
            for bq_key, build_key in BUILD_REV_KEY_MAP.iteritems()
        })
        bq_data['revisions'] = [bq_revision]

    bq_build = {
        'revision_origin': origin,
        'revision_origin_id': revision_id,
        'origin': origin,
        'origin_id': build_id,
        'valid': build[models.STATUS_KEY] == 'PASS',
        'start_time': build[models.CREATED_KEY].isoformat(),
        'description': build[models.GIT_DESCRIBE_V_KEY],
        'duration': build[models.BUILD_TIME_KEY],
        'architecture': build[models.ARCHITECTURE_KEY],
        'compiler': build[models.COMPILER_VERSION_FULL_KEY],
        'log_url': '/'.join([
            STORAGE_URL,
            build[models.FILE_SERVER_RESOURCE_KEY],
            utils.BUILD_LOG_FILE
        ]),
        'misc': {
            'defconfig': build[models.DEFCONFIG_FULL_KEY],
        },
    }
    bq_data['builds'] = [bq_build]

    _submit(bq_data, bq_options)

def push_tests(group_id, bq_options, db_options={}, db=None):
    if db is None:
        db = utils.db.get_db_connection(db_options)
    collection = db[models.TEST_GROUP_COLLECTION]
    group = utils.db.find_one2(collection, group_id)
    origin = bq_options.get("origin", "kernelci")
    ns = bq_options.get("namespace", "kernelci.org")
    test_cases = _get_test_cases(group, db, [], ns)
    build = _get_build_doc(group, db)
    build_id = _make_id(build[models.ID_KEY], ns)
    env_description = "{} in {}".format(
        group[models.DEVICE_TYPE_KEY],
        group[models.LAB_NAME_KEY]
    )
    test_description = "{} on {} in {}".format(
        group[models.NAME_KEY],
        group[models.DEVICE_TYPE_KEY],
        group[models.LAB_NAME_KEY]
    )
    misc = {
        'plan': group[models.NAME_KEY],
        'plan_variant': group[models.PLAN_VARIANT_KEY],
    }
    env_misc = {
        'device': group[models.DEVICE_TYPE_KEY],
        'lab': group[models.LAB_NAME_KEY],
        'mach': group[models.MACH_KEY],
        'rootfs_url': group[models.INITRD_KEY],
        'instance': group[models.BOARD_INSTANCE_KEY],
    }

    bq_data = {
        'version': '1',
        "tests": [
            {
                'build_origin': origin,
                'build_origin_id': build_id,
                'origin': origin,
                'origin_id': test['id'],
                'environment': {
                    'description': env_description,
                    'misc': env_misc,
                },
                'path': test['path'],
                'description': test_description,
                'status': test['status'],
                'start_time': test['start_time'],
                'misc': misc,
            }
            for test in test_cases
        ],
    }
    _submit(bq_data, bq_options)
<|endoftext|>


<commit_before>"""
Equations of state.
"""

import numpy as np

def eos_gamma_law(gamma):

    p_from_rho_eps = lambda rho, eps : (gamma - 1.0) * rho * eps
    h_from_rho_eps = lambda rho, eps : 1.0 + gamma * eps
    cs_from_rho_eps = lambda rho, eps : \
    np.sqrt(gamma * p_from_rho_eps(rho, eps) / (rho * h_from_rho_eps(rho, eps)))
    h_from_rho_p = lambda rho, p : 1.0 + gamma / (gamma - 1.0) * p / rho

    eos = {'p_from_rho_eps' : p_from_rho_eps,
           'h_from_rho_eps' : h_from_rho_eps,
           'cs_from_rho_eps' : cs_from_rho_eps,
           'h_from_rho_p' : h_from_rho_p}

    return eos

def eos_polytrope_law(gamma, gamma_th, rho_transition, k):

    def p_from_rho_eps(rho, eps):
        if (rho < rho_transition):
            p_cold = k[0] * rho**gamma[0]
            eps_cold = p_cold / rho / (gamma[0] - 1.)
        else:
            p_cold = k[1] * rho**gamma[1]
            eps_cold = p_cold / rho / (gamma[1] - 1.) - \
                k[1] * rho_transition**(gamma[1] - 1.) + \
                k[0] * rho_transition**(gamma[0] - 1.)

        p_th = max(0.0, (gamma_th - 1.0) * rho * (eps - eps_cold))

        return p_cold + p_th

    def h_from_rho_eps(rho, eps):
        if (rho < rho_transition):
            p_cold = k[0] * rho**gamma[0]
            eps_cold = p_cold / rho / (gamma[0] - 1.0)
        else:
            p_cold = k[1] * rho**gamma[1]
            eps_cold = p_cold / rho / (gamma[1] - 1.0) - \
                k[1] * rho_transition**(gamma[1] - 1.0) + \
                k[0] * rho_transition**(gamma[0] - 1.0)

        p_th = max(0., (gamma_th - 1.) * rho * (eps - eps_cold))

        return 1. + eps_cold + eps + (p_cold + p_th)/ rho

    def cs_from_rho_eps(rho, eps):
        return np.sqrt(gamma * p_from_rho_eps(rho, eps) / (rho * h_from_rho_eps(rho, eps)))

    def h_from_rho_p(rho, p):
        if (rho < rho_transition):
            p_cold = k[0] * rho**gamma[0]
            eps_cold = p_cold / rho / (gamma[0] - 1.0)
        else:
            p_cold = k[1] * rho**gamma[1]
            eps_cold = p_cold / rho / (gamma[1] - 1.0) - \
                k[1] * rho_transition**(gamma[1] - 1.0) + \
                k[0] * rho_transition**(gamma[0] - 1.0)

        p_th = max(0.0, p - p_cold)
        eps= 0.0 * p_th #FIXME

        return 1.0 + eps_cold + eps + p / rho

    eos = {'p_from_rho_eps' : p_from_rho_eps,
           'h_from_rho_eps' : h_from_rho_eps,
           'cs_from_rho_eps' : cs_from_rho_eps,
           'h_from_rho_p' : h_from_rho_p}

    return eos

<commit_msg>Add definition of reactive EOS.<commit_after>"""
Equations of state.
"""

import numpy as np

def eos_gamma_law(gamma):

    p_from_rho_eps = lambda rho, eps : (gamma - 1.0) * rho * eps
    h_from_rho_eps = lambda rho, eps : 1.0 + gamma * eps
    cs_from_rho_eps = lambda rho, eps : \
    np.sqrt(gamma * p_from_rho_eps(rho, eps) / (rho * h_from_rho_eps(rho, eps)))
    h_from_rho_p = lambda rho, p : 1.0 + gamma / (gamma - 1.0) * p / rho

    eos = {'p_from_rho_eps' : p_from_rho_eps,
           'h_from_rho_eps' : h_from_rho_eps,
           'cs_from_rho_eps' : cs_from_rho_eps,
           'h_from_rho_p' : h_from_rho_p}

    return eos

def eos_gamma_law_react(gamma, q):

    p_from_rho_eps = lambda rho, eps : (gamma - 1.0) * rho * (eps - q)
    h_from_rho_eps = lambda rho, eps : 1.0 + gamma * eps + (1.0 - gamma) * q
    cs_from_rho_eps = lambda rho, eps : \
    np.sqrt(gamma * (gamma - 1.0) * (eps - q) / \
    (1.0 + gamma * eps + (1.0 - gamma) * q))
    h_from_rho_p = lambda rho, p : 1.0 + gamma / (gamma - 1.0) * p / rho + q

    eos = {'p_from_rho_eps' : p_from_rho_eps,
           'h_from_rho_eps' : h_from_rho_eps,
           'cs_from_rho_eps' : cs_from_rho_eps,
           'h_from_rho_p' : h_from_rho_p}

    return eos

def eos_polytrope_law(gamma, gamma_th, rho_transition, k):

    def p_from_rho_eps(rho, eps):
        if (rho < rho_transition):
            p_cold = k[0] * rho**gamma[0]
            eps_cold = p_cold / rho / (gamma[0] - 1.)
        else:
            p_cold = k[1] * rho**gamma[1]
            eps_cold = p_cold / rho / (gamma[1] - 1.) - \
                k[1] * rho_transition**(gamma[1] - 1.) + \
                k[0] * rho_transition**(gamma[0] - 1.)

        p_th = max(0.0, (gamma_th - 1.0) * rho * (eps - eps_cold))

        return p_cold + p_th

    def h_from_rho_eps(rho, eps):
        if (rho < rho_transition):
            p_cold = k[0] * rho**gamma[0]
            eps_cold = p_cold / rho / (gamma[0] - 1.0)
        else:
            p_cold = k[1] * rho**gamma[1]
            eps_cold = p_cold / rho / (gamma[1] - 1.0) - \
                k[1] * rho_transition**(gamma[1] - 1.0) + \
                k[0] * rho_transition**(gamma[0] - 1.0)

        p_th = max(0., (gamma_th - 1.) * rho * (eps - eps_cold))

        return 1. + eps_cold + eps + (p_cold + p_th)/ rho

    def cs_from_rho_eps(rho, eps):
        return np.sqrt(gamma * p_from_rho_eps(rho, eps) / (rho * h_from_rho_eps(rho, eps)))

    def h_from_rho_p(rho, p):
        if (rho < rho_transition):
            p_cold = k[0] * rho**gamma[0]
            eps_cold = p_cold / rho / (gamma[0] - 1.0)
        else:
            p_cold = k[1] * rho**gamma[1]
            eps_cold = p_cold / rho / (gamma[1] - 1.0) - \
                k[1] * rho_transition**(gamma[1] - 1.0) + \
                k[0] * rho_transition**(gamma[0] - 1.0)

        p_th = max(0.0, p - p_cold)
        eps= 0.0 * p_th #FIXME

        return 1.0 + eps_cold + eps + p / rho

    eos = {'p_from_rho_eps' : p_from_rho_eps,
           'h_from_rho_eps' : h_from_rho_eps,
           'cs_from_rho_eps' : cs_from_rho_eps,
           'h_from_rho_p' : h_from_rho_p}

    return eos

<|endoftext|>


<commit_before>#!/usr/bin/env python3

import operator
import re

operations = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.floordiv,
    '^': operator.pow,
}
order_of_operations = [
    ['^'],
    ['*', '/'],
    ['+', '-'],
]

class EquationError (Exception):
    pass

def parse_number(num):
    '''
    Converts a string to an int if possible,
    otherwise float if possible,
    otherwise returns the original string
    '''
    try:
        return int(num)
    except ValueError:
        try:
            return float(num)
        except ValueError:
            return num

def tokenize(equation):
    '''
    Tokenizes an infix equation to create a list
    '''
    # things to split by
    text = r'[a-zA-Z]+'
    num = r'(?<!\d)-?\d*\.?\d+'
    parens = r'[()]'
    #
    stack = re.split('({}|{}|{})'.format(text, num, parens), equation)
    stack = filter(None, stack)
    stack = map(parse_number, stack)
    return list(stack)

def infix2postfix(
        equation,
        operations=operations,
        order_of_operations=order_of_operations):
    '''
    Converts a tokenized infix equation to postfix
    '''
    equation = list(equation)
    stack = []
    output = []

    for item in equation:
        if isinstance(item, int):
            output.append(item)
        elif item == '(':
            stack.append(item)
        elif item == ')':
            if '(' not in stack:
                raise EquationError('Invalid equation: {}'.format(equation))
            while stack[-1] != '(':
                output.append(stack.pop())
            stack.pop()
        elif item in operations:
            higher_or_equal_priority = []
            ops = iter(order_of_operations)
            line = next(ops)
            try:
                while item not in line:
                    higher_or_equal_priority.extend(line)
                    line = next(ops)
            except StopIteration:
                raise SyntaxError('Operator and Order of Operations mismatch')

            while stack and stack[-1] in higher_or_equal_priority:
                output.append(stack.pop())
            stack.append(item)
        else:
            raise EquationError('Invalid character found: {} in {}'.format(
                item, equation))

    if '(' in stack:
        raise EquationError('Invalid equation: {}'.format(equation))

    while stack:
        output.append(stack.pop())

    return output

def solve_postfix(
        equation,
        operations=operations,
        order_of_operations=order_of_operations):
    '''
    Solves a tokenized postfix equation
    '''
    equation = list(equation)
    stack = []

    for item in equation:
        if isinstance(item, int):
            stack.append(item)
        elif item in operations:
            if len(stack) < 2:
                raise EquationError('Not enough operands for {} in {}'.format(
                    item, equation))
            else:
                b = stack.pop()
                a = stack.pop()
                stack.append(operations[item](a, b))
        else:
            raise EquationError('Invalid operand/operator: {} in '.format(
                item, equation))

    if len(stack) != 1:
        raise EquationError('Invalid equation: {}'.format(equation))

    return stack[0]

def solve(
        equation,
        operations=operations,
        order_of_operations=order_of_operations):
    '''
    Runs equation2list, infix2postfix, and solve_postfix in order
    '''
    equation = tokenize(equation)
    postfix = infix2postfix(equation, operations, order_of_operations)
    value = solve_postfix(postfix, operations, order_of_operations)
    return value

if __name__ == '__main__':
    print(solve(input()))
<commit_msg>Added whitespace filtering to equations<commit_after>#!/usr/bin/env python3

import operator
import re

operations = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.floordiv,
    '^': operator.pow,
}
order_of_operations = [
    ['^'],
    ['*', '/'],
    ['+', '-'],
]

class EquationError (Exception):
    pass

def parse_number(num):
    '''
    Converts a string to an int if possible,
    otherwise float if possible,
    otherwise returns the original string
    '''
    try:
        return int(num)
    except ValueError:
        try:
            return float(num)
        except ValueError:
            return num

def tokenize(equation):
    '''
    Tokenizes an infix equation to create a list
    '''
    # things to split by
    text = r'[a-zA-Z]+'
    num = r'(?<!\d)-?\d*\.?\d+'
    parens = r'[()]'
    #
    stack = re.split('({}|{}|{})'.format(text, num, parens), equation)
    stack = filter(None, stack)
    stack = map(parse_number, stack)
    return list(stack)

def infix2postfix(
        equation,
        operations=operations,
        order_of_operations=order_of_operations):
    '''
    Converts a tokenized infix equation to postfix
    '''
    equation = list(equation)
    stack = []
    output = []

    for item in equation:
        if isinstance(item, int):
            output.append(item)
        elif item == '(':
            stack.append(item)
        elif item == ')':
            if '(' not in stack:
                raise EquationError('Invalid equation: {}'.format(equation))
            while stack[-1] != '(':
                output.append(stack.pop())
            stack.pop()
        elif item in operations:
            higher_or_equal_priority = []
            ops = iter(order_of_operations)
            line = next(ops)
            try:
                while item not in line:
                    higher_or_equal_priority.extend(line)
                    line = next(ops)
            except StopIteration:
                raise SyntaxError('Operator and Order of Operations mismatch')

            while stack and stack[-1] in higher_or_equal_priority:
                output.append(stack.pop())
            stack.append(item)
        else:
            raise EquationError('Invalid character found: {} in {}'.format(
                item, equation))

    if '(' in stack:
        raise EquationError('Invalid equation: {}'.format(equation))

    while stack:
        output.append(stack.pop())

    return output

def solve_postfix(
        equation,
        operations=operations,
        order_of_operations=order_of_operations):
    '''
    Solves a tokenized postfix equation
    '''
    equation = list(equation)
    stack = []

    for item in equation:
        if isinstance(item, int):
            stack.append(item)
        elif item in operations:
            if len(stack) < 2:
                raise EquationError('Not enough operands for {} in {}'.format(
                    item, equation))
            else:
                b = stack.pop()
                a = stack.pop()
                stack.append(operations[item](a, b))
        else:
            raise EquationError('Invalid operand/operator: {} in '.format(
                item, equation))

    if len(stack) != 1:
        raise EquationError('Invalid equation: {}'.format(equation))

    return stack[0]

def solve(
        equation,
        operations=operations,
        order_of_operations=order_of_operations):
    '''
    Runs equation2list, infix2postfix, and solve_postfix in order
    '''
    equation = re.sub('\s', '', equation) # remove whitespace
    equation = tokenize(equation)
    postfix = infix2postfix(equation, operations, order_of_operations)
    value = solve_postfix(postfix, operations, order_of_operations)
    return value

if __name__ == '__main__':
    print(solve(input()))
<|endoftext|>


<commit_before>#!/usr/bin/env python

from PyQt4.QtGui import *
from PyQt4.QtCore import *

from structdata import g_project

from areaeditor import AreaEditor
from roommanager import RoomManager

class ResizeButton(QPushButton):

    def sizeHint(self):
        return QSize(10, 10)
    def __init__(self, parent=None):
        super(ResizeButton, self).__init__(parent)
        self.setStyleSheet("background-color:"
                                           "rgba( 255, 255, 255, 100% );")

class AreaResize(QWidget):

    def __init__(self, area, bg_width, bg_height, parent=None):
        super(AreaResize, self).__init__(parent)
        self.in_resize = False
        self.moving_area = False
        self.area_start = None
        self.area_cur = None
        self.mouse_on_area_resize = False
        self.bg_width = bg_width
        self.bg_height = bg_height
        self.area = area
        self.resize(QSize(float(self.area.width),
                          float(self.area.height)))
        self.vl = QVBoxLayout()
        self.vl.setContentsMargins(0, 0, 0, 0)
        self.area_editor = None
        self.signal_mapper_pressed = QSignalMapper(self)
        self.resize_buttons = []
        horizontal = QHBoxLayout()
        horizontal.setContentsMargins(0, 0, 0, 0)
        for i in range(8):
            button = ResizeButton(self)
            button.setVisible(False)
            if i == 0 or i == 7:
                button.setCursor(Qt.SizeFDiagCursor)
            elif i == 5 or i == 2:
                button.setCursor(Qt.SizeBDiagCursor)
            elif i == 1 or i == 6:
                button.setCursor(Qt.SizeVerCursor)
            else:
                button.setCursor(Qt.SizeHorCursor)
            horizontal.addWidget(button)
            if i not in [2, 4, 7]:
                horizontal.addStretch()
            else:
                self.vl.addLayout(horizontal)
                if i != 7:
                    self.vl.addStretch()
                    horizontal = QHBoxLayout()
                    horizontal.setContentsMargins(0, 0, 0, 0)
            self.connect(button, SIGNAL("pressed()"),
                         self.signal_mapper_pressed, SLOT("map()"))
            self.signal_mapper_pressed.setMapping(button, i)
            self.resize_buttons.append(button)
        self.setLayout(self.vl)
        self.connect(self.signal_mapper_pressed, SIGNAL("mapped(int)"),
                     self.startTrack)

    def mouseMoveEvent(self, event=None):
        if (event.buttons() and Qt.LeftButton) == Qt.LeftButton and self.in_resize:
            self.resizeAreaResize(event.x(), event.y())
        if (event.buttons() and Qt.LeftButton) == Qt.LeftButton and self.moving_area:
            self.area_cur = event.pos()
            self.changeAreaPosition()

    def resizeAreaResize(self, x, y):
        """
        funzione per il ridimensionamento dell'AreaResize. I paramtri passati
        sono le coordinate su cui viene fatto il ridimensionamento
        """
        #uso per non superare i bordi laterali dello sfondo
        x = min(x, self.bg_width - self.x()) if x + self.x() > 0\
                                             else max(0, x)
#            #uso per non superare i bordi superiore e inferiore dello sfondo
        y = min(y, self.bg_height - self.y()) if y + self.y() > 0\
                                              else max(0, y)
        x_widget = self.x()
        y_widget = self.y()
        #resize with top left button
        if self.index == 0:
            self.move(x_widget + x, y_widget + y)
            self.resize(QSize(self.width() - x, self.height() - y))
        #resize with top button
        elif self.index == 1:
            self.move(x_widget, y_widget + y)
            self.resize(QSize(self.width(), self.height() - y))
        #resize with top right button
        elif self.index == 2:
            self.move(self.x(), y_widget + y)
            self.resize(QSize(x, self.height() - y))
        #resize with left button
        elif self.index == 3:
            self.move(x_widget + x, y_widget)
            self.resize(QSize(self.width() - x, self.height()))
        #resize with right button
        elif self.index == 4:
            self.resize(QSize(x, self.height()))
        #resize with bottom left button
        elif self.index == 5:
            self.move(x_widget + x, self.y())
            self.resize(QSize(self.width() - x, y))
        #resize with bottom button
        elif self.index == 6:
            self.resize(QSize(self.width(), y))
        #resize with bottom right button
        elif self.index == 7:
            self.resize(QSize(x + 5, y + 5))
        self.update()

    def mouseReleaseEvent(self, event=None):
        if self.in_resize or (self.moving_area and self.area_cur is not None):
            self.updateArea()
        else:
            self.area_start = None

    def mousePressEvent(self, event=None):
        self.moving_area = True
        self.area_start = event.pos()

    def changeAreaPosition(self):
        """
        funzione per il calcolo della nuova posizione dell'area nel momento
        in cui viene cambiata la posizione dell'area
        """
        x_cur = self.area_cur.x()
        y_cur = self.area_cur.y()
        x_start = self.area_start.x()
        y_start = self.area_start.y()
        diff_x = x_cur - x_start
        diff_y = y_cur - y_start
        x_widget = self.x() + diff_x
        y_widget = self.y() + diff_y

        #controllo per non superare orizzontalmente i limiti dell'immagine
        if x_widget < 0:
            x_widget = 0
        elif x_widget + self.width() > self.bg_width:
            x_widget = x_widget - (x_widget + self.width() - self.bg_width)
        #controllo per non superare verticalmente i limiti dell'immagine
        if y_widget < 0:
            y_widget = 0
        elif y_widget + self.height() > self.bg_height:
            y_widget = y_widget - (y_widget + self.height() - self.bg_height)
        self.move(x_widget, y_widget)
        self.update()

    def updateArea(self):
        """
        funzione per il ridimensionamento e lo spostamento di un'area
        """
        if self.in_resize or self.moving_area:
            self.in_resize = False
            self.moving_area = False
            self.area_cur = None
            self.area_start = None
            self.area.x = str(self.x())
            self.area.y = str(self.y())
            self.area.width = str(self.width())
            self.area.height = str(self.height())
            g_project.notify()
            self.update()

    def mouseDoubleClickEvent(self, event=None):
        self.showAreaEditor()

    def showAreaEditor(self):
        self.area_editor = AreaEditor(self.area, self.parent())
        self.area_editor.exec_()

    def keyPressEvent(self, event=None):
        """
        gestione dell'evento di pressione di un tasto. Se il mouse e' sopra
        l'oggetto e viene premuto il tasto Del l'area associata all'oggetto
        viene cancellata
        """
        if event.key() == Qt.Key_Delete and self.mouse_on_area_resize:
            self.cancelArea()

    def cancelArea(self):
        """
        funzione per la cancellazione dell'area associata all'oggetto
        la funzione si occupa anche di notificare l'avvenuto cambiamento
        del modello dei dati
        """
        room = self.searchRoomForArea()
        if room:
            room.remove(self.area)
            self.area = None
            g_project.notify()

    def searchRoomForArea(self):
        """
        funzione che cerca la room a cui appartiene l'area associata
        all'oggetto. Se non la trova torna None
        """
        for key, room in g_project.data['rooms'].items():
            if self.area in room.areas:
                return room
        return None

    def enterEvent(self, event=None):
        for cb in self.resize_buttons:
            cb.setVisible(True)
        self.mouse_on_area_resize = True
        self.setFocus()
        self.update()

    def leaveEvent(self, event=None):
        for cb in self.resize_buttons:
            cb.setVisible(False)
        self.mouse_on_area_resize = False
        self.clearFocus()
        self.update()

    def startTrack(self, index):
        self.in_resize = True
        self.index = index

    def drawActionIcon(self, p):
        """
        funzione che disegna le icone delle azioni definite nell'evento
        associato all'area che si sta rappresentando
        la funzione ha come parametro di ingresso un QPainter
        """
        action_to_draw = set()
        for action in g_project.data['events'][self.area.event].actions:
            action_to_draw.add(action.id)
        i = 0
        for action_id in action_to_draw:
            icon_path = "%s.png" % action_id
            icon = QPixmap(icon_path).scaled(20, 20, Qt.KeepAspectRatio,
                                             Qt.SmoothTransformation)
            p.drawPixmap(QPoint(self.width() - 25, i * 30 + 2), icon)
            i += 1

    def drawRequirementIcon(self, p):
        """
        funzione che disegna un icona se per attivare l'evento associato
        all'azione che si sta rappresentando sono necessari uno o piu'
        requirement
        la funzione ha come parametro di ingresso un QPainter
        """
        if len(g_project.data['events'][self.area.event].requirements):
            icon_path = "requirement.png"
            icon = QPixmap(icon_path).scaled(20, 20, Qt.KeepAspectRatio,
                                             Qt.SmoothTransformation)
            p.drawPixmap(QPoint(5, 0), icon)

    def paintEvent(self, event=None):
        QWidget.paintEvent(self, event)
        p = QPainter(self)

        # XXX: senza questo resta il trail dell'area mentre viene
        # ridimensionata: investigare
        p.setRenderHint(QPainter.Antialiasing)

        p.setPen(Qt.blue)
        p.drawRect(0, 0, self.width(), self.height())
        self.drawActionIcon(p)
        self.drawRequirementIcon(p)
<commit_msg>change cancelArea method, now before delete area from room search the area index and then pop the area from Room.areas list<commit_after>#!/usr/bin/env python

from PyQt4.QtGui import *
from PyQt4.QtCore import *

from structdata import g_project

from areaeditor import AreaEditor
from roommanager import RoomManager

class ResizeButton(QPushButton):

    def sizeHint(self):
        return QSize(10, 10)
    def __init__(self, parent=None):
        super(ResizeButton, self).__init__(parent)
        self.setStyleSheet("background-color:"
                                           "rgba( 255, 255, 255, 100% );")

class AreaResize(QWidget):

    def __init__(self, area, bg_width, bg_height, parent=None):
        super(AreaResize, self).__init__(parent)
        self.in_resize = False
        self.moving_area = False
        self.area_start = None
        self.area_cur = None
        self.show_resize_buttons = False
        self.mouse_on_area_resize = False
        self.bg_width = bg_width
        self.bg_height = bg_height
        self.area = area
        self.resize(QSize(float(self.area.width),
                          float(self.area.height)))
        self.vl = QVBoxLayout()
        self.vl.setContentsMargins(0, 0, 0, 0)
        self.area_editor = None
        self.signal_mapper_pressed = QSignalMapper(self)
        self.resize_buttons = []
        horizontal = QHBoxLayout()
        horizontal.setContentsMargins(0, 0, 0, 0)
        for i in range(8):
            button = ResizeButton(self)
            button.setVisible(False)
            if i == 0 or i == 7:
                button.setCursor(Qt.SizeFDiagCursor)
            elif i == 5 or i == 2:
                button.setCursor(Qt.SizeBDiagCursor)
            elif i == 1 or i == 6:
                button.setCursor(Qt.SizeVerCursor)
            else:
                button.setCursor(Qt.SizeHorCursor)
            horizontal.addWidget(button)
            if i not in [2, 4, 7]:
                horizontal.addStretch()
            else:
                self.vl.addLayout(horizontal)
                if i != 7:
                    self.vl.addStretch()
                    horizontal = QHBoxLayout()
                    horizontal.setContentsMargins(0, 0, 0, 0)
            self.connect(button, SIGNAL("pressed()"),
                         self.signal_mapper_pressed, SLOT("map()"))
            self.signal_mapper_pressed.setMapping(button, i)
            self.resize_buttons.append(button)
        self.setLayout(self.vl)
        self.connect(self.signal_mapper_pressed, SIGNAL("mapped(int)"),
                     self.startTrack)

    def mouseMoveEvent(self, event=None):
        if (event.buttons() and Qt.LeftButton) == Qt.LeftButton and self.in_resize:
            self.resizeAreaResize(event.x(), event.y())
        if (event.buttons() and Qt.LeftButton) == Qt.LeftButton and self.moving_area:
            self.area_cur = event.pos()
            self.changeAreaPosition()

    def resizeAreaResize(self, x, y):
        """
        funzione per il ridimensionamento dell'AreaResize. I paramtri passati
        sono le coordinate su cui viene fatto il ridimensionamento
        """
        #uso per non superare i bordi laterali dello sfondo
        x = min(x, self.bg_width - self.x()) if x + self.x() > 0\
                                             else max(0, x)
#            #uso per non superare i bordi superiore e inferiore dello sfondo
        y = min(y, self.bg_height - self.y()) if y + self.y() > 0\
                                              else max(0, y)
        x_widget = self.x()
        y_widget = self.y()
        #resize with top left button
        if self.index == 0:
            self.move(x_widget + x, y_widget + y)
            self.resize(QSize(self.width() - x, self.height() - y))
        #resize with top button
        elif self.index == 1:
            self.move(x_widget, y_widget + y)
            self.resize(QSize(self.width(), self.height() - y))
        #resize with top right button
        elif self.index == 2:
            self.move(self.x(), y_widget + y)
            self.resize(QSize(x, self.height() - y))
        #resize with left button
        elif self.index == 3:
            self.move(x_widget + x, y_widget)
            self.resize(QSize(self.width() - x, self.height()))
        #resize with right button
        elif self.index == 4:
            self.resize(QSize(x, self.height()))
        #resize with bottom left button
        elif self.index == 5:
            self.move(x_widget + x, self.y())
            self.resize(QSize(self.width() - x, y))
        #resize with bottom button
        elif self.index == 6:
            self.resize(QSize(self.width(), y))
        #resize with bottom right button
        elif self.index == 7:
            self.resize(QSize(x + 5, y + 5))
        self.update()

    def mouseReleaseEvent(self, event=None):
        if self.in_resize or (self.moving_area and self.area_cur is not None):
            self.updateArea()
        else:
            self.area_start = None

    def mousePressEvent(self, event=None):
        self.moving_area = True
        self.area_start = event.pos()

    def changeAreaPosition(self):
        """
        funzione per il calcolo della nuova posizione dell'area nel momento
        in cui viene cambiata la posizione dell'area
        """
        x_cur = self.area_cur.x()
        y_cur = self.area_cur.y()
        x_start = self.area_start.x()
        y_start = self.area_start.y()
        diff_x = x_cur - x_start
        diff_y = y_cur - y_start
        x_widget = self.x() + diff_x
        y_widget = self.y() + diff_y

        #controllo per non superare orizzontalmente i limiti dell'immagine
        if x_widget < 0:
            x_widget = 0
        elif x_widget + self.width() > self.bg_width:
            x_widget = x_widget - (x_widget + self.width() - self.bg_width)
        #controllo per non superare verticalmente i limiti dell'immagine
        if y_widget < 0:
            y_widget = 0
        elif y_widget + self.height() > self.bg_height:
            y_widget = y_widget - (y_widget + self.height() - self.bg_height)
        self.move(x_widget, y_widget)
        self.update()

    def updateArea(self):
        """
        funzione per il ridimensionamento e lo spostamento di un'area
        """
        if self.in_resize or self.moving_area:
            self.in_resize = False
            self.moving_area = False
            self.area_cur = None
            self.area_start = None
            self.area.x = str(self.x())
            self.area.y = str(self.y())
            self.area.width = str(self.width())
            self.area.height = str(self.height())
            g_project.notify()
            self.update()

    def mouseDoubleClickEvent(self, event=None):
        self.showAreaEditor()

    def showAreaEditor(self):
        self.area_editor = AreaEditor(self.area, self.parent())
        self.area_editor.exec_()

    def keyPressEvent(self, event=None):
        """
        gestione dell'evento di pressione di un tasto. Se il mouse e' sopra
        l'oggetto e viene premuto il tasto Del l'area associata all'oggetto
        viene cancellata
        """
        if event.key() == Qt.Key_Delete and self.mouse_on_area_resize:
            self.cancelArea()

    def cancelArea(self):
        """
        funzione per la cancellazione dell'area associata all'oggetto
        la funzione si occupa anche di notificare l'avvenuto cambiamento
        del modello dei dati
        """
        room = self.searchRoomForArea()
        if room:
            index = room.areas.index(self.area)
            room.areas.pop(index)
            self.area = None
            g_project.notify()

    def searchRoomForArea(self):
        """
        funzione che cerca la room a cui appartiene l'area associata
        all'oggetto. Se non la trova torna None
        """
        for key, room in g_project.data['rooms'].items():
            if self.area in room.areas:
                return room
        return None

    def enterEvent(self, event=None):
        for cb in self.resize_buttons:
            cb.setVisible(True)
        self.mouse_on_area_resize = True
        self.setFocus()
        self.update()

    def leaveEvent(self, event=None):
        for cb in self.resize_buttons:
            cb.setVisible(False)
        self.mouse_on_area_resize = False
        self.clearFocus()
        self.update()

    def startTrack(self, index):
        self.in_resize = True
        self.index = index

    def drawActionIcon(self, p):
        """
        funzione che disegna le icone delle azioni definite nell'evento
        associato all'area che si sta rappresentando
        la funzione ha come parametro di ingresso un QPainter
        """
        action_to_draw = set()
        for action in g_project.data['events'][self.area.event].actions:
            action_to_draw.add(action.id)
        i = 0
        for action_id in action_to_draw:
            icon_path = "%s.png" % action_id
            icon = QPixmap(icon_path).scaled(20, 20, Qt.KeepAspectRatio,
                                             Qt.SmoothTransformation)
            p.drawPixmap(QPoint(self.width() - 25, i * 30 + 2), icon)
            i += 1

    def drawRequirementIcon(self, p):
        """
        funzione che disegna un icona se per attivare l'evento associato
        all'azione che si sta rappresentando sono necessari uno o piu'
        requirement
        la funzione ha come parametro di ingresso un QPainter
        """
        if len(g_project.data['events'][self.area.event].requirements):
            icon_path = "requirement.png"
            icon = QPixmap(icon_path).scaled(20, 20, Qt.KeepAspectRatio,
                                             Qt.SmoothTransformation)
            p.drawPixmap(QPoint(5, 0), icon)

    def paintEvent(self, event=None):
        QWidget.paintEvent(self, event)
        p = QPainter(self)

        # XXX: senza questo resta il trail dell'area mentre viene
        # ridimensionata: investigare
        p.setRenderHint(QPainter.Antialiasing)

        p.setPen(Qt.blue)
        p.drawRect(0, 0, self.width(), self.height())
        self.drawActionIcon(p)
        self.drawRequirementIcon(p)

<|endoftext|>


<commit_before>#!/usr/bin/env python

# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
tf.logging.set_verbosity(tf.logging.INFO)

HEIGHT=28
WIDTH=28
NCLASSES=10

def linear_model(img, mode, hparams):
  X = tf.reshape(img,[-1,HEIGHT*WIDTH]) #flatten
  ylogits = tf.layers.dense(X,NCLASSES,activation=None)
  return ylogits, NCLASSES

def dnn_model(img, mode, hparams):
  #TODO: Implement DNN model with three hiddenlayers
  pass

def dnn_dropout_model(img, mode, hparams):
  #TODO: Implement DNN model and apply dropout to the last hidden layer
  pass

def cnn_model(img, mode, hparams):
  ksize1 = hparams.get('ksize1', 5)
  ksize2 = hparams.get('ksize2', 5)
  nfil1 = hparams.get('nfil1', 10)
  nfil2 = hparams.get('nfil2', 20)
  dprob = hparams.get('dprob', 0.25)

  c1 = tf.layers.conv2d(img, filters=nfil1,
                          kernel_size=ksize1, strides=1, # ?x28x28x10
                          padding='same', activation=tf.nn.relu)
  p1 = tf.layers.max_pooling2d(c1,pool_size=2, strides=2) # ?x14x14x10
  c2 = None #TODO: apply a second convolution to the output of p1
  p2 = None #TODO: apply a pooling layer with pool_size=2 and strides=2

  outlen = p2.shape[1]*p2.shape[2]*p2.shape[3] #980
  p2flat = tf.reshape(p2, [-1, outlen]) # flattened

  h3 = tf.layers.dense(p2flat, 300, activation=tf.nn.relu)
  h3d = tf.layers.dropout(
      h3, rate=dprob, training=(mode == tf.estimator.ModeKeys.TRAIN))

  ylogits = tf.layers.dense(h3d, NCLASSES, activation=None)
  return ylogits, NCLASSES

def serving_input_fn():
    #input will be rank 3
    feature_placeholders = {
        'image': tf.placeholder(tf.float32, [None, HEIGHT, WIDTH])}
    #but model function requires rank 4
    features = {
        'image': tf.expand_dims(feature_placeholders['image'],-1)}
    return tf.estimator.export.ServingInputReceiver(features, feature_placeholders)

def image_classifier(features, labels, mode, params):
  model_functions = {
      'linear':linear_model,
      'dnn':dnn_model,
      'dnn_dropout':dnn_dropout_model,
      'cnn':cnn_model}
  model_function = model_functions[params['model']]
  ylogits, nclasses = model_function(features['image'], mode, params)

  probabilities = tf.nn.softmax(ylogits)
  classes = tf.cast(tf.argmax(probabilities, 1), tf.uint8)
  if mode == tf.estimator.ModeKeys.TRAIN or mode == tf.estimator.ModeKeys.EVAL:
    loss = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits_v2(
            logits=ylogits, labels=labels))
    evalmetrics = {'accuracy': tf.metrics.accuracy(classes, tf.argmax(labels, 1))}
    if mode == tf.estimator.ModeKeys.TRAIN:
      # this is needed for batch normalization, but has no effect otherwise
      update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
      with tf.control_dependencies(update_ops):
         train_op = tf.contrib.layers.optimize_loss(
             loss,
             tf.train.get_global_step(),
             learning_rate=params['learning_rate'],
             optimizer="Adam")
    else:
      train_op = None
  else:
    loss = None
    train_op = None
    evalmetrics = None

  return tf.estimator.EstimatorSpec(
        mode=mode,
        predictions={"probabilities": probabilities, "classes": classes},
        loss=loss,
        train_op=train_op,
        eval_metric_ops=evalmetrics,
        export_outputs={'classes':tf.estimator.export.PredictOutput(
            {"probabilities": probabilities, "classes": classes})}
    )

def train_and_evaluate(output_dir, hparams):
  EVAL_INTERVAL = 60

  mnist = input_data.read_data_sets('mnist/data', one_hot=True, reshape=False)

  train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={'image':mnist.train.images},
    y=mnist.train.labels,
    batch_size=100,
    num_epochs=None,
    shuffle=True,
    queue_capacity=5000
  )

  eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={'image':mnist.test.images},
    y=mnist.test.labels,
    batch_size=100,
    num_epochs=1,
    shuffle=False,
    queue_capacity=5000
  )
  estimator = tf.estimator.Estimator(model_fn = image_classifier,
                                     params = hparams,
                                     config=tf.estimator.RunConfig(
                                         save_checkpoints_secs = EVAL_INTERVAL),
                                     model_dir = output_dir)
  train_spec = tf.estimator.TrainSpec(input_fn = train_input_fn,
                                    max_steps = hparams['train_steps'])
  exporter = tf.estimator.LatestExporter('exporter', serving_input_fn)
  eval_spec = tf.estimator.EvalSpec(input_fn = eval_input_fn,
                                  steps = None,
                                  exporters = exporter,
                                  throttle_secs = EVAL_INTERVAL)
  tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)<commit_msg>added summary file writer cache clear<commit_after>#!/usr/bin/env python

# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
tf.logging.set_verbosity(tf.logging.INFO)

HEIGHT=28
WIDTH=28
NCLASSES=10

def linear_model(img, mode, hparams):
  X = tf.reshape(img,[-1,HEIGHT*WIDTH]) #flatten
  ylogits = tf.layers.dense(X,NCLASSES,activation=None)
  return ylogits, NCLASSES

def dnn_model(img, mode, hparams):
  #TODO: Implement DNN model with three hiddenlayers
  pass

def dnn_dropout_model(img, mode, hparams):
  #TODO: Implement DNN model and apply dropout to the last hidden layer
  pass

def cnn_model(img, mode, hparams):
  ksize1 = hparams.get('ksize1', 5)
  ksize2 = hparams.get('ksize2', 5)
  nfil1 = hparams.get('nfil1', 10)
  nfil2 = hparams.get('nfil2', 20)
  dprob = hparams.get('dprob', 0.25)

  c1 = tf.layers.conv2d(img, filters=nfil1,
                          kernel_size=ksize1, strides=1, # ?x28x28x10
                          padding='same', activation=tf.nn.relu)
  p1 = tf.layers.max_pooling2d(c1,pool_size=2, strides=2) # ?x14x14x10
  c2 = None #TODO: apply a second convolution to the output of p1
  p2 = None #TODO: apply a pooling layer with pool_size=2 and strides=2

  outlen = p2.shape[1]*p2.shape[2]*p2.shape[3] #980
  p2flat = tf.reshape(p2, [-1, outlen]) # flattened

  h3 = tf.layers.dense(p2flat, 300, activation=tf.nn.relu)
  h3d = tf.layers.dropout(
      h3, rate=dprob, training=(mode == tf.estimator.ModeKeys.TRAIN))

  ylogits = tf.layers.dense(h3d, NCLASSES, activation=None)
  return ylogits, NCLASSES

def serving_input_fn():
    #input will be rank 3
    feature_placeholders = {
        'image': tf.placeholder(tf.float32, [None, HEIGHT, WIDTH])}
    #but model function requires rank 4
    features = {
        'image': tf.expand_dims(feature_placeholders['image'],-1)}
    return tf.estimator.export.ServingInputReceiver(features, feature_placeholders)

def image_classifier(features, labels, mode, params):
  model_functions = {
      'linear':linear_model,
      'dnn':dnn_model,
      'dnn_dropout':dnn_dropout_model,
      'cnn':cnn_model}
  model_function = model_functions[params['model']]
  ylogits, nclasses = model_function(features['image'], mode, params)

  probabilities = tf.nn.softmax(ylogits)
  classes = tf.cast(tf.argmax(probabilities, 1), tf.uint8)
  if mode == tf.estimator.ModeKeys.TRAIN or mode == tf.estimator.ModeKeys.EVAL:
    loss = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits_v2(
            logits=ylogits, labels=labels))
    evalmetrics = {'accuracy': tf.metrics.accuracy(classes, tf.argmax(labels, 1))}
    if mode == tf.estimator.ModeKeys.TRAIN:
      # this is needed for batch normalization, but has no effect otherwise
      update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
      with tf.control_dependencies(update_ops):
         train_op = tf.contrib.layers.optimize_loss(
             loss,
             tf.train.get_global_step(),
             learning_rate=params['learning_rate'],
             optimizer="Adam")
    else:
      train_op = None
  else:
    loss = None
    train_op = None
    evalmetrics = None

  return tf.estimator.EstimatorSpec(
        mode=mode,
        predictions={"probabilities": probabilities, "classes": classes},
        loss=loss,
        train_op=train_op,
        eval_metric_ops=evalmetrics,
        export_outputs={'classes':tf.estimator.export.PredictOutput(
            {"probabilities": probabilities, "classes": classes})}
    )

def train_and_evaluate(output_dir, hparams):
  tf.summary.FileWriterCache.clear() # ensure filewriter cache is clear for TensorBoard events file
  EVAL_INTERVAL = 60

  mnist = input_data.read_data_sets('mnist/data', one_hot=True, reshape=False)

  train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={'image':mnist.train.images},
    y=mnist.train.labels,
    batch_size=100,
    num_epochs=None,
    shuffle=True,
    queue_capacity=5000
  )

  eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={'image':mnist.test.images},
    y=mnist.test.labels,
    batch_size=100,
    num_epochs=1,
    shuffle=False,
    queue_capacity=5000
  )
  estimator = tf.estimator.Estimator(model_fn = image_classifier,
                                     params = hparams,
                                     config=tf.estimator.RunConfig(
                                         save_checkpoints_secs = EVAL_INTERVAL),
                                     model_dir = output_dir)
  train_spec = tf.estimator.TrainSpec(input_fn = train_input_fn,
                                    max_steps = hparams['train_steps'])
  exporter = tf.estimator.LatestExporter('exporter', serving_input_fn)
  eval_spec = tf.estimator.EvalSpec(input_fn = eval_input_fn,
                                  steps = None,
                                  exporters = exporter,
                                  throttle_secs = EVAL_INTERVAL)
  tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
<|endoftext|>


<commit_before>"""distutils.extension

Provides the Extension class, used to describe C/C++ extension
modules in setup scripts."""

# created 2000/05/30, Greg Ward

__revision__ = "$Id$"

from types import *

# This class is really only used by the "build_ext" command, so it might
# make sense to put it in distutils.command.build_ext.  However, that
# module is already big enough, and I want to make this class a bit more
# complex to simplify some common cases ("foo" module in "foo.c") and do
# better error-checking ("foo.c" actually exists).
#
# Also, putting this in build_ext.py means every setup script would have to
# import that large-ish module (indirectly, through distutils.core) in
# order to do anything.

class Extension:
    """Just a collection of attributes that describes an extension
    module and everything needed to build it (hopefully in a portable
    way, but there are hooks that let you be as unportable as you need).

    Instance attributes:
      name : string
        the full name of the extension, including any packages -- ie.
        *not* a filename or pathname, but Python dotted name
      sources : [string]
        list of source filenames, relative to the distribution root
        (where the setup script lives), in Unix form (slash-separated)
        for portability.  Source files may be C, C++, SWIG (.i),
        platform-specific resource files, or whatever else is recognized
        by the "build_ext" command as source for a Python extension.
      include_dirs : [string]
        list of directories to search for C/C++ header files (in Unix
        form for portability)
      define_macros : [(name : string, value : string|None)]
        list of macros to define; each macro is defined using a 2-tuple,
        where 'value' is either the string to define it to or None to
        define it without a particular value (equivalent of "#define
        FOO" in source or -DFOO on Unix C compiler command line)
      undef_macros : [string]
        list of macros to undefine explicitly
      library_dirs : [string]
        list of directories to search for C/C++ libraries at link time
      libraries : [string]
        list of library names (not filenames or paths) to link against
      runtime_library_dirs : [string]
        list of directories to search for C/C++ libraries at run time
        (for shared extensions, this is when the extension is loaded)
      extra_objects : [string]
        list of extra files to link with (eg. object files not implied
        by 'sources', static library that must be explicitly specified,
        binary resource files, etc.)
      extra_compile_args : [string]
        any extra platform- and compiler-specific information to use
        when compiling the source files in 'sources'.  For platforms and
        compilers where "command line" makes sense, this is typically a
        list of command-line arguments, but for other platforms it could
        be anything.
      extra_link_args : [string]
        any extra platform- and compiler-specific information to use
        when linking object files together to create the extension (or
        to create a new static Python interpreter).  Similar
        interpretation as for 'extra_compile_args'.
      export_symbols : [string]
        list of symbols to be exported from a shared extension.  Not
        used on all platforms, and not generally necessary for Python
        extensions, which typically export exactly one symbol: "init" +
        extension_name.
    """

    def __init__ (self, name, sources,
                  include_dirs=None,
                  define_macros=None,
                  undef_macros=None,
                  library_dirs=None,
                  libraries=None,
                  runtime_library_dirs=None,
                  extra_objects=None,
                  extra_compile_args=None,
                  extra_link_args=None,
                  export_symbols=None,
                 ):

        assert type(name) is StringType, "'name' must be a string"
        assert (type(sources) is ListType and
                len(sources) >= 1 and
                map(type, sources) == [StringType]*len(sources)), \
                "'sources' must be a non-empty list of strings"

        self.name = name
        self.sources = sources
        self.include_dirs = include_dirs or []
        self.define_macros = define_macros or []
        self.undef_macros = undef_macros or []
        self.library_dirs = library_dirs or []
        self.libraries = libraries or []
        self.runtime_library_dirs = runtime_library_dirs or []
        self.extra_objects = extra_objects or []
        self.extra_compile_args = extra_compile_args or []
        self.extra_link_args = extra_link_args or []
        self.export_symbols = export_symbols or []

# class Extension
<commit_msg>Added 'read_setup_file()' to read old-style Setup files.  Could make life   easier for people porting Makefile.pre.in-based extensions to Distutils. Also loosened argument-checking in Extension constructor to make life   easier for 'read_setup_file()'.<commit_after>"""distutils.extension

Provides the Extension class, used to describe C/C++ extension
modules in setup scripts."""

# created 2000/05/30, Greg Ward

__revision__ = "$Id$"

import os, string
from types import *

# This class is really only used by the "build_ext" command, so it might
# make sense to put it in distutils.command.build_ext.  However, that
# module is already big enough, and I want to make this class a bit more
# complex to simplify some common cases ("foo" module in "foo.c") and do
# better error-checking ("foo.c" actually exists).
#
# Also, putting this in build_ext.py means every setup script would have to
# import that large-ish module (indirectly, through distutils.core) in
# order to do anything.

class Extension:
    """Just a collection of attributes that describes an extension
    module and everything needed to build it (hopefully in a portable
    way, but there are hooks that let you be as unportable as you need).

    Instance attributes:
      name : string
        the full name of the extension, including any packages -- ie.
        *not* a filename or pathname, but Python dotted name
      sources : [string]
        list of source filenames, relative to the distribution root
        (where the setup script lives), in Unix form (slash-separated)
        for portability.  Source files may be C, C++, SWIG (.i),
        platform-specific resource files, or whatever else is recognized
        by the "build_ext" command as source for a Python extension.
      include_dirs : [string]
        list of directories to search for C/C++ header files (in Unix
        form for portability)
      define_macros : [(name : string, value : string|None)]
        list of macros to define; each macro is defined using a 2-tuple,
        where 'value' is either the string to define it to or None to
        define it without a particular value (equivalent of "#define
        FOO" in source or -DFOO on Unix C compiler command line)
      undef_macros : [string]
        list of macros to undefine explicitly
      library_dirs : [string]
        list of directories to search for C/C++ libraries at link time
      libraries : [string]
        list of library names (not filenames or paths) to link against
      runtime_library_dirs : [string]
        list of directories to search for C/C++ libraries at run time
        (for shared extensions, this is when the extension is loaded)
      extra_objects : [string]
        list of extra files to link with (eg. object files not implied
        by 'sources', static library that must be explicitly specified,
        binary resource files, etc.)
      extra_compile_args : [string]
        any extra platform- and compiler-specific information to use
        when compiling the source files in 'sources'.  For platforms and
        compilers where "command line" makes sense, this is typically a
        list of command-line arguments, but for other platforms it could
        be anything.
      extra_link_args : [string]
        any extra platform- and compiler-specific information to use
        when linking object files together to create the extension (or
        to create a new static Python interpreter).  Similar
        interpretation as for 'extra_compile_args'.
      export_symbols : [string]
        list of symbols to be exported from a shared extension.  Not
        used on all platforms, and not generally necessary for Python
        extensions, which typically export exactly one symbol: "init" +
        extension_name.
    """

    def __init__ (self, name, sources,
                  include_dirs=None,
                  define_macros=None,
                  undef_macros=None,
                  library_dirs=None,
                  libraries=None,
                  runtime_library_dirs=None,
                  extra_objects=None,
                  extra_compile_args=None,
                  extra_link_args=None,
                  export_symbols=None,
                 ):

        assert type(name) is StringType, "'name' must be a string"
        assert (type(sources) is ListType and
                map(type, sources) == [StringType]*len(sources)), \
                "'sources' must be a list of strings"

        self.name = name
        self.sources = sources
        self.include_dirs = include_dirs or []
        self.define_macros = define_macros or []
        self.undef_macros = undef_macros or []
        self.library_dirs = library_dirs or []
        self.libraries = libraries or []
        self.runtime_library_dirs = runtime_library_dirs or []
        self.extra_objects = extra_objects or []
        self.extra_compile_args = extra_compile_args or []
        self.extra_link_args = extra_link_args or []
        self.export_symbols = export_symbols or []

# class Extension

def read_setup_file (filename):
    from distutils.sysconfig import \
         parse_makefile, expand_makefile_vars, _variable_rx
    from distutils.text_file import TextFile
    from distutils.util import split_quoted

    # First pass over the file to gather "VAR = VALUE" assignments.
    vars = parse_makefile(filename)

    # Second pass to gobble up the real content: lines of the form
    #   <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
    file = TextFile(filename,
                    strip_comments=1, skip_blanks=1, join_lines=1,
                    lstrip_ws=1, rstrip_ws=1)
    extensions = []

    while 1:
        line = file.readline()
        if line is None:                # eof
            break
        if _variable_rx.match(line):    # VAR=VALUE, handled in first pass
            continue

        if line[0] == line[-1] == "*":
            file.warn("'%s' lines not handled yet" % line)
            continue

        #print "original line: " + line
        line = expand_makefile_vars(line, vars)
        words = split_quoted(line)
        #print "expanded line: " + line

        # NB. this parses a slightly different syntax than the old
        # makesetup script: here, there must be exactly one extension per
        # line, and it must be the first word of the line.  I have no idea
        # why the old syntax supported multiple extensions per line, as
        # they all wind up being the same.

        module = words[0]
        ext = Extension(module, [])
        append_next_word = None

        for word in words[1:]:
            if append_next_word is not None:
                append_next_word.append(word)
                append_next_word = None
                continue

            suffix = os.path.splitext(word)[1]
            switch = word[0:2] ; value = word[2:]

            if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++"):
                # hmm, should we do something about C vs. C++ sources?
                # or leave it up to the CCompiler implementation to
                # worry about?
                ext.sources.append(word)
            elif switch == "-I":
                ext.include_dirs.append(value)
            elif switch == "-D":
                equals = string.find(value, "=")
                if equals == -1:        # bare "-DFOO" -- no value
                    ext.define_macros.append((value, None))
                else:                   # "-DFOO=blah"
                    ext.define_macros.append((value[0:equals],
                                              value[equals+2:]))
            elif switch == "-U":
                ext.undef_macros.append(value)
            elif switch == "-C":        # only here 'cause makesetup has it!
                ext.extra_compile_args.append(word)
            elif switch == "-l":
                ext.libraries.append(value)
            elif switch == "-L":
                ext.library_dirs.append(value)
            elif switch == "-R":
                ext.runtime_library_dirs.append(value)
            elif word == "-rpath":
                append_next_word = ext.runtime_library_dirs
            elif word == "-Xlinker":
                append_next_word = ext.extra_link_args
            elif switch == "-u":
                ext.extra_link_args.append(word)
                if not value:
                    append_next_word = ext.extra_link_args
            elif suffix in (".a", ".so", ".sl", ".o"):
                # NB. a really faithful emulation of makesetup would
                # append a .o file to extra_objects only if it
                # had a slash in it; otherwise, it would s/.o/.c/
                # and append it to sources.  Hmmmm.
                ext.extra_objects.append(word)
            else:
                file.warn("unrecognized argument '%s'" % word)

        extensions.append(ext)

        #print "module:", module
        #print "source files:", source_files
        #print "cpp args:", cpp_args
        #print "lib args:", library_args

        #extensions[module] = { 'sources': source_files,
        #                       'cpp_args': cpp_args,
        #                       'lib_args': library_args }

    return extensions

# read_setup_file ()
<|endoftext|>