<commit_before>from urllib import urlencode

from django import http
from django.views.generic.list import MultipleObjectMixin
from django.forms import models as model_forms
from django.db import models
from django.core.exceptions import ImproperlyConfigured

from . import fields
from . import helpers
from . import renders
from . import transaction
from . import widgets
from .actions import ActionView
from .forms import VersionFilterForm
from .models import CMSLog
from .base_views import ModelCMSMixin, ModelCMSView
from .actions import CHECKBOX_NAME

class ListView(ModelCMSMixin, MultipleObjectMixin, ModelCMSView):
    """
    Class for listing objects and optionally editing those objects.
    Inherits from ModelCMSMixin, MultipleObjectMixin, ModelCMSView.
    This class adds a ChoicesRender instance as a 'choices' render
    type.

    :param display_fields: List of fields to display in the table. \
    Defaults to ('__unicode__',).
    :param change_fields: List of fields that are editable in this \
    view. Defaults to empty tuple.
    :param form_class: A model form class to use.
    :param filter_form: An instance of BaseFilterForm that can return \
    filter parameters that can be used to filer this list. \
    Defaults to None.
    :param default_template: Defaults to 'cms/list.html'.
    :param can_sort: Does this view allow sorting by column. \
    True or False.
    :param action_links: A list of action links to display \
    with each row. See `get_actions` for details.
    :param origin_action_links: A list of action links that should \
    redirect back here preserving the querystring.
    :param paginate_by: How many items per page. Defaults \
    to None, which means no paginating.
    :param paginator_class: The paginator class to use. \
    Defaults to Paginator.
    """

    # Fields that can be edited in this list.
    change_fields = ()

    # Fields that should be displayed. Must include
    display_fields = ('__unicode__',)

    # class that each form should use
    form_class = None

    filter_form = None

    action_views = None

    default_template = 'cms/list.html'

    # Are we allowed to sort this list?
    can_sort = True

    action_links = (
        ('edit', 'Edit', 'e'),
        ('delete', 'Delete', 'd', True),
        ('publish', 'Publish', 'P', True),
        ('preview', 'Preview', 'p')
    )

    def __init__(self, *args, **kwargs):
        super(ListView, self).__init__(*args, **kwargs)
        self.renders['choices'] = renders.ChoicesRender()

    def get_back_bundle(self, start_bundle=None):
        return None

    def formfield_for_dbfield(self, db_field, **kwargs):
        """
        Same as parent but sets the widget for any OrderFields to
        HiddenTextInput.
        """
        if isinstance(db_field, fields.OrderField):
            kwargs['widget'] = widgets.HiddenTextInput

        return super(ListView, self).formfield_for_dbfield(db_field, **kwargs)

    def _verify_list(self):
        allow_empty = self.get_allow_empty()
        if not allow_empty and len(self.object_list) == 0:
            raise http.Http404

    def get_actions(self):
        """
        Hook for specifying action links.
        Returns `self.action_links` by default.

        The format is a list of tuples. Each tuple
        has four slots:

        * **0** The view name to lookup to get the link.
        * **1** The verbose name of the link.
        * **2** The css attribute for this link.
        * **3** Should this link include an origin redirect
        """

        return self.action_links

    def get_filter_form(self, **kwargs):
        """
        If there is a filter_form, initializes that
        form with the contents of request.GET and
        returns it.
        """

        form = None
        if self.filter_form:
            form = self.filter_form(self.request.GET)
        elif self.model and hasattr(self.model._meta, '_is_view'):
            form = VersionFilterForm(self.request.GET)
        return form

    def get_filter(self, **filter_kwargs):
        """
        Combines the Q objects returned by a valid
        filter form with any other arguments and
        returns a list of Q objects that can be passed
        to a queryset.
        """

        q_objects = super(ListView, self).get_filter(**filter_kwargs)
        form = self.get_filter_form()
        if form:
            q_objects.extend(form.get_filter())

        return q_objects

    def get_formset_form_class(self):
        """
        Returns the form class for use in the formset.

        If a form_class attribute or change_fields
        is provided then a form will be constructed
        with that. Otherwise None is returned.
        """
        if self.form_class or self.change_fields:
            params = {'formfield_callback': self.formfield_for_dbfield}
            if self.form_class:
                fc = self.customize_form_widgets(self.form_class)
                params['form'] = fc
            if self.change_fields:
                params['fields'] = self.change_fields

            return model_forms.modelform_factory(self.model, **params)

    def get_formset_class(self, **kwargs):
        """
        Returns the formset for the queryset,
        if a form class is available.
        """
        form_class = self.get_formset_form_class()
        if form_class:
            kwargs['formfield_callback'] = self.formfield_for_dbfield
            return model_forms.modelformset_factory(self.model,
                        form_class, fields=self.change_fields, extra=0,
                        **kwargs)

    def _add_formset_id(self, data, queryset):
        q = None
        key = self.model._meta.pk.name
        for k, v in data.items():
            if k.endswith('-%s' % key):
                new_q = models.Q(**{key: v})
                if q:
                    q = q | new_q
                else:
                    q = new_q
        queryset = queryset.filter(q)
        return queryset

    def get_formset(self, data=None, queryset=None):
        """
        Returns an instantiated FormSet if available.
        If `self.can_submit` is False then no formset
        is returned.
        """
        if not self.can_submit:
            return None

        FormSet = self.get_formset_class()
        if queryset is None:
            queryset = self.get_queryset()

        if FormSet:
            if data:
                queryset = self._add_formset_id(data, queryset)
            return FormSet(data, queryset=queryset)

    def get_visible_fields(self, formset):
        """
        Returns a list of visible fields. This
        are all the fields in `self.display_fields`
        plus any visible fields in the given formset
        minus any hidden fields in the formset.
        """

        visible_fields = list(self.display_fields)
        if formset:
            for x in formset.empty_form.visible_fields():
                if not x.name in visible_fields:
                    visible_fields.append(x.name)

            for x in formset.empty_form.hidden_fields():
                if x.name in visible_fields:
                    visible_fields.remove(x.name)

        return visible_fields

    def _get_query_string(self, request, exclude_page=True):
        qs = request.GET.copy()
        if 'page' in qs and exclude_page:
            qs.pop('page')

        return '?%s&' % qs.urlencode() if qs else '?'

    def _sort_queryset(self, object_list, sort_field, order_type):
        sort_field = helpers.get_sort_field(sort_field, object_list.model)

        if order_type and sort_field:
            if order_type == helpers.AdminList.ASC:
                queryset = self.object_list.order_by(sort_field)
            else:
                queryset = self.object_list.order_by('-' + sort_field)
        else:
            queryset = self.object_list
            if not queryset.ordered:
                queryset = self.object_list.order_by('-pk')

        return queryset

    def _paginate_queryset(self, queryset):
        page_size = self.get_paginate_by(queryset)
        paginator = None
        if page_size:
            paginator, page, queryset, is_paginated = self.paginate_queryset(
                queryset, page_size)
            is_paginated = True
        else:
            page = None
            is_paginated = False
        return is_paginated, page, paginator, queryset

    def get_action_context(self, request):
        actions = []

        for action in self.action_views or self.bundle._meta.action_views:
            action_name = '{0}{1}'.format(action, self.bundle.action_alias)
            v, name = self.bundle.get_initialized_view_and_name(action_name,
                                                        **self.kwargs)
            url = self.bundle.get_view_url(action_name,
                                    request.user, url_kwargs=self.kwargs)
            if v and url:
                actions.append((url, v.action_name))

        return actions

    def get_list_data(self, request, **kwargs):
        """
        Returns the data needed for displaying the list.
        Returns a dictionary that should be treating as
        context with the following arguments:

        * **list** - The list of data to be displayed. This is \
        an instance of a wrapper class that combines the queryset \
        and formset and provides looping and labels and sorting controls.
        * **filter_form** - An instance of your filter form.
        * **is_paginated** - Is this list paginated, True or False.
        * **paginator** - The paginator object if available.
        * **page_obj** - A pagination object if available.
        * **show_form** - Should the rendering template show form controls.
        """

        self.object_list = self.get_queryset()
        self._verify_list()

        sort_field = None
        order_type = None
        if self.can_sort:
            default = None
            default_order = helpers.AdminList.ASC
            if self.object_list.ordered:
                if self.object_list.query.order_by:
                    default = self.object_list.query.order_by[0]
                else:
                    default = self.object_list.model._meta.ordering[0]
                if default.startswith('-'):
                    default = default[1:]
                    default_order = helpers.AdminList.DESC

            sort_field = request.GET.get('sf', default)
            order_type = request.GET.get('ot', default_order)

        queryset = self._sort_queryset(self.object_list, sort_field,
                                       order_type)

        if self.request.method == 'POST' and self.can_submit:
            formset = self.get_formset(data=self.request.POST, queryset=queryset)
            is_paginated, page, paginator, queryset = self._paginate_queryset(queryset)
        else:
            is_paginated, page, paginator, queryset = self._paginate_queryset(queryset)
            formset = self.get_formset(queryset=queryset)

        visible_fields = self.get_visible_fields(formset)
        adm_list = helpers.AdminList(formset, queryset, visible_fields,
                                       sort_field, order_type,
                                       self.model_name)

        actions = self.get_action_context(request)
        data = {
            'list': adm_list,
            'filter_form': self.get_filter_form(),
            'page_obj': page,
            'is_paginated': is_paginated,
            'show_form': (self.can_submit and formset is not None),
            'paginator': paginator,
            'checkbox_name' : CHECKBOX_NAME,
            'actions' : actions,
        }

        return data

    def get_context_data(self, **kwargs):
        """
        Get the context for this view. Adds the following values:

        * **query_string** - The querystring minus the current page.
        * **action_links** - The results of the `get_actions` method.
        """

        origin_qs = self._get_query_string(self.request, False)
        context = {
            'query_string': self._get_query_string(self.request),
            'origin_qs': self.request.path + origin_qs,
            'origin_var': self.ORIGIN_ARGUMENT,
            'action_links': self.get_actions()
        }
        context.update(kwargs)

        return context

    def get(self, request, *args, **kwargs):
        """
        Method for handling GET requests. If there is
        a GET parameter type=choice, then the render_type
        will be set to 'choices' to return a JSON version
        of this list. Calls `render` with the data from the
        `get_list_data` method as context.
        """

        if request.GET.get('type') == 'choices':
            self.render_type = 'choices'
            self.can_submit = False

        data = self.get_list_data(request, **kwargs)
        return self.render(request, **data)

    def post(self, request, *args, **kwargs):
        """
        Method for handling POST requests.
        If the formset is valid this will
        loop through the formset and save each form.
        A log is generated for each save. The user
        is notified of the total number of changes
        with a message. Returns a 'render redirect' to
        the current url.

        TODO: These formsets suffer from the same potential concurrency
        issues that the django admin has. This is caused by some issues
        with django formsets and concurrent users editing the same
        objects.
        """
        msg = None
        action = request.POST.get('actions', None)
        selected = request.POST.getlist(CHECKBOX_NAME)
        if not action == 'None':
            if len(selected) > 0:
                sel = {CHECKBOX_NAME : ','.join(selected)}
                qs = '?' + urlencode(sel)
                return self.render(request, redirect_url = action + qs)

        data = self.get_list_data(request, **kwargs)

        l = data.get('list')
        formset = None
        if l and l.formset:
            formset = l.formset

        url = self.request.build_absolute_uri()
        if formset:
            # Normally calling validate on a formset.
            # will result in a db call for each pk in
            # the formset regardless if the form has
            # changed or not.
            # To try to reduce queries only do a full
            # validate on forms that changed.
            # TODO: Find a way to not have to do
            # a pk lookup for any since we already
            # have the instance we want
            for form in formset.forms:
                if not form.has_changed():
                    form._errors = {}

        if formset and formset.is_valid():
            changecount = 0
            with transaction.commit_on_success():
                for form in formset.forms:
                    if form.has_changed():
                        obj = form.save()
                        changecount += 1
                        self.log_action(obj, CMSLog.SAVE, url=url,
                                        update_parent=changecount == 1)

            return self.render(request, redirect_url=url,
                           message="%s items updated" % changecount,
                           collect_render_data=False)
        else:
            return self.render(request, message = msg, **data)
<commit_msg>check for python None as well as 'None'<commit_after>from urllib import urlencode

from django import http
from django.views.generic.list import MultipleObjectMixin
from django.forms import models as model_forms
from django.db import models
from django.core.exceptions import ImproperlyConfigured

from . import fields
from . import helpers
from . import renders
from . import transaction
from . import widgets
from .actions import ActionView
from .forms import VersionFilterForm
from .models import CMSLog
from .base_views import ModelCMSMixin, ModelCMSView
from .actions import CHECKBOX_NAME

class ListView(ModelCMSMixin, MultipleObjectMixin, ModelCMSView):
    """
    Class for listing objects and optionally editing those objects.
    Inherits from ModelCMSMixin, MultipleObjectMixin, ModelCMSView.
    This class adds a ChoicesRender instance as a 'choices' render
    type.

    :param display_fields: List of fields to display in the table. \
    Defaults to ('__unicode__',).
    :param change_fields: List of fields that are editable in this \
    view. Defaults to empty tuple.
    :param form_class: A model form class to use.
    :param filter_form: An instance of BaseFilterForm that can return \
    filter parameters that can be used to filer this list. \
    Defaults to None.
    :param default_template: Defaults to 'cms/list.html'.
    :param can_sort: Does this view allow sorting by column. \
    True or False.
    :param action_links: A list of action links to display \
    with each row. See `get_actions` for details.
    :param origin_action_links: A list of action links that should \
    redirect back here preserving the querystring.
    :param paginate_by: How many items per page. Defaults \
    to None, which means no paginating.
    :param paginator_class: The paginator class to use. \
    Defaults to Paginator.
    """

    # Fields that can be edited in this list.
    change_fields = ()

    # Fields that should be displayed. Must include
    display_fields = ('__unicode__',)

    # class that each form should use
    form_class = None

    filter_form = None

    action_views = None

    default_template = 'cms/list.html'

    # Are we allowed to sort this list?
    can_sort = True

    action_links = (
        ('edit', 'Edit', 'e'),
        ('delete', 'Delete', 'd', True),
        ('publish', 'Publish', 'P', True),
        ('preview', 'Preview', 'p')
    )

    def __init__(self, *args, **kwargs):
        super(ListView, self).__init__(*args, **kwargs)
        self.renders['choices'] = renders.ChoicesRender()

    def get_back_bundle(self, start_bundle=None):
        return None

    def formfield_for_dbfield(self, db_field, **kwargs):
        """
        Same as parent but sets the widget for any OrderFields to
        HiddenTextInput.
        """
        if isinstance(db_field, fields.OrderField):
            kwargs['widget'] = widgets.HiddenTextInput

        return super(ListView, self).formfield_for_dbfield(db_field, **kwargs)

    def _verify_list(self):
        allow_empty = self.get_allow_empty()
        if not allow_empty and len(self.object_list) == 0:
            raise http.Http404

    def get_actions(self):
        """
        Hook for specifying action links.
        Returns `self.action_links` by default.

        The format is a list of tuples. Each tuple
        has four slots:

        * **0** The view name to lookup to get the link.
        * **1** The verbose name of the link.
        * **2** The css attribute for this link.
        * **3** Should this link include an origin redirect
        """

        return self.action_links

    def get_filter_form(self, **kwargs):
        """
        If there is a filter_form, initializes that
        form with the contents of request.GET and
        returns it.
        """

        form = None
        if self.filter_form:
            form = self.filter_form(self.request.GET)
        elif self.model and hasattr(self.model._meta, '_is_view'):
            form = VersionFilterForm(self.request.GET)
        return form

    def get_filter(self, **filter_kwargs):
        """
        Combines the Q objects returned by a valid
        filter form with any other arguments and
        returns a list of Q objects that can be passed
        to a queryset.
        """

        q_objects = super(ListView, self).get_filter(**filter_kwargs)
        form = self.get_filter_form()
        if form:
            q_objects.extend(form.get_filter())

        return q_objects

    def get_formset_form_class(self):
        """
        Returns the form class for use in the formset.

        If a form_class attribute or change_fields
        is provided then a form will be constructed
        with that. Otherwise None is returned.
        """
        if self.form_class or self.change_fields:
            params = {'formfield_callback': self.formfield_for_dbfield}
            if self.form_class:
                fc = self.customize_form_widgets(self.form_class)
                params['form'] = fc
            if self.change_fields:
                params['fields'] = self.change_fields

            return model_forms.modelform_factory(self.model, **params)

    def get_formset_class(self, **kwargs):
        """
        Returns the formset for the queryset,
        if a form class is available.
        """
        form_class = self.get_formset_form_class()
        if form_class:
            kwargs['formfield_callback'] = self.formfield_for_dbfield
            return model_forms.modelformset_factory(self.model,
                        form_class, fields=self.change_fields, extra=0,
                        **kwargs)

    def _add_formset_id(self, data, queryset):
        q = None
        key = self.model._meta.pk.name
        for k, v in data.items():
            if k.endswith('-%s' % key):
                new_q = models.Q(**{key: v})
                if q:
                    q = q | new_q
                else:
                    q = new_q
        queryset = queryset.filter(q)
        return queryset

    def get_formset(self, data=None, queryset=None):
        """
        Returns an instantiated FormSet if available.
        If `self.can_submit` is False then no formset
        is returned.
        """
        if not self.can_submit:
            return None

        FormSet = self.get_formset_class()
        if queryset is None:
            queryset = self.get_queryset()

        if FormSet:
            if data:
                queryset = self._add_formset_id(data, queryset)
            return FormSet(data, queryset=queryset)

    def get_visible_fields(self, formset):
        """
        Returns a list of visible fields. This
        are all the fields in `self.display_fields`
        plus any visible fields in the given formset
        minus any hidden fields in the formset.
        """

        visible_fields = list(self.display_fields)
        if formset:
            for x in formset.empty_form.visible_fields():
                if not x.name in visible_fields:
                    visible_fields.append(x.name)

            for x in formset.empty_form.hidden_fields():
                if x.name in visible_fields:
                    visible_fields.remove(x.name)

        return visible_fields

    def _get_query_string(self, request, exclude_page=True):
        qs = request.GET.copy()
        if 'page' in qs and exclude_page:
            qs.pop('page')

        return '?%s&' % qs.urlencode() if qs else '?'

    def _sort_queryset(self, object_list, sort_field, order_type):
        sort_field = helpers.get_sort_field(sort_field, object_list.model)

        if order_type and sort_field:
            if order_type == helpers.AdminList.ASC:
                queryset = self.object_list.order_by(sort_field)
            else:
                queryset = self.object_list.order_by('-' + sort_field)
        else:
            queryset = self.object_list
            if not queryset.ordered:
                queryset = self.object_list.order_by('-pk')

        return queryset

    def _paginate_queryset(self, queryset):
        page_size = self.get_paginate_by(queryset)
        paginator = None
        if page_size:
            paginator, page, queryset, is_paginated = self.paginate_queryset(
                queryset, page_size)
            is_paginated = True
        else:
            page = None
            is_paginated = False
        return is_paginated, page, paginator, queryset

    def get_action_context(self, request):
        actions = []

        for action in self.action_views or self.bundle._meta.action_views:
            action_name = '{0}{1}'.format(action, self.bundle.action_alias)
            v, name = self.bundle.get_initialized_view_and_name(action_name,
                                                        **self.kwargs)
            url = self.bundle.get_view_url(action_name,
                                    request.user, url_kwargs=self.kwargs)
            if v and url:
                actions.append((url, v.action_name))

        return actions

    def get_list_data(self, request, **kwargs):
        """
        Returns the data needed for displaying the list.
        Returns a dictionary that should be treating as
        context with the following arguments:

        * **list** - The list of data to be displayed. This is \
        an instance of a wrapper class that combines the queryset \
        and formset and provides looping and labels and sorting controls.
        * **filter_form** - An instance of your filter form.
        * **is_paginated** - Is this list paginated, True or False.
        * **paginator** - The paginator object if available.
        * **page_obj** - A pagination object if available.
        * **show_form** - Should the rendering template show form controls.
        """

        self.object_list = self.get_queryset()
        self._verify_list()

        sort_field = None
        order_type = None
        if self.can_sort:
            default = None
            default_order = helpers.AdminList.ASC
            if self.object_list.ordered:
                if self.object_list.query.order_by:
                    default = self.object_list.query.order_by[0]
                else:
                    default = self.object_list.model._meta.ordering[0]
                if default.startswith('-'):
                    default = default[1:]
                    default_order = helpers.AdminList.DESC

            sort_field = request.GET.get('sf', default)
            order_type = request.GET.get('ot', default_order)

        queryset = self._sort_queryset(self.object_list, sort_field,
                                       order_type)

        if self.request.method == 'POST' and self.can_submit:
            formset = self.get_formset(data=self.request.POST, queryset=queryset)
            is_paginated, page, paginator, queryset = self._paginate_queryset(queryset)
        else:
            is_paginated, page, paginator, queryset = self._paginate_queryset(queryset)
            formset = self.get_formset(queryset=queryset)

        visible_fields = self.get_visible_fields(formset)
        adm_list = helpers.AdminList(formset, queryset, visible_fields,
                                       sort_field, order_type,
                                       self.model_name)

        actions = self.get_action_context(request)
        data = {
            'list': adm_list,
            'filter_form': self.get_filter_form(),
            'page_obj': page,
            'is_paginated': is_paginated,
            'show_form': (self.can_submit and formset is not None),
            'paginator': paginator,
            'checkbox_name' : CHECKBOX_NAME,
            'actions' : actions,
        }

        return data

    def get_context_data(self, **kwargs):
        """
        Get the context for this view. Adds the following values:

        * **query_string** - The querystring minus the current page.
        * **action_links** - The results of the `get_actions` method.
        """

        origin_qs = self._get_query_string(self.request, False)
        context = {
            'query_string': self._get_query_string(self.request),
            'origin_qs': self.request.path + origin_qs,
            'origin_var': self.ORIGIN_ARGUMENT,
            'action_links': self.get_actions()
        }
        context.update(kwargs)

        return context

    def get(self, request, *args, **kwargs):
        """
        Method for handling GET requests. If there is
        a GET parameter type=choice, then the render_type
        will be set to 'choices' to return a JSON version
        of this list. Calls `render` with the data from the
        `get_list_data` method as context.
        """

        if request.GET.get('type') == 'choices':
            self.render_type = 'choices'
            self.can_submit = False

        data = self.get_list_data(request, **kwargs)
        return self.render(request, **data)

    def post(self, request, *args, **kwargs):
        """
        Method for handling POST requests.
        If the formset is valid this will
        loop through the formset and save each form.
        A log is generated for each save. The user
        is notified of the total number of changes
        with a message. Returns a 'render redirect' to
        the current url.

        TODO: These formsets suffer from the same potential concurrency
        issues that the django admin has. This is caused by some issues
        with django formsets and concurrent users editing the same
        objects.
        """
        msg = None
        action = request.POST.get('actions', None)
        selected = request.POST.getlist(CHECKBOX_NAME)
        if not action == 'None' and action is not None:
            if len(selected) > 0:
                sel = {CHECKBOX_NAME : ','.join(selected)}
                qs = '?' + urlencode(sel)
                return self.render(request, redirect_url = action + qs)

        data = self.get_list_data(request, **kwargs)

        l = data.get('list')
        formset = None
        if l and l.formset:
            formset = l.formset

        url = self.request.build_absolute_uri()
        if formset:
            # Normally calling validate on a formset.
            # will result in a db call for each pk in
            # the formset regardless if the form has
            # changed or not.
            # To try to reduce queries only do a full
            # validate on forms that changed.
            # TODO: Find a way to not have to do
            # a pk lookup for any since we already
            # have the instance we want
            for form in formset.forms:
                if not form.has_changed():
                    form._errors = {}

        if formset and formset.is_valid():
            changecount = 0
            with transaction.commit_on_success():
                for form in formset.forms:
                    if form.has_changed():
                        obj = form.save()
                        changecount += 1
                        self.log_action(obj, CMSLog.SAVE, url=url,
                                        update_parent=changecount == 1)

            return self.render(request, redirect_url=url,
                           message="%s items updated" % changecount,
                           collect_render_data=False)
        else:
            return self.render(request, message = msg, **data)
<|endoftext|>


<commit_before>"""Error-message handling.

For copyright, license, and warranty, see bottom of file.
"""

import sys
from schevo.lib import optimize

import gtk

import schevo.error

BULLET = u'\u2022 '

def show_error(parent, e):
    # By default, just show the error message verbatim.
    markup = [str(e)]
    # Override for specific error types.
    if isinstance(e, schevo.error.DeleteRestricted):
        markup = [
            u'You cannot delete this object from the database.\n'
            u'It is referred to by the following objects:\n'
            u'\n'
            ]
        for entity, referring_entity, referring_field_name in e.restrictions:
            markup.append(BULLET + unicode(entity) + '\n')
    elif isinstance(e, schevo.error.KeyCollision):
        markup = [
            u'You cannot save this object to the database.\n'
            u'There is already an object of this type that has\n'
            u'the following values, which must be unique:\n'
            u'\n'
            ]
        for field_name, field_value in zip(e.key_spec, e.field_values):
            markup.append(BULLET + '%s: %s'
                          % (field_name, field_value))
    markup = u''.join(markup)
    # Show the dialog.
    flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
    win = gtk.MessageDialog(parent=parent, flags=flags,
                            type=gtk.MESSAGE_ERROR,
                            buttons=gtk.BUTTONS_CLOSE,
                            message_format=str(e))
    win.set_markup(markup)
    win.run()
    win.destroy()

optimize.bind_all(sys.modules[__name__])  # Last line of module.

# Copyright (C) 2001-2007 Orbtech, L.L.C.
#
# Schevo
# http://schevo.org/
#
# Orbtech
# Saint Louis, MO
# http://orbtech.com/
#
# This toolkit 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 toolkit 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 St, Fifth Floor, Boston, MA  02110-1301  USA
<commit_msg>Nicer error message for TransactionRuleViolation<commit_after>"""Error-message handling.

For copyright, license, and warranty, see bottom of file.
"""

import sys
from schevo.lib import optimize

import gtk

import schevo.error

BULLET = u'\u2022 '

def escape(s):
    return s.replace('&', '&').replace('<', '<').replace('>', '>')

def show_error(parent, e):
    # By default, just show the error message verbatim.
    markup = [str(e)]
    # Override for specific error types.
    if isinstance(e, schevo.error.DeleteRestricted):
        print 'DeleteRestricted'
        markup = [
            u'The object was not deleted from the database.\n'
            u'\n'
            u'It is referred to by the following objects,\n'
            u'which require you to delete them first before\n'
            u'deleting this object.\n'
            u'\n'
            ]
        for entity, referring_entity, referring_field_name in e.restrictions:
            markup.append(BULLET + '%s\n' % escape(unicode(entity)))
    elif isinstance(e, schevo.error.KeyCollision):
        print 'KeyCollision'
        markup = [
            u'Your changes were not saved.\n'
            u'\n'
            u'There is already an object of this type that has\n'
            u'the following values, which must be unique:\n'
            u'\n'
            ]
        for field_name, field_value in zip(e.key_spec, e.field_values):
            markup.append(BULLET + '%s: %s'
                          % (escape(field_name), escape(field_value)))
    elif isinstance(e, schevo.error.TransactionRuleViolation):
        print 'TransactionRuleViolation'
        markup = [
            u'Your changes were not saved.\n'
            u'\n'
            u'The following transaction rule was violated when\n'
            u'attempting to save:\n'
            u'\n'
            ]
        markup.append(BULLET + u'%s\n' % escape(e.message))
    markup = u''.join(markup)
    # Show the dialog.
    flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
    win = gtk.MessageDialog(parent=parent, flags=flags,
                            type=gtk.MESSAGE_ERROR,
                            buttons=gtk.BUTTONS_CLOSE)
    win.set_markup(markup)
    win.run()
    win.destroy()

optimize.bind_all(sys.modules[__name__])  # Last line of module.

# Copyright (C) 2001-2007 Orbtech, L.L.C.
#
# Schevo
# http://schevo.org/
#
# Orbtech
# Saint Louis, MO
# http://orbtech.com/
#
# This toolkit 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 toolkit 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 St, Fifth Floor, Boston, MA  02110-1301  USA
<|endoftext|>


<commit_before># -*- coding: latin-1 -*-

# Copyright 2018 Google Inc.
#
# 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 curses
import inspect
import os
import sys
import unittest

import third_party.pyperclip as clipboard

import app.ci_program
from app.curses_util import *

class FakeCursesTestCase(unittest.TestCase):
  def setUp(self):
    self.cursesScreen = curses.StandardScreen()
    self.prg = app.ci_program.CiProgram(self.cursesScreen)

  def addClickInfo(self, timeStamp, screenText, bState):
    def createEvent(display, cmdIndex):
      row, col = self.findText(screenText)
      # Note that the mouse info is x,y (col, row).
      info = (timeStamp, col, row, 0, bState)
      curses.addMouseEvent(info)
      return None
    return createEvent

  def addMouseInfo(self, timeStamp, mouseRow, mouseCol, bState):
    """
    bState may be a logical or of:
      curses.BUTTON1_PRESSED;
      curses.BUTTON1_RELEASED;
      ...
      curses.BUTTON_SHIFT
      curses.BUTTON_CTRL
      curses.BUTTON_ALT
    """
    assert type(timeStamp) is int
    assert type(mouseRow) is int
    assert type(mouseCol) is int
    assert type(bState) is int
    # Note that the mouse info is x,y (col, row).
    info = (timeStamp, mouseCol, mouseRow, 0, bState)
    def createEvent(display, cmdIndex):
      curses.addMouseEvent(info)
      return None
    return createEvent

  def displayCheck(self, *args):
    assert type(args[0]) is int
    caller = inspect.stack()[1]
    callerText = u"\n  %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def displayChecker(display, cmdIndex):
      result = display.checkText(*args)
      if result is not None:
        output = callerText + u' at index ' + str(cmdIndex) + result
        if self.cursesScreen.movie:
          print(output)
        else:
          self.fail(output)
      return None
    return displayChecker

  def displayCheckNot(self, *args):
    """
    Verify that the display does not match.
    """
    assert type(args[0]) is int
    caller = inspect.stack()[1]
    callerText = "\n  %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def displayCheckerNot(display, cmdIndex):
      result = display.checkText(*args)
      if result is None:
        output = callerText + u' at index ' + str(cmdIndex)
        if self.cursesScreen.movie:
          print(output)
        else:
          self.fail(output)
      return None
    return displayCheckerNot

  def displayCheckStyle(self, *args):
    caller = inspect.stack()[1]
    callerText = u"\n  %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def displayStyleChecker(display, cmdIndex):
      result = display.checkStyle(*args)
      if result is not None:
        output = callerText + u' at index ' + str(cmdIndex) + result
        if self.cursesScreen.movie:
          print(output)
        else:
          self.fail(output)
      return None
    return displayStyleChecker

  def findText(self, screenText):
    """Locate |screenText| on the display, returning row, col.
    """
    return self.cursesScreen.test_find_text(screenText)

  def cursorCheck(self, expectedRow, expectedCol):
    assert type(expectedRow) is int
    assert type(expectedCol) is int
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def cursorChecker(display, cmdIndex):
      penRow, penCol = self.cursesScreen.getyx()
      if self.cursesScreen.movie:
        return None
      self.assertEqual((expectedRow, expectedCol), (penRow, penCol), callerText)
      return None
    return cursorChecker

  def resizeScreen(self, rows, cols):
    assert type(rows) is int
    assert type(cols) is int
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def setScreenSize(display, cmdIndex):
      self.cursesScreen.fakeDisplay.setScreenSize(rows, cols)
      return curses.KEY_RESIZE
    return setScreenSize

  def setClipboard(self, text):
    assert type(text) is str
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def copyToClipboard(display, cmdIndex):
      self.assertTrue(clipboard.copy)  # Check that copy exists.
      clipboard.copy(text)
      return None
    return copyToClipboard

  def setMovieMode(self, enabled):
    self.cursesScreen.movie = enabled
    self.cursesScreen.fakeInput.isVerbose = enabled

  def writeText(self, text):
    assert type(text) is unicode, type(text)
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def copyToClipboard(display, cmdIndex):
      self.assertTrue(clipboard.copy)  # Check that copy exists.
      clipboard.copy(text)
      return CTRL_V
    return copyToClipboard

  def notReached(display):
    """Calling this will fail the test. It's expected that the code will not
    reach this function."""
    self.fail('Called notReached!')

  def runWithFakeInputs(self, fakeInputs):
    assert hasattr(fakeInputs, "__getitem__") or hasattr(fakeInputs, "__iter__")
    app.color.reset(),
    self.cursesScreen.setFakeInputs(fakeInputs + [self.notReached,])
    self.assertTrue(self.prg)
    self.assertFalse(self.prg.exiting)
    self.prg.run()
    #curses.printFakeDisplay()
    if app.ci_program.userConsoleMessage:
      message = app.ci_program.userConsoleMessage
      app.ci_program.userConsoleMessage = None
      self.fail(message)
    # Check that the application is closed down (don't leave it running across
    # tests).
    self.assertTrue(self.prg.exiting)
    self.assertEqual(self.cursesScreen.fakeInput.inputsIndex,
        len(fakeInputs) - 1)
    # Handy for debugging.
    if 0:
      caller = inspect.stack()[1]
      callerText = u"  %s:%s:%s(): " % (
          os.path.split(caller[1])[1], caller[2], caller[3])
      print(u'\n-------- finished', callerText)

  def runWithTestFile(self, kTestFile, fakeInputs):
    sys.argv = [kTestFile]
    self.assertFalse(os.path.isfile(kTestFile))
    self.runWithFakeInputs(fakeInputs)

  def selectionDocumentCheck(self, expectedPenRow, expectedPenCol, expectedMarkerRow,
      expectedMarkerCol, expectedMode):
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def checker(display, cmdIndex):
      selection = self.prg.getDocumentSelection()
      self.assertEqual((expectedPenRow, expectedPenCol, expectedMarkerRow,
          expectedMarkerCol, expectedMode), selection, callerText)
    return checker

  def selectionCheck(self, expectedPenRow, expectedPenCol, expectedMarkerRow,
      expectedMarkerCol, expectedMode):
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def checker(display, cmdIndex):
      selection = self.prg.getSelection()
      self.assertEqual((expectedPenRow, expectedPenCol, expectedMarkerRow,
          expectedMarkerCol, expectedMode), selection, callerText)
    return checker

  def tearDown(self):
    # Disable mouse tracking in xterm.
    sys.stdout.write(b'\033[?1002l\n')
    # Disable Bracketed Paste Mode.
    sys.stdout.write(b'\033[?2004l\n')
<commit_msg>add debug_print_stack()<commit_after># -*- coding: latin-1 -*-

# Copyright 2018 Google Inc.
#
# 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 curses
import inspect
import os
import sys
import unittest

import third_party.pyperclip as clipboard

import app.ci_program
from app.curses_util import *

def debug_print_stack(*args):
  stack = inspect.stack()[1:]
  stack.reverse()
  lines = []
  for i,frame in enumerate(stack):
    lines.append(u"stack %2d %14s %4s %s" % (i, os.path.split(frame[1])[1],
        frame[2], frame[3]))
  print(u"\n".join(lines))

class FakeCursesTestCase(unittest.TestCase):
  def setUp(self):
    self.cursesScreen = curses.StandardScreen()
    self.prg = app.ci_program.CiProgram(self.cursesScreen)

  def addClickInfo(self, timeStamp, screenText, bState):
    def createEvent(display, cmdIndex):
      row, col = self.findText(screenText)
      # Note that the mouse info is x,y (col, row).
      info = (timeStamp, col, row, 0, bState)
      curses.addMouseEvent(info)
      return None
    return createEvent

  def addMouseInfo(self, timeStamp, mouseRow, mouseCol, bState):
    """
    bState may be a logical or of:
      curses.BUTTON1_PRESSED;
      curses.BUTTON1_RELEASED;
      ...
      curses.BUTTON_SHIFT
      curses.BUTTON_CTRL
      curses.BUTTON_ALT
    """
    assert type(timeStamp) is int
    assert type(mouseRow) is int
    assert type(mouseCol) is int
    assert type(bState) is int
    # Note that the mouse info is x,y (col, row).
    info = (timeStamp, mouseCol, mouseRow, 0, bState)
    def createEvent(display, cmdIndex):
      curses.addMouseEvent(info)
      return None
    return createEvent

  def displayCheck(self, *args):
    assert type(args[0]) is int
    caller = inspect.stack()[1]
    callerText = u"\n  %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def displayChecker(display, cmdIndex):
      result = display.checkText(*args)
      if result is not None:
        output = callerText + u' at index ' + str(cmdIndex) + result
        if self.cursesScreen.movie:
          print(output)
        else:
          self.fail(output)
      return None
    return displayChecker

  def displayCheckNot(self, *args):
    """
    Verify that the display does not match.
    """
    assert type(args[0]) is int
    caller = inspect.stack()[1]
    callerText = "\n  %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def displayCheckerNot(display, cmdIndex):
      result = display.checkText(*args)
      if result is None:
        output = callerText + u' at index ' + str(cmdIndex)
        if self.cursesScreen.movie:
          print(output)
        else:
          self.fail(output)
      return None
    return displayCheckerNot

  def displayCheckStyle(self, *args):
    caller = inspect.stack()[1]
    callerText = u"\n  %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def displayStyleChecker(display, cmdIndex):
      result = display.checkStyle(*args)
      if result is not None:
        output = callerText + u' at index ' + str(cmdIndex) + result
        if self.cursesScreen.movie:
          print(output)
        else:
          self.fail(output)
      return None
    return displayStyleChecker

  def findText(self, screenText):
    """Locate |screenText| on the display, returning row, col.
    """
    return self.cursesScreen.test_find_text(screenText)

  def cursorCheck(self, expectedRow, expectedCol):
    assert type(expectedRow) is int
    assert type(expectedCol) is int
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def cursorChecker(display, cmdIndex):
      penRow, penCol = self.cursesScreen.getyx()
      if self.cursesScreen.movie:
        return None
      self.assertEqual((expectedRow, expectedCol), (penRow, penCol), callerText)
      return None
    return cursorChecker

  def resizeScreen(self, rows, cols):
    assert type(rows) is int
    assert type(cols) is int
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def setScreenSize(display, cmdIndex):
      self.cursesScreen.fakeDisplay.setScreenSize(rows, cols)
      return curses.KEY_RESIZE
    return setScreenSize

  def setClipboard(self, text):
    assert type(text) is str
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def copyToClipboard(display, cmdIndex):
      self.assertTrue(clipboard.copy)  # Check that copy exists.
      clipboard.copy(text)
      return None
    return copyToClipboard

  def setMovieMode(self, enabled):
    self.cursesScreen.movie = enabled
    self.cursesScreen.fakeInput.isVerbose = enabled

  def writeText(self, text):
    assert type(text) is unicode, type(text)
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def copyToClipboard(display, cmdIndex):
      self.assertTrue(clipboard.copy)  # Check that copy exists.
      clipboard.copy(text)
      return CTRL_V
    return copyToClipboard

  def notReached(display):
    """Calling this will fail the test. It's expected that the code will not
    reach this function."""
    self.fail('Called notReached!')

  def runWithFakeInputs(self, fakeInputs):
    assert hasattr(fakeInputs, "__getitem__") or hasattr(fakeInputs, "__iter__")
    app.color.reset(),
    self.cursesScreen.setFakeInputs(fakeInputs + [self.notReached,])
    self.assertTrue(self.prg)
    self.assertFalse(self.prg.exiting)
    self.prg.run()
    #curses.printFakeDisplay()
    if app.ci_program.userConsoleMessage:
      message = app.ci_program.userConsoleMessage
      app.ci_program.userConsoleMessage = None
      self.fail(message)
    # Check that the application is closed down (don't leave it running across
    # tests).
    self.assertTrue(self.prg.exiting)
    self.assertEqual(self.cursesScreen.fakeInput.inputsIndex,
        len(fakeInputs) - 1)
    # Handy for debugging.
    if 0:
      caller = inspect.stack()[1]
      callerText = u"  %s:%s:%s(): " % (
          os.path.split(caller[1])[1], caller[2], caller[3])
      print(u'\n-------- finished', callerText)

  def runWithTestFile(self, kTestFile, fakeInputs):
    sys.argv = [kTestFile]
    self.assertFalse(os.path.isfile(kTestFile))
    self.runWithFakeInputs(fakeInputs)

  def selectionDocumentCheck(self, expectedPenRow, expectedPenCol, expectedMarkerRow,
      expectedMarkerCol, expectedMode):
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def checker(display, cmdIndex):
      selection = self.prg.getDocumentSelection()
      self.assertEqual((expectedPenRow, expectedPenCol, expectedMarkerRow,
          expectedMarkerCol, expectedMode), selection, callerText)
    return checker

  def selectionCheck(self, expectedPenRow, expectedPenCol, expectedMarkerRow,
      expectedMarkerCol, expectedMode):
    caller = inspect.stack()[1]
    callerText = u"in %s:%s:%s(): " % (
        os.path.split(caller[1])[1], caller[2], caller[3])
    def checker(display, cmdIndex):
      selection = self.prg.getSelection()
      self.assertEqual((expectedPenRow, expectedPenCol, expectedMarkerRow,
          expectedMarkerCol, expectedMode), selection, callerText)
    return checker

  def tearDown(self):
    # Disable mouse tracking in xterm.
    sys.stdout.write(b'\033[?1002l\n')
    # Disable Bracketed Paste Mode.
    sys.stdout.write(b'\033[?2004l\n')
<|endoftext|>


<commit_before>"""Error-message handling.

For copyright, license, and warranty, see bottom of file.
"""

import sys
from schevo.lib import optimize

import gtk

import schevo.error

BULLET = u'\u2022 '

def escape(s):
    return s.replace('&', '&').replace('<', '<').replace('>', '>')

def show_error(parent, e):
    # Override for specific error types.
    if isinstance(e, schevo.error.DeleteRestricted):
        print 'DeleteRestricted'
        markup = [
            u'The object was not deleted from the database.\n'
            u'\n'
            u'It is referred to by the following objects,\n'
            u'which require you to delete them first before\n'
            u'deleting this object.\n'
            u'\n'
            ]
        for entity, referring_entity, referring_field_name in e.restrictions:
            markup.append(BULLET + '%s\n' % escape(unicode(entity)))
    elif isinstance(e, schevo.error.KeyCollision):
        print 'KeyCollision'
        markup = [
            u'Your changes were not saved.\n'
            u'\n'
            u'There is already an object of this type that has\n'
            u'the following values, which must be unique:\n'
            u'\n'
            ]
        for field_name, field_value in zip(e.key_spec, e.field_values):
            markup.append(BULLET + '%s: %s'
                          % (escape(field_name), escape(field_value)))
    elif isinstance(e, schevo.error.TransactionRuleViolation):
        print 'TransactionRuleViolation'
        markup = [
            u'Your changes were not saved.\n'
            u'\n'
            u'The following transaction rule was violated when\n'
            u'attempting to save:\n'
            u'\n'
            ]
        markup.append(BULLET + u'%s\n' % escape(e.message))
    else:
        # By default, just show the error message verbatim.
        markup = [escape(str(e))]
    markup = u''.join(markup)
    # Show the dialog.
    flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
    win = gtk.MessageDialog(parent=parent, flags=flags,
                            type=gtk.MESSAGE_ERROR,
                            buttons=gtk.BUTTONS_CLOSE)
    win.set_markup(markup)
    win.run()
    win.destroy()

optimize.bind_all(sys.modules[__name__])  # Last line of module.

# Copyright (C) 2001-2007 Orbtech, L.L.C.
#
# Schevo
# http://schevo.org/
#
# Orbtech
# Saint Louis, MO
# http://orbtech.com/
#
# This toolkit 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 toolkit 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 St, Fifth Floor, Boston, MA  02110-1301  USA
<commit_msg>Better wording for TransactionFieldsNotChanged<commit_after>"""Error-message handling.

For copyright, license, and warranty, see bottom of file.
"""

import sys
from schevo.lib import optimize

import gtk

import schevo.error

BULLET = u'\u2022 '

def escape(s):
    return s.replace('&', '&').replace('<', '<').replace('>', '>')

def show_error(parent, e):
    # Override for specific error types.
    if isinstance(e, schevo.error.DeleteRestricted):
        markup = [
            u'The object was not deleted from the database.\n'
            u'\n'
            u'It is referred to by the following objects,\n'
            u'which require you to delete them first before\n'
            u'deleting this object.\n'
            u'\n'
            ]
        for entity, referring_entity, referring_field_name in e.restrictions:
            markup.append(BULLET + '%s\n' % escape(unicode(entity)))
    elif isinstance(e, schevo.error.KeyCollision):
        markup = [
            u'Your changes were not saved.\n'
            u'\n'
            u'There is already an object of this type that has\n'
            u'the following values, which must be unique:\n'
            u'\n'
            ]
        for field_name, field_value in zip(e.key_spec, e.field_values):
            markup.append(BULLET + '%s: %s'
                          % (escape(field_name), escape(field_value)))
    elif isinstance(e, schevo.error.TransactionRuleViolation):
        markup = [
            u'Your changes were not saved.\n'
            u'\n'
            u'The following transaction rule was violated when\n'
            u'attempting to save:\n'
            u'\n'
            ]
        markup.append(BULLET + u'%s\n' % escape(e.message))
    elif isinstance(e, schevo.error.TransactionFieldsNotChanged):
        markup = [
            u'No fields changed.\n'
            u'\n'
            u'Change at least one field to update this object,\n'
            u'or click Cancel to leave it unchanged.\n'
            ]
    else:
        # By default, just show the error message verbatim.
        markup = [escape(str(e))]
    markup = u''.join(markup)
    # Show the dialog.
    flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
    win = gtk.MessageDialog(parent=parent, flags=flags,
                            type=gtk.MESSAGE_ERROR,
                            buttons=gtk.BUTTONS_CLOSE)
    win.set_markup(markup)
    win.run()
    win.destroy()

optimize.bind_all(sys.modules[__name__])  # Last line of module.

# Copyright (C) 2001-2007 Orbtech, L.L.C.
#
# Schevo
# http://schevo.org/
#
# Orbtech
# Saint Louis, MO
# http://orbtech.com/
#
# This toolkit 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 toolkit 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 St, Fifth Floor, Boston, MA  02110-1301  USA
<|endoftext|>


<commit_before>#!/usr/bin/env python
import os
import json
import time
import argparse
import subprocess
import terminal

snapshot_id = '7067f369f7b76f0a3276beb561820a21c9b5204ab60fbd90524560db96d7cb38'
key_name = 'tempkey'

def generate_ssh_key(key_file):
    subprocess.call(['ssh-keygen','-f', key_file,'-P',''])

def get_public_key(key_file):
    with open(key_file) as f:
        content = f.readlines()[0].rstrip('\n')
    return str(content)

def start_snap(name, snapshot_id, size=None, script=None):
    output = terminal.start_snapshot(snapshot_id, size, None, name, None, script)
    request_id = output['request_id']
    output = terminal.request_progress(request_id)
    state = 'None'
    time.sleep(1)
    while output['status'] != 'success':
        output = terminal.request_progress(request_id)
        if output['state'] != state:
            state = output['state']
            print('(%s)' % state)
        time.sleep(1)
    container_key = output['result']['container_key']
    subdomain = output['result']['subdomain']
    container_ip = output['result']['container_ip']
    return container_key, container_ip, subdomain

def run_on_terminal(cip, user, pemfile, script):
    try:
        p = subprocess.Popen(
        ['ssh', '-q' ,'-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', '-i', pemfile,
         user + '@' + cip, script], 0, None,  None, None, None)
        p.wait()
        return p.returncode
    except Exception, e:
        return 'Error: [%s]' % e

def get_script(filename):
    try:
        with open(filename) as f:
            data = f.read()
            data.replace('\n',';')
        return data
    except Exception, e:
        print '(%s)' % e
        return None

def send_script(cip, user, script, pemfile, path=''):
    try:
        p = subprocess.Popen(
        ['scp', '-q' ,'-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', '-i', pemfile,
         script, '%s@%s:%s' % (user,cip,path)], 0, None,  None, None, None)
        p.wait()
        return p.returncode
    except Exception, e:
        return 'Error: [%s]' % e

def args_sanitizer(args):
    if args.size not in terminal.instance_types()['instance_types']:
        print "Error. Wrong instance type"
        exit(1)
    if (int(args.quantity) < 1 or int(args.quantity) > 100):
        print "Error. Terminal amount out of bounds ( should be in between 1 and 100 )"
        exit(1)
    if args.method not in ('ssh, startup'):
        print "Error. Not a valid method. (use ssh or startup)"
        exit(1)
    if args.ssh_key_file is None:
        key_name = args.ssh_key_file

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("quantity", type=int, help="How many nodes will have your deploy")
    parser.add_argument("-s", "--size", type=str, default='medium', help="micro, mini, small, [medium], xlarge.. etc")
    parser.add_argument("-u", "--utoken", type=str, default=None ,help="Your user token")
    parser.add_argument("-a", "--atoken", type=str, default=None, help="Your access token")
    parser.add_argument("-c", "--creds", type=str, default='/etc/creds.json', help="A credentials json file")
    parser.add_argument("-x", "--script", type=str, default=None, help="A script file to be executed in the new Terminals. \n\
    With ssh method you can also use a binary executable. \n\
    If a script is not provided, the terminals will be created and ssh keys installed on them.")
    parser.add_argument('-m', "--method", type=str, default='ssh', help="[ssh] or startup script methods")
    parser.add_argument('-n', "--name", type=str, default='Scripted Terminal', help="The name of your Terminal")
    parser.add_argument('-k', "--ssh_key_file", type=str, default=None, help="Use your own ssh key instead of create a new one - \
    Use your private key name")
    parser.description="Utility to start and setup Terminals"
    args = parser.parse_args()

    terminal.setup_credentials(args.utoken, args.atoken, args.creds)
    args_sanitizer(args)

    # Preparing
    if args.method == 'ssh':
        if args.ssh_key_file is None:
            generate_ssh_key(key_name)
        else:
            key_name=args.ssh_key_file
        publicKey=get_public_key('%s.pub' % key_name)
        script=None
    else:
        if args.script is not None:
            script=get_script(args.script)
        else:
            script=None

    # Creating terminals
    terminals=[]
    for i in range(args.quantity):
        name = '%s-%s' % (args.name,i)
        print "Starting Terminal %s" % name
        container_key, container_ip, subdomain = start_snap(name, snapshot_id, args.size, script)
        terminals.append({'container_key':container_key, 'container_ip':container_ip, 'subdomain':subdomain, 'name':name})
    time.sleep(2) # Prevent race-condition issues

    # Installing stuff by ssh method
    if args.method == 'ssh':
        for i in range(len(terminals)):
            terminal.add_authorized_key_to_terminal(terminals[i]['container_key'],publicKey)
            time.sleep(1)
            if args.script is not None:
                send_script(terminals[i]['container_ip'], 'root', key_name ,script)
                run_on_terminal(terminals[i]['container_ip'], 'root', key_name ,'/bin/bash /root/%s' % os.path.basename(args.script))

    # Print results in json format
    print json.dumps(terminals)<commit_msg>bugfixes<commit_after>#!/usr/bin/env python
import os
import json
import time
import argparse
import subprocess
import terminal

snapshot_id = '7067f369f7b76f0a3276beb561820a21c9b5204ab60fbd90524560db96d7cb38'
key_name = 'tempkey'

def generate_ssh_key(key_file):
    subprocess.call(['ssh-keygen','-f', key_file,'-P',''])

def get_public_key(key_file):
    with open(key_file) as f:
        content = f.readlines()[0].rstrip('\n')
    return str(content)

def start_snap(name, snapshot_id, size=None, script=None):
    output = terminal.start_snapshot(snapshot_id, size, None, name, None, script)
    request_id = output['request_id']
    output = terminal.request_progress(request_id)
    state = 'None'
    time.sleep(1)
    while output['status'] != 'success':
        output = terminal.request_progress(request_id)
        if output['state'] != state:
            state = output['state']
            print('(%s)' % state)
        time.sleep(1)
    container_key = output['result']['container_key']
    subdomain = output['result']['subdomain']
    container_ip = output['result']['container_ip']
    return container_key, container_ip, subdomain

def run_on_terminal(cip, user, pemfile, script):
    try:
        p = subprocess.Popen(
        ['ssh', '-q' ,'-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', '-i', pemfile,
         user + '@' + cip, script], 0, None,  None, None, None)
        p.wait()
        return p.returncode
    except Exception, e:
        return 'Error: [%s]' % e

def get_script(filename):
    try:
        with open(filename) as f:
            data = f.read()
            data.replace('\n',';')
        return data
    except Exception, e:
        print '(%s)' % e
        return None

def send_script(cip, user, script, pemfile, path=''):
    try:
        p = subprocess.Popen(
        ['scp' , -i, pemfile, '-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null',
         script, '%s@%s:%s' % (user,cip,path)], 0, None,  None, None, None)
        p.wait()
        return p.returncode
    except Exception, e:
        return 'Error: [%s]' % e

def args_sanitizer(args):
    if args.size not in terminal.instance_types()['instance_types']:
        print "Error. Wrong instance type"
        exit(1)
    if (int(args.quantity) < 1 or int(args.quantity) > 100):
        print "Error. Terminal amount out of bounds ( should be in between 1 and 100 )"
        exit(1)
    if args.method not in ('ssh, startup'):
        print "Error. Not a valid method. (use ssh or startup)"
        exit(1)
    if args.ssh_key_file is None:
        key_name = args.ssh_key_file

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("quantity", type=int, help="How many nodes will have your deploy")
    parser.add_argument("-s", "--size", type=str, default='medium', help="micro, mini, small, [medium], xlarge.. etc")
    parser.add_argument("-u", "--utoken", type=str, default=None ,help="Your user token")
    parser.add_argument("-a", "--atoken", type=str, default=None, help="Your access token")
    parser.add_argument("-c", "--creds", type=str, default='/etc/creds.json', help="A credentials json file")
    parser.add_argument("-x", "--script", type=str, default=None, help="A script file to be executed in the new Terminals. \n\
    With ssh method you can also use a binary executable. \n\
    If a script is not provided, the terminals will be created and ssh keys installed on them.")
    parser.add_argument('-m', "--method", type=str, default='ssh', help="[ssh] or startup script methods")
    parser.add_argument('-n', "--name", type=str, default='Scripted Terminal', help="The name of your Terminal")
    parser.add_argument('-k', "--ssh_key_file", type=str, default=None, help="Use your own ssh key instead of create a new one - \
    Use your private key name")
    parser.description="Utility to start and setup Terminals"
    args = parser.parse_args()

    terminal.setup_credentials(args.utoken, args.atoken, args.creds)
    args_sanitizer(args)

    # Preparing
    if args.method == 'ssh':
        if args.ssh_key_file is None:
            generate_ssh_key(key_name)
        else:
            key_name=args.ssh_key_file
        publicKey=get_public_key('%s.pub' % key_name)
        script=None
    else:
        if args.script is not None:
            script=get_script(args.script)
        else:
            script=None

    # Creating terminals
    terminals=[]
    for i in range(args.quantity):
        name = '%s-%s' % (args.name,i)
        print "Starting Terminal %s" % name
        container_key, container_ip, subdomain = start_snap(name, snapshot_id, args.size, script)
        terminals.append({'container_key':container_key, 'container_ip':container_ip, 'subdomain':subdomain, 'name':name})
    time.sleep(2) # Prevent race-condition issues

    # Installing stuff by ssh method
    if args.method == 'ssh':
        for i in range(len(terminals)):
            terminal.add_authorized_key_to_terminal(terminals[i]['container_key'],publicKey)
            time.sleep(1)
            if args.script is not None:
                print "Sending Script"
                send_script(terminals[i]['container_ip'], 'root', key_name ,script)
                print "Running Script"
                run_on_terminal(terminals[i]['container_ip'], 'root', key_name ,'/bin/bash /root/%s' % os.path.basename(args.script))

    # Print results in json format
    print json.dumps(terminals)<|endoftext|>


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

import argparse
import os
import subprocess
import sys

from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL, PLATFORM, \
                       enable_verbose_mode, is_verbose_mode, get_target_arch
from lib.util import execute_stdout, get_electron_version, scoped_cwd

SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
PYTHON_26_URL = 'https://chromium.googlesource.com/chromium/deps/python_26'

if os.environ.has_key('CI'):
  NPM = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'npm')
else:
  NPM = 'npm'
if sys.platform in ['win32', 'cygwin']:
  NPM += '.cmd'

def main():
  os.chdir(SOURCE_ROOT)

  args = parse_args()
  defines = args_to_defines(args)
  if not args.yes and PLATFORM != 'win32':
    check_root()
  if args.verbose:
    enable_verbose_mode()
  if sys.platform == 'cygwin':
    update_win32_python()

  update_submodules()

  libcc_source_path = args.libcc_source_path
  libcc_shared_library_path = args.libcc_shared_library_path
  libcc_static_library_path = args.libcc_static_library_path

  # Redirect to use local libchromiumcontent build.
  if args.build_libchromiumcontent:
    build_libchromiumcontent(args.verbose, args.target_arch, defines)
    dist_dir = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
                            'libchromiumcontent', 'dist', 'main')
    libcc_source_path = os.path.join(dist_dir, 'src')
    libcc_shared_library_path = os.path.join(dist_dir, 'shared_library')
    libcc_static_library_path = os.path.join(dist_dir, 'static_library')

  if PLATFORM != 'win32':
    if not args.disable_clang and args.clang_dir == '':
      # Download prebuilt clang binaries.
      update_clang()

  setup_python_libs()
  update_node_modules('.')
  bootstrap_brightray(args.dev, args.url, args.target_arch,
                      libcc_source_path, libcc_shared_library_path,
                      libcc_static_library_path)

  if PLATFORM == 'linux':
    download_sysroot(args.target_arch)

  create_chrome_version_h()
  touch_config_gypi()
  run_update(defines, args.msvs, args.disable_clang, args.clang_dir)
  update_electron_modules('spec', args.target_arch)

def parse_args():
  parser = argparse.ArgumentParser(description='Bootstrap this project')
  parser.add_argument('-u', '--url',
                      help='The base URL from which to download '
                      'libchromiumcontent (i.e., the URL you passed to '
                      'libchromiumcontent\'s script/upload script',
                      default=BASE_URL,
                      required=False)
  parser.add_argument('-v', '--verbose',
                      action='store_true',
                      help='Prints the output of the subprocesses')
  parser.add_argument('-d', '--dev', action='store_true',
                      help='Do not download static_library build')
  parser.add_argument('-y', '--yes', '--assume-yes',
                      action='store_true',
                      help='Run non-interactively by assuming "yes" to all ' \
                           'prompts.')
  parser.add_argument('--msvs', action='store_true',
                      help='Generate Visual Studio project')
  parser.add_argument('--target_arch', default=get_target_arch(),
                      help='Manually specify the arch to build for')
  parser.add_argument('--clang_dir', default='', help='Path to clang binaries')
  parser.add_argument('--disable_clang', action='store_true',
                      help='Use compilers other than clang for building')
  parser.add_argument('--build_libchromiumcontent', action='store_true',
                      help='Build local version of libchromiumcontent')
  parser.add_argument('--libcc_source_path', required=False,
                      help='The source path of libchromiumcontent. ' \
                           'NOTE: All options of libchromiumcontent are ' \
                           'required OR let electron choose it')
  parser.add_argument('--libcc_shared_library_path', required=False,
                      help='The shared library path of libchromiumcontent.')
  parser.add_argument('--libcc_static_library_path', required=False,
                      help='The static library path of libchromiumcontent.')
  return parser.parse_args()

def args_to_defines(args):
  defines = ''
  if args.disable_clang:
    defines += ' clang=0'
  if args.clang_dir:
    defines += ' make_clang_dir=' + args.clang_dir
    defines += ' clang_use_chrome_plugins=0'
  return defines

def check_root():
  if os.geteuid() == 0:
    print "We suggest not running this as root, unless you're really sure."
    choice = raw_input("Do you want to continue? [y/N]: ")
    if choice not in ('y', 'Y'):
      sys.exit(0)

def update_submodules():
  execute_stdout(['git', 'submodule', 'sync', '--recursive'])
  execute_stdout(['git', 'submodule', 'update', '--init', '--recursive'])

def setup_python_libs():
  for lib in ('requests', 'boto'):
    with scoped_cwd(os.path.join(VENDOR_DIR, lib)):
      execute_stdout([sys.executable, 'setup.py', 'build'])

def bootstrap_brightray(is_dev, url, target_arch, libcc_source_path,
                        libcc_shared_library_path,
                        libcc_static_library_path):
  bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap')
  args = [
    '--commit', LIBCHROMIUMCONTENT_COMMIT,
    '--target_arch', target_arch,
    url
  ]
  if is_dev:
    args = ['--dev'] + args
  if (libcc_source_path != None and
      libcc_shared_library_path != None and
      libcc_static_library_path != None):
    args += ['--libcc_source_path', libcc_source_path,
             '--libcc_shared_library_path', libcc_shared_library_path,
             '--libcc_static_library_path', libcc_static_library_path]
  execute_stdout([sys.executable, bootstrap] + args)

def set_clang_env(env):
  llvm_dir = os.path.join(SOURCE_ROOT, 'vendor', 'llvm-build',
                          'Release+Asserts', 'bin')
  env['CC']  = os.path.join(llvm_dir, 'clang')
  env['CXX'] = os.path.join(llvm_dir, 'clang++')

def update_node_modules(dirname, env=None):
  if env is None:
    env = os.environ.copy()
  if PLATFORM == 'linux':
    # Use prebuilt clang for building native modules.
    set_clang_env(env)
    env['npm_config_clang'] = '1'
  with scoped_cwd(dirname):
    args = [NPM, 'install']
    if is_verbose_mode():
      args += ['--verbose']
    # Ignore npm install errors when running in CI.
    if os.environ.has_key('CI'):
      try:
        execute_stdout(args, env)
      except subprocess.CalledProcessError:
        pass
    else:
      execute_stdout(args, env)

def update_electron_modules(dirname, target_arch):
  env = os.environ.copy()
  env['npm_config_arch']    = target_arch
  env['npm_config_target']  = get_electron_version()
  env['npm_config_disturl'] = 'https://atom.io/download/atom-shell'
  update_node_modules(dirname, env)

def update_win32_python():
  with scoped_cwd(VENDOR_DIR):
    if not os.path.exists('python_26'):
      execute_stdout(['git', 'clone', PYTHON_26_URL])

def build_libchromiumcontent(verbose, target_arch, defines):
  args = [sys.executable,
          os.path.join(SOURCE_ROOT, 'script', 'build-libchromiumcontent.py')]
  if verbose:
    args += ['-v']
  if defines:
    args += ['--defines', defines]
  execute_stdout(args + ['--target_arch', target_arch])

def update_clang():
  execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'update-clang.sh')])

def download_sysroot(target_arch):
  if target_arch == 'ia32':
    target_arch = 'i386'
  if target_arch == 'x64':
    target_arch = 'amd64'
  execute_stdout([sys.executable,
                  os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py'),
                  '--arch', target_arch])

def create_chrome_version_h():
  version_file = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
                              'libchromiumcontent', 'VERSION')
  target_file = os.path.join(SOURCE_ROOT, 'atom', 'common', 'chrome_version.h')
  template_file = os.path.join(SOURCE_ROOT, 'script', 'chrome_version.h.in')

  with open(version_file, 'r') as f:
    version = f.read()
  with open(template_file, 'r') as f:
    template = f.read()
  content = template.replace('{PLACEHOLDER}', version.strip())

  # We update the file only if the content has changed (ignoring line ending
  # differences).
  should_write = True
  if os.path.isfile(target_file):
    with open(target_file, 'r') as f:
      should_write = f.read().replace('r', '') != content.replace('r', '')
  if should_write:
    with open(target_file, 'w') as f:
      f.write(content)

def touch_config_gypi():
  config_gypi = os.path.join(SOURCE_ROOT, 'vendor', 'node', 'config.gypi')
  with open(config_gypi, 'w+') as f:
    content = "\n{'variables':{}}"
    if f.read() != content:
      f.write(content)

def run_update(defines, msvs, disable_clang, clang_dir):
  env = os.environ.copy()
  if not disable_clang and clang_dir == '':
    # Build with prebuilt clang.
    set_clang_env(env)

  args = [sys.executable, os.path.join(SOURCE_ROOT, 'script', 'update.py')]
  if defines:
    args += ['--defines', defines]
  if msvs:
    args += ['--msvs']

  execute_stdout(args, env)

if __name__ == '__main__':
  sys.exit(main())
<commit_msg>No more need to overwrite env when running update.py<commit_after>#!/usr/bin/env python

import argparse
import os
import subprocess
import sys

from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL, PLATFORM, \
                       enable_verbose_mode, is_verbose_mode, get_target_arch
from lib.util import execute_stdout, get_electron_version, scoped_cwd

SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
PYTHON_26_URL = 'https://chromium.googlesource.com/chromium/deps/python_26'

if os.environ.has_key('CI'):
  NPM = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'npm')
else:
  NPM = 'npm'
if sys.platform in ['win32', 'cygwin']:
  NPM += '.cmd'

def main():
  os.chdir(SOURCE_ROOT)

  args = parse_args()
  defines = args_to_defines(args)
  if not args.yes and PLATFORM != 'win32':
    check_root()
  if args.verbose:
    enable_verbose_mode()
  if sys.platform == 'cygwin':
    update_win32_python()

  update_submodules()

  libcc_source_path = args.libcc_source_path
  libcc_shared_library_path = args.libcc_shared_library_path
  libcc_static_library_path = args.libcc_static_library_path

  # Redirect to use local libchromiumcontent build.
  if args.build_libchromiumcontent:
    build_libchromiumcontent(args.verbose, args.target_arch, defines)
    dist_dir = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
                            'libchromiumcontent', 'dist', 'main')
    libcc_source_path = os.path.join(dist_dir, 'src')
    libcc_shared_library_path = os.path.join(dist_dir, 'shared_library')
    libcc_static_library_path = os.path.join(dist_dir, 'static_library')

  if PLATFORM != 'win32':
    if not args.disable_clang and args.clang_dir == '':
      # Download prebuilt clang binaries.
      update_clang()

  setup_python_libs()
  update_node_modules('.')
  bootstrap_brightray(args.dev, args.url, args.target_arch,
                      libcc_source_path, libcc_shared_library_path,
                      libcc_static_library_path)

  if PLATFORM == 'linux':
    download_sysroot(args.target_arch)

  create_chrome_version_h()
  touch_config_gypi()
  run_update(defines, args.msvs)
  update_electron_modules('spec', args.target_arch)

def parse_args():
  parser = argparse.ArgumentParser(description='Bootstrap this project')
  parser.add_argument('-u', '--url',
                      help='The base URL from which to download '
                      'libchromiumcontent (i.e., the URL you passed to '
                      'libchromiumcontent\'s script/upload script',
                      default=BASE_URL,
                      required=False)
  parser.add_argument('-v', '--verbose',
                      action='store_true',
                      help='Prints the output of the subprocesses')
  parser.add_argument('-d', '--dev', action='store_true',
                      help='Do not download static_library build')
  parser.add_argument('-y', '--yes', '--assume-yes',
                      action='store_true',
                      help='Run non-interactively by assuming "yes" to all ' \
                           'prompts.')
  parser.add_argument('--msvs', action='store_true',
                      help='Generate Visual Studio project')
  parser.add_argument('--target_arch', default=get_target_arch(),
                      help='Manually specify the arch to build for')
  parser.add_argument('--clang_dir', default='', help='Path to clang binaries')
  parser.add_argument('--disable_clang', action='store_true',
                      help='Use compilers other than clang for building')
  parser.add_argument('--build_libchromiumcontent', action='store_true',
                      help='Build local version of libchromiumcontent')
  parser.add_argument('--libcc_source_path', required=False,
                      help='The source path of libchromiumcontent. ' \
                           'NOTE: All options of libchromiumcontent are ' \
                           'required OR let electron choose it')
  parser.add_argument('--libcc_shared_library_path', required=False,
                      help='The shared library path of libchromiumcontent.')
  parser.add_argument('--libcc_static_library_path', required=False,
                      help='The static library path of libchromiumcontent.')
  return parser.parse_args()

def args_to_defines(args):
  defines = ''
  if args.disable_clang:
    defines += ' clang=0'
  if args.clang_dir:
    defines += ' make_clang_dir=' + args.clang_dir
    defines += ' clang_use_chrome_plugins=0'
  return defines

def check_root():
  if os.geteuid() == 0:
    print "We suggest not running this as root, unless you're really sure."
    choice = raw_input("Do you want to continue? [y/N]: ")
    if choice not in ('y', 'Y'):
      sys.exit(0)

def update_submodules():
  execute_stdout(['git', 'submodule', 'sync', '--recursive'])
  execute_stdout(['git', 'submodule', 'update', '--init', '--recursive'])

def setup_python_libs():
  for lib in ('requests', 'boto'):
    with scoped_cwd(os.path.join(VENDOR_DIR, lib)):
      execute_stdout([sys.executable, 'setup.py', 'build'])

def bootstrap_brightray(is_dev, url, target_arch, libcc_source_path,
                        libcc_shared_library_path,
                        libcc_static_library_path):
  bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap')
  args = [
    '--commit', LIBCHROMIUMCONTENT_COMMIT,
    '--target_arch', target_arch,
    url
  ]
  if is_dev:
    args = ['--dev'] + args
  if (libcc_source_path != None and
      libcc_shared_library_path != None and
      libcc_static_library_path != None):
    args += ['--libcc_source_path', libcc_source_path,
             '--libcc_shared_library_path', libcc_shared_library_path,
             '--libcc_static_library_path', libcc_static_library_path]
  execute_stdout([sys.executable, bootstrap] + args)

def set_clang_env(env):
  llvm_dir = os.path.join(SOURCE_ROOT, 'vendor', 'llvm-build',
                          'Release+Asserts', 'bin')
  env['CC']  = os.path.join(llvm_dir, 'clang')
  env['CXX'] = os.path.join(llvm_dir, 'clang++')

def update_node_modules(dirname, env=None):
  if env is None:
    env = os.environ.copy()
  if PLATFORM == 'linux':
    # Use prebuilt clang for building native modules.
    set_clang_env(env)
    env['npm_config_clang'] = '1'
  with scoped_cwd(dirname):
    args = [NPM, 'install']
    if is_verbose_mode():
      args += ['--verbose']
    # Ignore npm install errors when running in CI.
    if os.environ.has_key('CI'):
      try:
        execute_stdout(args, env)
      except subprocess.CalledProcessError:
        pass
    else:
      execute_stdout(args, env)

def update_electron_modules(dirname, target_arch):
  env = os.environ.copy()
  env['npm_config_arch']    = target_arch
  env['npm_config_target']  = get_electron_version()
  env['npm_config_disturl'] = 'https://atom.io/download/atom-shell'
  update_node_modules(dirname, env)

def update_win32_python():
  with scoped_cwd(VENDOR_DIR):
    if not os.path.exists('python_26'):
      execute_stdout(['git', 'clone', PYTHON_26_URL])

def build_libchromiumcontent(verbose, target_arch, defines):
  args = [sys.executable,
          os.path.join(SOURCE_ROOT, 'script', 'build-libchromiumcontent.py')]
  if verbose:
    args += ['-v']
  if defines:
    args += ['--defines', defines]
  execute_stdout(args + ['--target_arch', target_arch])

def update_clang():
  execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'update-clang.sh')])

def download_sysroot(target_arch):
  if target_arch == 'ia32':
    target_arch = 'i386'
  if target_arch == 'x64':
    target_arch = 'amd64'
  execute_stdout([sys.executable,
                  os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py'),
                  '--arch', target_arch])

def create_chrome_version_h():
  version_file = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
                              'libchromiumcontent', 'VERSION')
  target_file = os.path.join(SOURCE_ROOT, 'atom', 'common', 'chrome_version.h')
  template_file = os.path.join(SOURCE_ROOT, 'script', 'chrome_version.h.in')

  with open(version_file, 'r') as f:
    version = f.read()
  with open(template_file, 'r') as f:
    template = f.read()
  content = template.replace('{PLACEHOLDER}', version.strip())

  # We update the file only if the content has changed (ignoring line ending
  # differences).
  should_write = True
  if os.path.isfile(target_file):
    with open(target_file, 'r') as f:
      should_write = f.read().replace('r', '') != content.replace('r', '')
  if should_write:
    with open(target_file, 'w') as f:
      f.write(content)

def touch_config_gypi():
  config_gypi = os.path.join(SOURCE_ROOT, 'vendor', 'node', 'config.gypi')
  with open(config_gypi, 'w+') as f:
    content = "\n{'variables':{}}"
    if f.read() != content:
      f.write(content)

def run_update(defines, msvs):
  args = [sys.executable, os.path.join(SOURCE_ROOT, 'script', 'update.py')]
  if defines:
    args += ['--defines', defines]
  if msvs:
    args += ['--msvs']

  execute_stdout(args)

if __name__ == '__main__':
  sys.exit(main())
<|endoftext|>


<commit_before>import os

from celery import Celery
from datetime import timedelta

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'reservas.settings.production')

from django.conf import settings  # noqa

app = Celery('reservas')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

app.conf.CELERYBEAT_SCHEDULE = {
    'obtener_eventos_recursos': {
        'task': 'obtener_eventos_recursos',
        'schedule': timedelta(hours=1)
    },
}

@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))
<commit_msg>Cambio de periodicidad de obtención de eventos mediante 'Celery Beat'<commit_after>import os

from celery import Celery
from datetime import timedelta

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'reservas.settings.production')

from django.conf import settings  # noqa

app = Celery('reservas')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

app.conf.CELERYBEAT_SCHEDULE = {
    'obtener_eventos_recursos': {
        'task': 'obtener_eventos_recursos',
        'schedule': timedelta(minutes=15)
    },
}

@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Riporto i commit sull'account twetter della LugMap:
   http://twitter.com/#!/LugMap

   Copyright 2010-2013 - Andrea Gelmini (andrea.gelmini@gelma.net)

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>."""

if True: # import dei moduli
	import sys
	if sys.version_info < (2,6):
		sys.exit("Necessito di un interprete Python dalla versione 2.6 in poi")

	try:
		import ConfigParser, os, shelve, subprocess, time
	except:
		sys.exit("Non sono disponibili tutti i moduli standard necessari")

	try:
		import tweepy # http://talkfast.org/2010/05/31/twitter-from-the-command-line-in-python-using-oauth
	except:
		sys.exit("Manca il modulo Tweepy: easy_install tweepy")

if True: # leggo configurazione
	configdiesempio="""
	[db]
	path = /tmp/portavoce.db ; percorso del DB con i commit noti/inviati

	[twitter]
	consumer_key	= xxxxxxxxxxxxxxxxxxxxx
	consumer_secret	= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	access_key      = xxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	access_secret	= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	"""
	configurazione=ConfigParser.ConfigParser()
	configfile = os.path.join(os.environ["HOME"], '.portavoce.conf')
	try:
		configurazione.read(configfile)
		dbfile = configurazione.get('db', 'path', 1)
	except:
		sys.exit("Necessito del file di configurazione corretto in:\n        "+configfile+"\n\nVedi esempio incluso nel sorgente:"+configdiesempio)

try: # apro il db
	db = shelve.open(dbfile)
except:
	sys.exit("Errore nell'apertura/creazione del DB",dbfile)

class tweta:
	"""Posto su Tweet"""
	def __init__(self):
		# piglio codici
		try:
			self.CONSUMER_KEY    = configurazione.get('twitter','consumer_key',1)
			self.CONSUMER_SECRET = configurazione.get('twitter','consumer_secret',1)
			self.ACCESS_KEY      = configurazione.get('twitter','access_key',1)
			self.ACCESS_SECRET   = configurazione.get('twitter','access_secret',1)
		except:
			sys.exit("Necessito del file di configurazione corretto in:\n        "+configfile+"\n\nVedi esempio incluso nel sorgente:"+configdiesempio)
		# connetto
		self.auth            = tweepy.OAuthHandler(self.CONSUMER_KEY, self.CONSUMER_SECRET)
		self.auth.set_access_token(self.ACCESS_KEY, self.ACCESS_SECRET)
		self.twitter         = tweepy.API(self.auth)

	def tweta(self, testo):
		self.twitter.update_status(testo)

if __name__ == "__main__":
	commit_nuovi = []
	os.chdir(sys.path[0])
	for line in subprocess.Popen('git rev-list --pretty=oneline --all --no-merges --abbrev-commit', shell=True, bufsize=1000000, stdout=subprocess.PIPE).stdout:
		commit, log = line[0:7], line[8:-1]
		if not db.has_key(commit): # controllo se il commit non è gia' noto
			db[commit] = None # lo salvo subito, altrimenti risulta nuovo al prossimo controllo
			flag_doppio = False # controllo eventuali commit doppi (cherry-pick, ecc)
			for voce in commit_nuovi:
				if voce['log'] == log:
					flag_doppio = True
					break
			if flag_doppio is False:
				commit_nuovi.append({'commit': commit, 'log': log})

	if commit_nuovi:
		commit_nuovi.reverse() # ribalto l'ordine dei commit
		tweeter = tweta()
		for voce in commit_nuovi:
			testo = voce['log'][0:130]+' ('+voce['commit']+')'
			tweeter.tweta(testo)
			time.sleep(5)
	db.close()
<commit_msg>scripts: portavoce.py: aggiunto nota Tweepy<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Riporto i commit sull'account twetter della LugMap:
   http://twitter.com/#!/LugMap

   Copyright 2010-2013 - Andrea Gelmini (andrea.gelmini@gelma.net)

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>."""

if True: # import dei moduli
	import sys
	if sys.version_info < (2,6):
		sys.exit("Necessito di un interprete Python dalla versione 2.6 in poi")

	try:
		import ConfigParser, os, shelve, subprocess, time
	except:
		sys.exit("Non sono disponibili tutti i moduli standard necessari")

	try:
		import tweepy # http://talkfast.org/2010/05/31/twitter-from-the-command-line-in-python-using-oauth
	except:
		sys.exit("Manca il modulo Tweepy: easy_install tweepy non funziona per via dell'aggiornamento delle API di Twitter. Installalo da GitHub: https://github.com/tweepy/tweepy")

if True: # leggo configurazione
	configdiesempio="""
	[db]
	path = /tmp/portavoce.db ; percorso del DB con i commit noti/inviati

	[twitter]
	consumer_key	= xxxxxxxxxxxxxxxxxxxxx
	consumer_secret	= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	access_key      = xxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	access_secret	= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	"""
	configurazione=ConfigParser.ConfigParser()
	configfile = os.path.join(os.environ["HOME"], '.portavoce.conf')
	try:
		configurazione.read(configfile)
		dbfile = configurazione.get('db', 'path', 1)
	except:
		sys.exit("Necessito del file di configurazione corretto in:\n        "+configfile+"\n\nVedi esempio incluso nel sorgente:"+configdiesempio)

try: # apro il db
	db = shelve.open(dbfile)
except:
	sys.exit("Errore nell'apertura/creazione del DB",dbfile)

class tweta:
	"""Posto su Tweet"""
	def __init__(self):
		# piglio codici
		try:
			self.CONSUMER_KEY    = configurazione.get('twitter','consumer_key',1)
			self.CONSUMER_SECRET = configurazione.get('twitter','consumer_secret',1)
			self.ACCESS_KEY      = configurazione.get('twitter','access_key',1)
			self.ACCESS_SECRET   = configurazione.get('twitter','access_secret',1)
		except:
			sys.exit("Necessito del file di configurazione corretto in:\n        "+configfile+"\n\nVedi esempio incluso nel sorgente:"+configdiesempio)
		# connetto
		self.auth            = tweepy.OAuthHandler(self.CONSUMER_KEY, self.CONSUMER_SECRET)
		self.auth.set_access_token(self.ACCESS_KEY, self.ACCESS_SECRET)
		self.twitter         = tweepy.API(self.auth)

	def tweta(self, testo):
		self.twitter.update_status(testo)

if __name__ == "__main__":
	commit_nuovi = []
	os.chdir(sys.path[0])
	for line in subprocess.Popen('git rev-list --pretty=oneline --all --no-merges --abbrev-commit', shell=True, bufsize=1000000, stdout=subprocess.PIPE).stdout:
		commit, log = line[0:7], line[8:-1]
		if not db.has_key(commit): # controllo se il commit non è gia' noto
			db[commit] = None # lo salvo subito, altrimenti risulta nuovo al prossimo controllo
			flag_doppio = False # controllo eventuali commit doppi (cherry-pick, ecc)
			for voce in commit_nuovi:
				if voce['log'] == log:
					flag_doppio = True
					break
			if flag_doppio is False:
				commit_nuovi.append({'commit': commit, 'log': log})

	if commit_nuovi:
		commit_nuovi.reverse() # ribalto l'ordine dei commit
		tweeter = tweta()
		for voce in commit_nuovi:
			testo = voce['log'][0:130]+' ('+voce['commit']+')'
			tweeter.tweta(testo)
			time.sleep(5)
	db.close()
<|endoftext|>